mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 20:34:07 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into skin
This commit is contained in:
commit
75a2864845
148 changed files with 6289 additions and 2267 deletions
|
@ -24,6 +24,16 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS -mavx)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# add compiler flags to AVX2 source files
|
||||
file(GLOB_RECURSE AVX2_SRCS "src/avx2/*.cpp" "src/avx2/*.c")
|
||||
foreach(SRC ${AVX2_SRCS})
|
||||
if (WIN32)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS /arch:AVX2)
|
||||
elseif (APPLE OR UNIX)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "-mavx2 -mfma")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
setup_memory_debugger()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 1.2,
|
||||
"version": 1.3,
|
||||
"settings": [
|
||||
{
|
||||
"name": "metaverse",
|
||||
|
@ -71,6 +71,76 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "descriptors",
|
||||
"label": "Description",
|
||||
"help": "This data will be queryable from your server. It may be collected by High Fidelity and used to share your domain with others.",
|
||||
"settings": [
|
||||
{
|
||||
"name": "description",
|
||||
"label": "Description",
|
||||
"help": "A description of your domain (256 character limit)."
|
||||
},
|
||||
{
|
||||
"name": "maturity",
|
||||
"label": "Maturity",
|
||||
"help": "A maturity rating, available as a guideline for content on your domain.",
|
||||
"default": "unrated",
|
||||
"type": "select",
|
||||
"options": [
|
||||
{
|
||||
"value": "unrated",
|
||||
"label": "Unrated"
|
||||
},
|
||||
{
|
||||
"value": "everyone",
|
||||
"label": "Everyone"
|
||||
},
|
||||
{
|
||||
"value": "teen",
|
||||
"label": "Teen (13+)"
|
||||
},
|
||||
{
|
||||
"value": "mature",
|
||||
"label": "Mature (17+)"
|
||||
},
|
||||
{
|
||||
"value": "adult",
|
||||
"label": "Adult (18+)"
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
"name": "hosts",
|
||||
"label": "Hosts",
|
||||
"type": "table",
|
||||
"help": "Usernames of hosts who can reliably show your domain to new visitors.",
|
||||
"numbered": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "host",
|
||||
"label": "Username",
|
||||
"can_set": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"label": "Tags",
|
||||
"type": "table",
|
||||
"help": "Common categories under which your domain falls.",
|
||||
"numbered": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "tag",
|
||||
"label": "Tag",
|
||||
"can_set": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "security",
|
||||
"label": "Security",
|
||||
|
|
132
domain-server/src/DomainMetadata.cpp
Normal file
132
domain-server/src/DomainMetadata.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// DomainMetadata.cpp
|
||||
// domain-server/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 5/25/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
#include "DomainMetadata.h"
|
||||
|
||||
#include <HifiConfigVariantMap.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <LimitedNodeList.h>
|
||||
|
||||
#include "DomainServerNodeData.h"
|
||||
|
||||
const QString DomainMetadata::USERS = "users";
|
||||
const QString DomainMetadata::USERS_NUM_TOTAL = "num_users";
|
||||
const QString DomainMetadata::USERS_NUM_ANON = "num_anon_users";
|
||||
const QString DomainMetadata::USERS_HOSTNAMES = "user_hostnames";
|
||||
// users metadata will appear as (JSON):
|
||||
// { "num_users": Number,
|
||||
// "num_anon_users": Number,
|
||||
// "user_hostnames": { <HOSTNAME>: Number }
|
||||
// }
|
||||
|
||||
const QString DomainMetadata::DESCRIPTORS = "descriptors";
|
||||
const QString DomainMetadata::DESCRIPTORS_DESCRIPTION = "description";
|
||||
const QString DomainMetadata::DESCRIPTORS_CAPACITY = "capacity"; // parsed from security
|
||||
const QString DomainMetadata::DESCRIPTORS_RESTRICTION = "restriction"; // parsed from ACL
|
||||
const QString DomainMetadata::DESCRIPTORS_MATURITY = "maturity";
|
||||
const QString DomainMetadata::DESCRIPTORS_HOSTS = "hosts";
|
||||
const QString DomainMetadata::DESCRIPTORS_TAGS = "tags";
|
||||
// descriptors metadata will appear as (JSON):
|
||||
// { "capacity": Number,
|
||||
// TODO: "hours": String, // UTF-8 representation of the week, split into 15" segments
|
||||
// "restriction": String, // enum of either open, hifi, or acl
|
||||
// "maturity": String, // enum corresponding to ESRB ratings
|
||||
// "hosts": [ String ], // capped list of usernames
|
||||
// "description": String, // capped description
|
||||
// TODO: "img": {
|
||||
// "src": String,
|
||||
// "type": String,
|
||||
// "size": Number,
|
||||
// "updated_at": Number,
|
||||
// },
|
||||
// "tags": [ String ], // capped list of tags
|
||||
// }
|
||||
|
||||
// metadata will appear as (JSON):
|
||||
// { users: <USERS>, descriptors: <DESCRIPTORS> }
|
||||
//
|
||||
// it is meant to be sent to and consumed by an external API
|
||||
|
||||
DomainMetadata::DomainMetadata() {
|
||||
_metadata[USERS] = {};
|
||||
_metadata[DESCRIPTORS] = {};
|
||||
}
|
||||
|
||||
void DomainMetadata::setDescriptors(QVariantMap& settings) {
|
||||
const QString CAPACITY = "security.maximum_user_capacity";
|
||||
const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY);
|
||||
unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0;
|
||||
|
||||
// TODO: Keep parity with ACL development.
|
||||
const QString RESTRICTION = "security.restricted_access";
|
||||
const QString RESTRICTION_OPEN = "open";
|
||||
// const QString RESTRICTION_HIFI = "hifi";
|
||||
const QString RESTRICTION_ACL = "acl";
|
||||
const QVariant* isRestrictedVariant = valueForKeyPath(settings, RESTRICTION);
|
||||
bool isRestricted = isRestrictedVariant ? isRestrictedVariant->toBool() : false;
|
||||
QString restriction = isRestricted ? RESTRICTION_ACL : RESTRICTION_OPEN;
|
||||
|
||||
QVariantMap descriptors = settings[DESCRIPTORS].toMap();
|
||||
descriptors[DESCRIPTORS_CAPACITY] = capacity;
|
||||
descriptors[DESCRIPTORS_RESTRICTION] = restriction;
|
||||
_metadata[DESCRIPTORS] = descriptors;
|
||||
|
||||
#if DEV_BUILD || PR_BUILD
|
||||
qDebug() << "Domain metadata descriptors set:" << descriptors;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DomainMetadata::updateUsers() {
|
||||
static const QString DEFAULT_HOSTNAME = "*";
|
||||
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
int numConnected = 0;
|
||||
int numConnectedAnonymously = 0;
|
||||
QVariantMap userHostnames;
|
||||
|
||||
// figure out the breakdown of currently connected interface clients
|
||||
nodeList->eachNode([&numConnected, &numConnectedAnonymously, &userHostnames](const SharedNodePointer& node) {
|
||||
auto linkedData = node->getLinkedData();
|
||||
if (linkedData) {
|
||||
auto nodeData = static_cast<DomainServerNodeData*>(linkedData);
|
||||
|
||||
if (!nodeData->wasAssigned()) {
|
||||
++numConnected;
|
||||
|
||||
if (nodeData->getUsername().isEmpty()) {
|
||||
++numConnectedAnonymously;
|
||||
}
|
||||
|
||||
// increment the count for this hostname (or the default if we don't have one)
|
||||
auto placeName = nodeData->getPlaceName();
|
||||
auto hostname = placeName.isEmpty() ? DEFAULT_HOSTNAME : placeName;
|
||||
userHostnames[hostname] = userHostnames[hostname].toInt() + 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
QVariantMap users = {
|
||||
{ USERS_NUM_TOTAL, numConnected },
|
||||
{ USERS_NUM_ANON, numConnectedAnonymously },
|
||||
{ USERS_HOSTNAMES, userHostnames }};
|
||||
_metadata[USERS] = users;
|
||||
|
||||
#if DEV_BUILD || PR_BUILD
|
||||
qDebug() << "Domain metadata users updated:" << users;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DomainMetadata::usersChanged() {
|
||||
++_tic;
|
||||
|
||||
#if DEV_BUILD || PR_BUILD
|
||||
qDebug() << "Domain metadata users change detected";
|
||||
#endif
|
||||
}
|
65
domain-server/src/DomainMetadata.h
Normal file
65
domain-server/src/DomainMetadata.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// DomainMetadata.h
|
||||
// domain-server/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 5/25/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
#ifndef hifi_DomainMetadata_h
|
||||
#define hifi_DomainMetadata_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <QVariantMap>
|
||||
#include <QJsonObject>
|
||||
|
||||
class DomainMetadata : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
static const QString USERS;
|
||||
static const QString USERS_NUM_TOTAL;
|
||||
static const QString USERS_NUM_ANON;
|
||||
static const QString USERS_HOSTNAMES;
|
||||
|
||||
static const QString DESCRIPTORS;
|
||||
static const QString DESCRIPTORS_DESCRIPTION;
|
||||
static const QString DESCRIPTORS_CAPACITY;
|
||||
static const QString DESCRIPTORS_HOURS;
|
||||
static const QString DESCRIPTORS_RESTRICTION;
|
||||
static const QString DESCRIPTORS_MATURITY;
|
||||
static const QString DESCRIPTORS_HOSTS;
|
||||
static const QString DESCRIPTORS_TAGS;
|
||||
static const QString DESCRIPTORS_IMG;
|
||||
static const QString DESCRIPTORS_IMG_SRC;
|
||||
static const QString DESCRIPTORS_IMG_TYPE;
|
||||
static const QString DESCRIPTORS_IMG_SIZE;
|
||||
static const QString DESCRIPTORS_IMG_UPDATED_AT;
|
||||
|
||||
public:
|
||||
DomainMetadata();
|
||||
|
||||
// Returns the last set metadata
|
||||
// If connected users have changed, metadata may need to be updated
|
||||
// this should be checked by storing tic = getTic() between calls
|
||||
// and testing it for equality before the next get (tic == getTic())
|
||||
QJsonObject get() { return QJsonObject::fromVariantMap(_metadata); }
|
||||
QJsonObject getUsers() { return QJsonObject::fromVariantMap(_metadata[USERS].toMap()); }
|
||||
QJsonObject getDescriptors() { return QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); }
|
||||
|
||||
uint32_t getTic() { return _tic; }
|
||||
|
||||
void setDescriptors(QVariantMap& settings);
|
||||
void updateUsers();
|
||||
|
||||
public slots:
|
||||
void usersChanged();
|
||||
|
||||
protected:
|
||||
QVariantMap _metadata;
|
||||
uint32_t _tic{ 0 };
|
||||
};
|
||||
|
||||
#endif // hifi_DomainMetadata_h
|
|
@ -94,6 +94,10 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
qRegisterMetaType<DomainServerWebSessionData>("DomainServerWebSessionData");
|
||||
qRegisterMetaTypeStreamOperators<DomainServerWebSessionData>("DomainServerWebSessionData");
|
||||
|
||||
// update the metadata when a user (dis)connects
|
||||
connect(this, &DomainServer::userConnected, &_metadata, &DomainMetadata::usersChanged);
|
||||
connect(this, &DomainServer::userDisconnected, &_metadata, &DomainMetadata::usersChanged);
|
||||
|
||||
// make sure we hear about newly connected nodes from our gatekeeper
|
||||
connect(&_gatekeeper, &DomainGatekeeper::connectedNode, this, &DomainServer::handleConnectedNode);
|
||||
|
||||
|
@ -112,6 +116,9 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
optionallyGetTemporaryName(args);
|
||||
}
|
||||
|
||||
// update the metadata with current descriptors
|
||||
_metadata.setDescriptors(_settingsManager.getSettingsMap());
|
||||
}
|
||||
|
||||
DomainServer::~DomainServer() {
|
||||
|
@ -767,12 +774,16 @@ QUrl DomainServer::oauthAuthorizationURL(const QUuid& stateUUID) {
|
|||
}
|
||||
|
||||
void DomainServer::handleConnectedNode(SharedNodePointer newNode) {
|
||||
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||
|
||||
// reply back to the user with a PacketType::DomainList
|
||||
sendDomainListToNode(newNode, nodeData->getSendingSockAddr());
|
||||
|
||||
|
||||
// if this node is a user (unassigned Agent), signal
|
||||
if (newNode->getType() == NodeType::Agent && !nodeData->wasAssigned()) {
|
||||
emit userConnected();
|
||||
}
|
||||
|
||||
// send out this node to our other connected nodes
|
||||
broadcastNewNode(newNode);
|
||||
}
|
||||
|
@ -1067,62 +1078,39 @@ void DomainServer::performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr)
|
|||
sendHeartbeatToMetaverse(newPublicSockAddr.getAddress().toString());
|
||||
}
|
||||
|
||||
|
||||
void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) {
|
||||
const QString DOMAIN_UPDATE = "/api/v1/domains/%1";
|
||||
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
const QUuid& domainID = nodeList->getSessionUUID();
|
||||
|
||||
// setup the domain object to send to the data server
|
||||
const QString PUBLIC_NETWORK_ADDRESS_KEY = "network_address";
|
||||
const QString AUTOMATIC_NETWORKING_KEY = "automatic_networking";
|
||||
|
||||
// Setup the domain object to send to the data server
|
||||
QJsonObject domainObject;
|
||||
|
||||
if (!networkAddress.isEmpty()) {
|
||||
static const QString PUBLIC_NETWORK_ADDRESS_KEY = "network_address";
|
||||
domainObject[PUBLIC_NETWORK_ADDRESS_KEY] = networkAddress;
|
||||
}
|
||||
|
||||
static const QString AUTOMATIC_NETWORKING_KEY = "automatic_networking";
|
||||
domainObject[AUTOMATIC_NETWORKING_KEY] = _automaticNetworkingSetting;
|
||||
|
||||
// add a flag to indicate if this domain uses restricted access - for now that will exclude it from listings
|
||||
const QString RESTRICTED_ACCESS_FLAG = "restricted";
|
||||
|
||||
// Add a flag to indicate if this domain uses restricted access -
|
||||
// for now that will exclude it from listings
|
||||
static const QString RESTRICTED_ACCESS_FLAG = "restricted";
|
||||
domainObject[RESTRICTED_ACCESS_FLAG] =
|
||||
_settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
|
||||
|
||||
// figure out the breakdown of currently connected interface clients
|
||||
int numConnectedUnassigned = 0;
|
||||
QJsonObject userHostnames;
|
||||
|
||||
static const QString DEFAULT_HOSTNAME = "*";
|
||||
|
||||
nodeList->eachNode([&numConnectedUnassigned, &userHostnames](const SharedNodePointer& node) {
|
||||
if (node->getLinkedData()) {
|
||||
auto nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
||||
if (!nodeData->wasAssigned()) {
|
||||
++numConnectedUnassigned;
|
||||
|
||||
// increment the count for this hostname (or the default if we don't have one)
|
||||
auto hostname = nodeData->getPlaceName().isEmpty() ? DEFAULT_HOSTNAME : nodeData->getPlaceName();
|
||||
userHostnames[hostname] = userHostnames[hostname].toInt() + 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add the metadata to the heartbeat
|
||||
static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
|
||||
static const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
|
||||
static const QString HEARTBEAT_USER_HOSTNAMES_KEY = "user_hostnames";
|
||||
auto tic = _metadata.getTic();
|
||||
if (_metadataTic != tic) {
|
||||
_metadataTic = tic;
|
||||
_metadata.updateUsers();
|
||||
}
|
||||
domainObject[DOMAIN_HEARTBEAT_KEY] = _metadata.getUsers();
|
||||
|
||||
QJsonObject heartbeatObject;
|
||||
heartbeatObject[HEARTBEAT_NUM_USERS_KEY] = numConnectedUnassigned;
|
||||
heartbeatObject[HEARTBEAT_USER_HOSTNAMES_KEY] = userHostnames;
|
||||
|
||||
domainObject[DOMAIN_HEARTBEAT_KEY] = heartbeatObject;
|
||||
|
||||
QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson()));
|
||||
QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(domainObject).toJson(QJsonDocument::Compact)));
|
||||
|
||||
static const QString DOMAIN_UPDATE = "/api/v1/domains/%1";
|
||||
DependencyManager::get<AccountManager>()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)),
|
||||
AccountManagerAuth::Required,
|
||||
QNetworkAccessManager::PutOperation,
|
||||
|
@ -1918,11 +1906,10 @@ void DomainServer::nodeAdded(SharedNodePointer node) {
|
|||
}
|
||||
|
||||
void DomainServer::nodeKilled(SharedNodePointer node) {
|
||||
|
||||
// if this peer connected via ICE then remove them from our ICE peers hash
|
||||
_gatekeeper.removeICEPeer(node->getUUID());
|
||||
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
||||
if (nodeData) {
|
||||
// if this node's UUID matches a static assignment we need to throw it back in the assignment queue
|
||||
|
@ -1934,15 +1921,22 @@ void DomainServer::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
}
|
||||
|
||||
// If this node was an Agent ask DomainServerNodeData to potentially remove the interpolation we stored
|
||||
nodeData->removeOverrideForKey(USERNAME_UUID_REPLACEMENT_STATS_KEY,
|
||||
uuidStringWithoutCurlyBraces(node->getUUID()));
|
||||
|
||||
// cleanup the connection secrets that we set up for this node (on the other nodes)
|
||||
foreach (const QUuid& otherNodeSessionUUID, nodeData->getSessionSecretHash().keys()) {
|
||||
SharedNodePointer otherNode = DependencyManager::get<LimitedNodeList>()->nodeWithUUID(otherNodeSessionUUID);
|
||||
if (otherNode) {
|
||||
reinterpret_cast<DomainServerNodeData*>(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID());
|
||||
static_cast<DomainServerNodeData*>(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
if (node->getType() == NodeType::Agent) {
|
||||
// if this node was an Agent ask DomainServerNodeData to remove the interpolation we potentially stored
|
||||
nodeData->removeOverrideForKey(USERNAME_UUID_REPLACEMENT_STATS_KEY,
|
||||
uuidStringWithoutCurlyBraces(node->getUUID()));
|
||||
|
||||
// if this node is a user (unassigned Agent), signal
|
||||
if (!nodeData->wasAssigned()) {
|
||||
emit userDisconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <LimitedNodeList.h>
|
||||
|
||||
#include "DomainGatekeeper.h"
|
||||
#include "DomainMetadata.h"
|
||||
#include "DomainServerSettingsManager.h"
|
||||
#include "DomainServerWebSessionData.h"
|
||||
#include "WalletTransaction.h"
|
||||
|
@ -91,6 +92,8 @@ private slots:
|
|||
|
||||
signals:
|
||||
void iceServerChanged();
|
||||
void userConnected();
|
||||
void userDisconnected();
|
||||
|
||||
private:
|
||||
void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid());
|
||||
|
@ -167,6 +170,9 @@ private:
|
|||
|
||||
DomainServerSettingsManager _settingsManager;
|
||||
|
||||
DomainMetadata _metadata;
|
||||
uint32_t _metadataTic{ 0 };
|
||||
|
||||
HifiSockAddr _iceServerSocket;
|
||||
std::unique_ptr<NLPacket> _iceServerHeartbeatPacket;
|
||||
|
||||
|
|
|
@ -1,22 +1,40 @@
|
|||
{
|
||||
"name": "Oculus Touch to Standard",
|
||||
"channels": [
|
||||
{ "from": "OculusTouch.LY", "filters": "invert", "to": "Standard.LY" },
|
||||
{ "from": "OculusTouch.LX", "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.A", "to": "Standard.A" },
|
||||
{ "from": "OculusTouch.B", "to": "Standard.B" },
|
||||
{ "from": "OculusTouch.X", "to": "Standard.X" },
|
||||
{ "from": "OculusTouch.Y", "to": "Standard.Y" },
|
||||
|
||||
{ "from": "OculusTouch.LY", "filters": "invert", "to": "Standard.LY" },
|
||||
{ "from": "OculusTouch.LX", "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.LT", "to": "Standard.LT" },
|
||||
{ "from": "OculusTouch.LS", "to": "Standard.LS" },
|
||||
{ "from": "OculusTouch.LeftGrip", "to": "Standard.LeftGrip" },
|
||||
{ "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" },
|
||||
|
||||
{ "from": "OculusTouch.RY", "filters": "invert", "to": "Standard.RY" },
|
||||
{ "from": "OculusTouch.RX", "to": "Standard.RX" },
|
||||
|
||||
{ "from": "OculusTouch.RY", "filters": "invert", "to": "Standard.RY" },
|
||||
{ "from": "OculusTouch.RX", "to": "Standard.RX" },
|
||||
{ "from": "OculusTouch.RT", "to": "Standard.RT" },
|
||||
{ "from": "OculusTouch.RB", "to": "Standard.RB" },
|
||||
{ "from": "OculusTouch.RS", "to": "Standard.RS" },
|
||||
{ "from": "OculusTouch.RightGrip", "to": "Standard.RightGrip" },
|
||||
{ "from": "OculusTouch.RightHand", "to": "Standard.RightHand" },
|
||||
|
||||
{ "from": "OculusTouch.LeftApplicationMenu", "to": "Standard.Back" },
|
||||
{ "from": "OculusTouch.RightApplicationMenu", "to": "Standard.Start" },
|
||||
|
||||
{ "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" },
|
||||
{ "from": "OculusTouch.RightHand", "to": "Standard.RightHand" }
|
||||
{ "from": "OculusTouch.LeftPrimaryThumbTouch", "to": "Standard.LeftPrimaryThumbTouch" },
|
||||
{ "from": "OculusTouch.LeftSecondaryThumbTouch", "to": "Standard.LeftSecondaryThumbTouch" },
|
||||
{ "from": "OculusTouch.RightPrimaryThumbTouch", "to": "Standard.RightPrimaryThumbTouch" },
|
||||
{ "from": "OculusTouch.RightSecondaryThumbTouch", "to": "Standard.RightSecondaryThumbTouch" },
|
||||
{ "from": "OculusTouch.LeftPrimaryIndexTouch", "to": "Standard.LeftPrimaryIndexTouch" },
|
||||
{ "from": "OculusTouch.RightPrimaryIndexTouch", "to": "Standard.RightPrimaryIndexTouch" },
|
||||
{ "from": "OculusTouch.LSTouch", "to": "Standard.LSTouch" },
|
||||
{ "from": "OculusTouch.RSTouch", "to": "Standard.RSTouch" },
|
||||
{ "from": "OculusTouch.LeftThumbUp", "to": "Standard.LeftThumbUp" },
|
||||
{ "from": "OculusTouch.RightThumbUp", "to": "Standard.RightThumbUp" },
|
||||
{ "from": "OculusTouch.LeftIndexPoint", "to": "Standard.LeftIndexPoint" },
|
||||
{ "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" }
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"constrainToInteger",
|
||||
{ "type": "pulse", "interval": 0.5 },
|
||||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{ "from": "Vive.LX", "when": "Vive.LSOuter", "to": "Standard.LX" },
|
||||
|
||||
{ "from": "Vive.LT", "to": "Standard.LT" },
|
||||
{ "from": "Vive.LeftGrip", "to": "Standard.LB" },
|
||||
{ "from": "Vive.LeftGrip", "to": "Standard.LeftGrip" },
|
||||
{ "from": "Vive.LS", "to": "Standard.LS" },
|
||||
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
{ "from": "Vive.RX", "when": "Vive.RSOuter", "to": "Standard.RX" },
|
||||
|
||||
{ "from": "Vive.RT", "to": "Standard.RT" },
|
||||
{ "from": "Vive.RightGrip", "to": "Standard.RB" },
|
||||
{ "from": "Vive.RightGrip", "to": "Standard.RightGrip" },
|
||||
{ "from": "Vive.RS", "to": "Standard.RS" },
|
||||
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"name": "XBox to Standard",
|
||||
"channels": [
|
||||
{ "from": "GamePad.LY", "to": "Standard.LY" },
|
||||
{ "from": "GamePad.LX", "to": "Standard.LX" },
|
||||
{ "from": "GamePad.LY", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LY" },
|
||||
{ "from": "GamePad.LX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LX" },
|
||||
{ "from": "GamePad.LT", "to": "Standard.LT" },
|
||||
{ "from": "GamePad.LB", "to": "Standard.LB" },
|
||||
{ "from": "GamePad.LS", "to": "Standard.LS" },
|
||||
|
||||
{ "from": "GamePad.RY", "to": "Standard.RY" },
|
||||
{ "from": "GamePad.RX", "to": "Standard.RX" },
|
||||
{ "from": "GamePad.RY", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RY" },
|
||||
{ "from": "GamePad.RX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RX" },
|
||||
{ "from": "GamePad.RT", "to": "Standard.RT" },
|
||||
{ "from": "GamePad.RB", "to": "Standard.RB" },
|
||||
{ "from": "GamePad.RS", "to": "Standard.RS" },
|
||||
|
|
|
@ -341,7 +341,7 @@ Window {
|
|||
|
||||
HifiControls.GlyphButton {
|
||||
glyph: hifi.glyphs.reload
|
||||
color: hifi.buttons.white
|
||||
color: hifi.buttons.black
|
||||
colorScheme: root.colorScheme
|
||||
width: hifi.dimensions.controlLineHeight
|
||||
|
||||
|
@ -349,8 +349,8 @@ Window {
|
|||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "ADD TO WORLD"
|
||||
color: hifi.buttons.white
|
||||
text: "Add To World"
|
||||
color: hifi.buttons.black
|
||||
colorScheme: root.colorScheme
|
||||
width: 120
|
||||
|
||||
|
@ -360,8 +360,8 @@ Window {
|
|||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "RENAME"
|
||||
color: hifi.buttons.white
|
||||
text: "Rename"
|
||||
color: hifi.buttons.black
|
||||
colorScheme: root.colorScheme
|
||||
width: 80
|
||||
|
||||
|
@ -372,7 +372,7 @@ Window {
|
|||
HifiControls.Button {
|
||||
id: deleteButton
|
||||
|
||||
text: "DELETE"
|
||||
text: "Delete"
|
||||
color: hifi.buttons.red
|
||||
colorScheme: root.colorScheme
|
||||
width: 80
|
||||
|
|
|
@ -23,9 +23,9 @@ Window {
|
|||
title: "Running Scripts"
|
||||
resizable: true
|
||||
destroyOnInvisible: true
|
||||
implicitWidth: 400
|
||||
implicitWidth: 424
|
||||
implicitHeight: isHMD ? 695 : 728
|
||||
minSize: Qt.vector2d(200, 300)
|
||||
minSize: Qt.vector2d(424, 300)
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
|
@ -83,6 +83,11 @@ Window {
|
|||
scripts.reloadAllScripts();
|
||||
}
|
||||
|
||||
function loadDefaults() {
|
||||
console.log("Load default scripts");
|
||||
scripts.loadOneScript(scripts.defaultScriptsPath + "/defaultScripts.js");
|
||||
}
|
||||
|
||||
function stopAll() {
|
||||
console.log("Stop all scripts");
|
||||
scripts.stopAllScripts();
|
||||
|
@ -101,13 +106,13 @@ Window {
|
|||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Reload all"
|
||||
text: "Reload All"
|
||||
color: hifi.buttons.black
|
||||
onClicked: reloadAll()
|
||||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Stop all"
|
||||
text: "Remove All"
|
||||
color: hifi.buttons.red
|
||||
onClicked: stopAll()
|
||||
}
|
||||
|
@ -215,7 +220,6 @@ Window {
|
|||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
anchors.right: parent.right
|
||||
|
||||
HifiControls.Button {
|
||||
text: "from URL"
|
||||
|
@ -253,6 +257,13 @@ Window {
|
|||
onTriggered: ApplicationInterface.loadDialog();
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Load Defaults"
|
||||
color: hifi.buttons.black
|
||||
height: 26
|
||||
onClicked: loadDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <QtCore/QAbstractNativeEventFilter>
|
||||
#include <QtCore/QCommandLineParser>
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtCore/QThreadPool>
|
||||
|
||||
|
@ -197,7 +198,6 @@ static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check f
|
|||
|
||||
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
|
||||
static const QString INPUT_DEVICE_MENU_PREFIX = "Device: ";
|
||||
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||
|
||||
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
||||
|
@ -994,12 +994,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
if (_keyboardFocusedItem != entityItemID) {
|
||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
|
||||
if (EntityTypes::Web == properties.getType() && !properties.getLocked()) {
|
||||
if (EntityTypes::Web == properties.getType() && !properties.getLocked() && properties.getVisible()) {
|
||||
auto entity = entityScriptingInterface->getEntityTree()->findEntityByID(entityItemID);
|
||||
RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());
|
||||
if (webEntity) {
|
||||
webEntity->setProxyWindow(_window->windowHandle());
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
}
|
||||
_keyboardFocusedItem = entityItemID;
|
||||
|
@ -1049,6 +1049,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
}
|
||||
});
|
||||
|
||||
connect(this, &Application::aboutToQuit, [=]() {
|
||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||
if (_keyboardFocusHighlight) {
|
||||
_keyboardFocusHighlight->setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
|
@ -1145,9 +1152,7 @@ void Application::aboutToQuit() {
|
|||
emit beforeAboutToQuit();
|
||||
|
||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->deactivate();
|
||||
}
|
||||
}
|
||||
|
@ -1469,7 +1474,6 @@ void Application::initializeUi() {
|
|||
}
|
||||
}
|
||||
_window->setMenuBar(new Menu());
|
||||
updateInputModes();
|
||||
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, [=] {
|
||||
|
@ -1503,7 +1507,13 @@ void Application::paintGL() {
|
|||
// FIXME not needed anymore?
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
displayPlugin->beginFrameRender(_frameCount);
|
||||
// If a display plugin loses it's underlying support, it
|
||||
// needs to be able to signal us to not use it
|
||||
if (!displayPlugin->beginFrameRender(_frameCount)) {
|
||||
_inPaint = false;
|
||||
updateDisplayMode();
|
||||
return;
|
||||
}
|
||||
|
||||
// update the avatar with a fresh HMD pose
|
||||
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
||||
|
@ -2011,7 +2021,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->keyPressEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2345,7 +2355,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2377,9 +2387,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
void Application::focusOutEvent(QFocusEvent* event) {
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action && action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->pluginFocusOutEvent();
|
||||
}
|
||||
}
|
||||
|
@ -2464,7 +2472,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2501,7 +2509,7 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mousePressEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2546,7 +2554,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2573,7 +2581,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchUpdateEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -2591,7 +2599,7 @@ void Application::touchBeginEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchBeginEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2608,7 +2616,7 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchEndEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2624,7 +2632,7 @@ void Application::wheelEvent(QWheelEvent* event) const {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->wheelEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -2757,9 +2765,7 @@ void Application::idle(float nsecsElapsed) {
|
|||
getActiveDisplayPlugin()->idle();
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action && action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->idle();
|
||||
}
|
||||
}
|
||||
|
@ -2943,6 +2949,27 @@ void Application::loadSettings() {
|
|||
//DependencyManager::get<LODManager>()->setAutomaticLODAdjust(false);
|
||||
|
||||
Menu::getInstance()->loadSettings();
|
||||
|
||||
// If there is a preferred plugin, we probably messed it up with the menu settings, so fix it.
|
||||
auto pluginManager = PluginManager::getInstance();
|
||||
auto plugins = pluginManager->getPreferredDisplayPlugins();
|
||||
for (auto plugin : plugins) {
|
||||
auto menu = Menu::getInstance();
|
||||
if (auto action = menu->getActionForOption(plugin->getName())) {
|
||||
action->setChecked(true);
|
||||
action->trigger();
|
||||
// Find and activated highest priority plugin, bail for the rest
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto inputs = pluginManager->getInputPlugins();
|
||||
for (auto plugin : inputs) {
|
||||
if (!plugin->isActive()) {
|
||||
plugin->activate();
|
||||
}
|
||||
}
|
||||
|
||||
getMyAvatar()->loadData();
|
||||
|
||||
_settingsLoaded = true;
|
||||
|
@ -4923,7 +4950,34 @@ void Application::postLambdaEvent(std::function<void()> f) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::initPlugins() {
|
||||
void Application::initPlugins(const QStringList& arguments) {
|
||||
QCommandLineOption display("display", "Preferred displays", "displays");
|
||||
QCommandLineOption disableDisplays("disable-displays", "Displays to disable", "displays");
|
||||
QCommandLineOption disableInputs("disable-inputs", "Inputs to disable", "inputs");
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addOption(display);
|
||||
parser.addOption(disableDisplays);
|
||||
parser.addOption(disableInputs);
|
||||
parser.parse(arguments);
|
||||
|
||||
if (parser.isSet(display)) {
|
||||
auto preferredDisplays = parser.value(display).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Setting prefered display plugins:" << preferredDisplays;
|
||||
PluginManager::getInstance()->setPreferredDisplayPlugins(preferredDisplays);
|
||||
}
|
||||
|
||||
if (parser.isSet(disableDisplays)) {
|
||||
auto disabledDisplays = parser.value(disableDisplays).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Disabling following display plugins:" << disabledDisplays;
|
||||
PluginManager::getInstance()->disableDisplays(disabledDisplays);
|
||||
}
|
||||
|
||||
if (parser.isSet(disableInputs)) {
|
||||
auto disabledInputs = parser.value(disableInputs).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Disabling following input plugins:" << disabledInputs;
|
||||
PluginManager::getInstance()->disableInputs(disabledInputs);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::shutdownPlugins() {
|
||||
|
@ -5098,9 +5152,17 @@ void Application::updateDisplayMode() {
|
|||
|
||||
foreach(auto displayPlugin, standard) {
|
||||
addDisplayPluginToMenu(displayPlugin, first);
|
||||
auto displayPluginName = displayPlugin->getName();
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) {
|
||||
resizeGL();
|
||||
});
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::outputDeviceLost, [this, displayPluginName] {
|
||||
PluginManager::getInstance()->disableDisplayPlugin(displayPluginName);
|
||||
auto menu = Menu::getInstance();
|
||||
if (menu->menuItemExists(MenuOption::OutputMenu, displayPluginName)) {
|
||||
menu->removeMenuItem(MenuOption::OutputMenu, displayPluginName);
|
||||
}
|
||||
});
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
@ -5116,6 +5178,10 @@ void Application::updateDisplayMode() {
|
|||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
// Menu might have been removed if the display plugin lost
|
||||
if (!action) {
|
||||
continue;
|
||||
}
|
||||
if (action->isChecked()) {
|
||||
newDisplayPlugin = displayPlugin;
|
||||
break;
|
||||
|
@ -5181,81 +5247,6 @@ void Application::updateDisplayMode() {
|
|||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
||||
static void addInputPluginToMenu(InputPluginPointer inputPlugin) {
|
||||
auto menu = Menu::getInstance();
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name));
|
||||
|
||||
static QActionGroup* inputPluginGroup = nullptr;
|
||||
if (!inputPluginGroup) {
|
||||
inputPluginGroup = new QActionGroup(menu);
|
||||
inputPluginGroup->setExclusive(false);
|
||||
}
|
||||
|
||||
auto parent = menu->getMenu(MenuOption::InputMenu);
|
||||
auto action = menu->addCheckableActionToQMenuAndActionHash(parent,
|
||||
name, 0, true, qApp,
|
||||
SLOT(updateInputModes()));
|
||||
|
||||
inputPluginGroup->addAction(action);
|
||||
Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name));
|
||||
}
|
||||
|
||||
|
||||
void Application::updateInputModes() {
|
||||
auto menu = Menu::getInstance();
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
addInputPluginToMenu(inputPlugin);
|
||||
}
|
||||
});
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
||||
InputPluginList newInputPlugins;
|
||||
InputPluginList removedInputPlugins;
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
|
||||
auto it = std::find(std::begin(_activeInputPlugins), std::end(_activeInputPlugins), inputPlugin);
|
||||
if (action->isChecked() && it == std::end(_activeInputPlugins)) {
|
||||
_activeInputPlugins.push_back(inputPlugin);
|
||||
newInputPlugins.push_back(inputPlugin);
|
||||
} else if (!action->isChecked() && it != std::end(_activeInputPlugins)) {
|
||||
_activeInputPlugins.erase(it);
|
||||
removedInputPlugins.push_back(inputPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
// A plugin was checked
|
||||
if (newInputPlugins.size() > 0) {
|
||||
foreach(auto newInputPlugin, newInputPlugins) {
|
||||
newInputPlugin->activate();
|
||||
//newInputPlugin->installEventFilter(qApp);
|
||||
//newInputPlugin->installEventFilter(offscreenUi.data());
|
||||
}
|
||||
}
|
||||
if (removedInputPlugins.size() > 0) { // A plugin was unchecked
|
||||
foreach(auto removedInputPlugin, removedInputPlugins) {
|
||||
removedInputPlugin->deactivate();
|
||||
//removedInputPlugin->removeEventFilter(qApp);
|
||||
//removedInputPlugin->removeEventFilter(offscreenUi.data());
|
||||
}
|
||||
}
|
||||
|
||||
//if (newInputPlugins.size() > 0 || removedInputPlugins.size() > 0) {
|
||||
// if (!_currentInputPluginActions.isEmpty()) {
|
||||
// auto menu = Menu::getInstance();
|
||||
// foreach(auto itemInfo, _currentInputPluginActions) {
|
||||
// menu->removeMenuItem(itemInfo.first, itemInfo.second);
|
||||
// }
|
||||
// _currentInputPluginActions.clear();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
mat4 Application::getEyeProjection(int eye) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
if (isHMDMode()) {
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
};
|
||||
|
||||
// FIXME? Empty methods, do we still need them?
|
||||
static void initPlugins();
|
||||
static void initPlugins(const QStringList& arguments);
|
||||
static void shutdownPlugins();
|
||||
|
||||
Application(int& argc, char** argv, QElapsedTimer& startup_time);
|
||||
|
@ -327,7 +327,6 @@ private slots:
|
|||
void nodeKilled(SharedNodePointer node);
|
||||
static void packetSent(quint64 length);
|
||||
void updateDisplayMode();
|
||||
void updateInputModes();
|
||||
void domainConnectionRefused(const QString& reasonMessage, int reason);
|
||||
|
||||
private:
|
||||
|
|
|
@ -403,12 +403,6 @@ Menu::Menu() {
|
|||
// Developer > Avatar >>>
|
||||
MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
||||
|
||||
// Settings > Input Devices
|
||||
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced");
|
||||
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
|
||||
inputModeGroup->setExclusive(false);
|
||||
|
||||
|
||||
// Developer > Avatar > Face Tracking
|
||||
MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking");
|
||||
{
|
||||
|
|
|
@ -113,7 +113,6 @@ namespace MenuOption {
|
|||
const QString Help = "Help...";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString InputMenu = "Developer>Avatar>Input Devices";
|
||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
||||
const QString LoadScript = "Open and Run Script File...";
|
||||
|
|
|
@ -84,7 +84,6 @@ Avatar::Avatar(RigPointer rig) :
|
|||
_acceleration(0.0f),
|
||||
_lastAngularVelocity(0.0f),
|
||||
_lastOrientation(),
|
||||
_leanScale(0.5f),
|
||||
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
||||
_moving(false),
|
||||
_initialized(false),
|
||||
|
|
|
@ -210,7 +210,6 @@ protected:
|
|||
glm::vec3 _angularAcceleration;
|
||||
glm::quat _lastOrientation;
|
||||
|
||||
float _leanScale;
|
||||
glm::vec3 _worldUpDirection;
|
||||
float _stringLength;
|
||||
bool _moving; ///< set when position is changing
|
||||
|
|
|
@ -54,8 +54,6 @@ Head::Head(Avatar* owningAvatar) :
|
|||
_deltaPitch(0.0f),
|
||||
_deltaYaw(0.0f),
|
||||
_deltaRoll(0.0f),
|
||||
_deltaLeanSideways(0.0f),
|
||||
_deltaLeanForward(0.0f),
|
||||
_isCameraMoving(false),
|
||||
_isLookingAtMe(false),
|
||||
_lookingAtMeStarted(0),
|
||||
|
@ -70,7 +68,6 @@ void Head::init() {
|
|||
|
||||
void Head::reset() {
|
||||
_baseYaw = _basePitch = _baseRoll = 0.0f;
|
||||
_leanForward = _leanSideways = 0.0f;
|
||||
}
|
||||
|
||||
void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||
|
@ -118,13 +115,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
auto eyeTracker = DependencyManager::get<EyeTracker>();
|
||||
_isEyeTrackerConnected = eyeTracker->isTracking();
|
||||
}
|
||||
|
||||
// Twist the upper body to follow the rotation of the head, but only do this with my avatar,
|
||||
// since everyone else will see the full joint rotations for other people.
|
||||
const float BODY_FOLLOW_HEAD_YAW_RATE = 0.1f;
|
||||
const float BODY_FOLLOW_HEAD_FACTOR = 0.66f;
|
||||
float currentTwist = getTorsoTwist();
|
||||
setTorsoTwist(currentTwist + (getFinalYaw() * BODY_FOLLOW_HEAD_FACTOR - currentTwist) * BODY_FOLLOW_HEAD_YAW_RATE);
|
||||
}
|
||||
|
||||
if (!(_isFaceTrackerConnected || billboard)) {
|
||||
|
@ -301,17 +291,13 @@ void Head::applyEyelidOffset(glm::quat headOrientation) {
|
|||
}
|
||||
}
|
||||
|
||||
void Head::relaxLean(float deltaTime) {
|
||||
void Head::relax(float deltaTime) {
|
||||
// restore rotation, lean to neutral positions
|
||||
const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds
|
||||
float relaxationFactor = 1.0f - glm::min(deltaTime / LEAN_RELAXATION_PERIOD, 1.0f);
|
||||
_deltaYaw *= relaxationFactor;
|
||||
_deltaPitch *= relaxationFactor;
|
||||
_deltaRoll *= relaxationFactor;
|
||||
_leanSideways *= relaxationFactor;
|
||||
_leanForward *= relaxationFactor;
|
||||
_deltaLeanSideways *= relaxationFactor;
|
||||
_deltaLeanForward *= relaxationFactor;
|
||||
}
|
||||
|
||||
void Head::setScale (float scale) {
|
||||
|
@ -419,8 +405,3 @@ float Head::getFinalPitch() const {
|
|||
float Head::getFinalRoll() const {
|
||||
return glm::clamp(_baseRoll + _deltaRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL);
|
||||
}
|
||||
|
||||
void Head::addLeanDeltas(float sideways, float forward) {
|
||||
_deltaLeanSideways += sideways;
|
||||
_deltaLeanForward += forward;
|
||||
}
|
||||
|
|
|
@ -59,8 +59,6 @@ public:
|
|||
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||
glm::vec3 getUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
||||
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
|
||||
float getFinalLeanSideways() const { return _leanSideways + _deltaLeanSideways; }
|
||||
float getFinalLeanForward() const { return _leanForward + _deltaLeanForward; }
|
||||
|
||||
glm::quat getEyeRotation(const glm::vec3& eyePosition) const;
|
||||
|
||||
|
@ -91,8 +89,7 @@ public:
|
|||
virtual float getFinalYaw() const;
|
||||
virtual float getFinalRoll() const;
|
||||
|
||||
void relaxLean(float deltaTime);
|
||||
void addLeanDeltas(float sideways, float forward);
|
||||
void relax(float deltaTime);
|
||||
|
||||
float getTimeWithoutTalking() const { return _timeWithoutTalking; }
|
||||
|
||||
|
@ -132,10 +129,6 @@ private:
|
|||
float _deltaYaw;
|
||||
float _deltaRoll;
|
||||
|
||||
// delta lean angles for lean perturbations (driven by collisions)
|
||||
float _deltaLeanSideways;
|
||||
float _deltaLeanForward;
|
||||
|
||||
bool _isCameraMoving;
|
||||
bool _isLookingAtMe;
|
||||
quint64 _lookingAtMeStarted;
|
||||
|
|
|
@ -190,9 +190,6 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
if (!headData->getBlendshapeCoefficients().isEmpty()) {
|
||||
_headData->setBlendshapeCoefficients(headData->getBlendshapeCoefficients());
|
||||
}
|
||||
// head lean
|
||||
_headData->setLeanForward(headData->getLeanForward());
|
||||
_headData->setLeanSideways(headData->getLeanSideways());
|
||||
// head orientation
|
||||
_headData->setLookAtPosition(headData->getLookAtPosition());
|
||||
}
|
||||
|
@ -237,7 +234,7 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
|||
void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter));
|
||||
QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter), Q_ARG(bool, andReload), Q_ARG(bool, andHead));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -306,7 +303,7 @@ void MyAvatar::update(float deltaTime) {
|
|||
}
|
||||
|
||||
Head* head = getHead();
|
||||
head->relaxLean(deltaTime);
|
||||
head->relax(deltaTime);
|
||||
updateFromTrackers(deltaTime);
|
||||
|
||||
// Get audio loudness data from audio input device
|
||||
|
@ -574,16 +571,6 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
|
||||
head->setDeltaRoll(estimatedRotation.z);
|
||||
}
|
||||
|
||||
// Update torso lean distance based on accelerometer data
|
||||
const float TORSO_LENGTH = 0.5f;
|
||||
glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f);
|
||||
|
||||
const float MAX_LEAN = 45.0f;
|
||||
head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)),
|
||||
-MAX_LEAN, MAX_LEAN));
|
||||
head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)),
|
||||
-MAX_LEAN, MAX_LEAN));
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getLeftHandPosition() const {
|
||||
|
@ -692,7 +679,6 @@ void MyAvatar::saveData() {
|
|||
|
||||
settings.setValue("headPitch", getHead()->getBasePitch());
|
||||
|
||||
settings.setValue("leanScale", _leanScale);
|
||||
settings.setValue("scale", _targetScale);
|
||||
|
||||
settings.setValue("fullAvatarURL",
|
||||
|
@ -739,7 +725,7 @@ void MyAvatar::saveData() {
|
|||
settings.endGroup();
|
||||
}
|
||||
|
||||
float loadSetting(QSettings& settings, const char* name, float defaultValue) {
|
||||
float loadSetting(Settings& settings, const QString& name, float defaultValue) {
|
||||
float value = settings.value(name, defaultValue).toFloat();
|
||||
if (glm::isnan(value)) {
|
||||
value = defaultValue;
|
||||
|
@ -809,7 +795,6 @@ void MyAvatar::loadData() {
|
|||
|
||||
getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f));
|
||||
|
||||
_leanScale = loadSetting(settings, "leanScale", 0.05f);
|
||||
_targetScale = loadSetting(settings, "scale", 1.0f);
|
||||
setScale(glm::vec3(_targetScale));
|
||||
|
||||
|
@ -1214,7 +1199,10 @@ void MyAvatar::updateMotors() {
|
|||
if (_characterController.getState() == CharacterController::State::Hover) {
|
||||
motorRotation = getHead()->getCameraOrientation();
|
||||
} else {
|
||||
motorRotation = getOrientation();
|
||||
// non-hovering = walking: follow camera twist about vertical but not lift
|
||||
// so we decompose camera's rotation and store the twist part in motorRotation
|
||||
glm::quat liftRotation;
|
||||
swingTwistDecomposition(getHead()->getCameraOrientation(), _worldUpDirection, liftRotation, motorRotation);
|
||||
}
|
||||
const float DEFAULT_MOTOR_TIMESCALE = 0.2f;
|
||||
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
||||
|
@ -1268,13 +1256,13 @@ void MyAvatar::prepareForPhysicsSimulation() {
|
|||
void MyAvatar::harvestResultsFromPhysicsSimulation(float deltaTime) {
|
||||
glm::vec3 position = getPosition();
|
||||
glm::quat orientation = getOrientation();
|
||||
if (_characterController.isEnabled()) {
|
||||
if (_characterController.isEnabledAndReady()) {
|
||||
_characterController.getPositionAndOrientation(position, orientation);
|
||||
}
|
||||
nextAttitude(position, orientation);
|
||||
_bodySensorMatrix = _follow.postPhysicsUpdate(*this, _bodySensorMatrix);
|
||||
|
||||
if (_characterController.isEnabled()) {
|
||||
if (_characterController.isEnabledAndReady()) {
|
||||
setVelocity(_characterController.getLinearVelocity() + _characterController.getFollowVelocity());
|
||||
} else {
|
||||
setVelocity(getVelocity() + _characterController.getFollowVelocity());
|
||||
|
@ -1657,7 +1645,7 @@ void MyAvatar::updatePosition(float deltaTime) {
|
|||
|
||||
vec3 velocity = getVelocity();
|
||||
const float MOVING_SPEED_THRESHOLD_SQUARED = 0.0001f; // 0.01 m/s
|
||||
if (!_characterController.isEnabled()) {
|
||||
if (!_characterController.isEnabledAndReady()) {
|
||||
// _characterController is not in physics simulation but it can still compute its target velocity
|
||||
updateMotors();
|
||||
_characterController.computeNewVelocity(deltaTime, velocity);
|
||||
|
@ -1831,6 +1819,16 @@ void MyAvatar::updateMotionBehaviorFromMenu() {
|
|||
_motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
||||
}
|
||||
|
||||
setCharacterControllerEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController));
|
||||
}
|
||||
|
||||
void MyAvatar::setCharacterControllerEnabled(bool enabled) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setCharacterControllerEnabled", Q_ARG(bool, enabled));
|
||||
return;
|
||||
}
|
||||
|
||||
bool ghostingAllowed = true;
|
||||
EntityTreeRenderer* entityTreeRenderer = qApp->getEntities();
|
||||
if (entityTreeRenderer) {
|
||||
|
@ -1839,12 +1837,11 @@ void MyAvatar::updateMotionBehaviorFromMenu() {
|
|||
ghostingAllowed = zone->getGhostingAllowed();
|
||||
}
|
||||
}
|
||||
bool checked = menu->isOptionChecked(MenuOption::EnableCharacterController);
|
||||
if (!ghostingAllowed) {
|
||||
checked = true;
|
||||
}
|
||||
_characterController.setEnabled(ghostingAllowed ? enabled : true);
|
||||
}
|
||||
|
||||
_characterController.setEnabled(checked);
|
||||
bool MyAvatar::getCharacterControllerEnabled() {
|
||||
return _characterController.isEnabled();
|
||||
}
|
||||
|
||||
void MyAvatar::clearDriveKeys() {
|
||||
|
@ -2052,14 +2049,17 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co
|
|||
|
||||
void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) {
|
||||
_desiredBodyMatrix = desiredBodyMatrix;
|
||||
if (!isActive(Rotation) && shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
activate(Rotation);
|
||||
}
|
||||
if (!isActive(Horizontal) && shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
activate(Horizontal);
|
||||
}
|
||||
if (!isActive(Vertical) && (shouldActivateVertical(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
|
||||
activate(Vertical);
|
||||
|
||||
if (myAvatar.getHMDLeanRecenterEnabled()) {
|
||||
if (!isActive(Rotation) && shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
activate(Rotation);
|
||||
}
|
||||
if (!isActive(Horizontal) && shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
activate(Horizontal);
|
||||
}
|
||||
if (!isActive(Vertical) && (shouldActivateVertical(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
|
||||
activate(Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 desiredWorldMatrix = myAvatar.getSensorToWorldMatrix() * _desiredBodyMatrix;
|
||||
|
|
|
@ -69,7 +69,6 @@ class MyAvatar : public Avatar {
|
|||
Q_PROPERTY(AudioListenerMode audioListenerModeCustom READ getAudioListenerModeCustom)
|
||||
//TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity)
|
||||
|
||||
|
||||
Q_PROPERTY(glm::vec3 leftHandPosition READ getLeftHandPosition)
|
||||
Q_PROPERTY(glm::vec3 rightHandPosition READ getRightHandPosition)
|
||||
Q_PROPERTY(glm::vec3 leftHandTipPosition READ getLeftHandTipPosition)
|
||||
|
@ -84,6 +83,9 @@ class MyAvatar : public Avatar {
|
|||
|
||||
Q_PROPERTY(float energy READ getEnergy WRITE setEnergy)
|
||||
|
||||
Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled)
|
||||
Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled)
|
||||
|
||||
public:
|
||||
explicit MyAvatar(RigPointer rig);
|
||||
~MyAvatar();
|
||||
|
@ -123,9 +125,6 @@ public:
|
|||
|
||||
void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); }
|
||||
|
||||
void setLeanScale(float scale) { _leanScale = scale; }
|
||||
float getLeanScale() const { return _leanScale; }
|
||||
|
||||
Q_INVOKABLE glm::vec3 getDefaultEyePosition() const;
|
||||
|
||||
float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); }
|
||||
|
@ -163,6 +162,9 @@ public:
|
|||
Q_INVOKABLE bool getClearOverlayWhenDriving() const { return _clearOverlayWhenDriving; }
|
||||
Q_INVOKABLE void setClearOverlayWhenDriving(bool on) { _clearOverlayWhenDriving = on; }
|
||||
|
||||
Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; }
|
||||
Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; }
|
||||
|
||||
// get/set avatar data
|
||||
void saveData();
|
||||
void loadData();
|
||||
|
@ -264,6 +266,9 @@ public:
|
|||
controller::Pose getLeftHandControllerPoseInAvatarFrame() const;
|
||||
controller::Pose getRightHandControllerPoseInAvatarFrame() const;
|
||||
|
||||
Q_INVOKABLE void setCharacterControllerEnabled(bool enabled);
|
||||
Q_INVOKABLE bool getCharacterControllerEnabled();
|
||||
|
||||
public slots:
|
||||
void increaseSize();
|
||||
void decreaseSize();
|
||||
|
@ -470,6 +475,8 @@ private:
|
|||
ThreadSafeValueCache<controller::Pose> _leftHandControllerPoseInSensorFrameCache { controller::Pose() };
|
||||
ThreadSafeValueCache<controller::Pose> _rightHandControllerPoseInSensorFrameCache { controller::Pose() };
|
||||
|
||||
bool _hmdLeanRecenterEnabled = true;
|
||||
|
||||
float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f };
|
||||
float AUDIO_ENERGY_CONSTANT { 0.000001f };
|
||||
float MAX_AVATAR_MOVEMENT_PER_FRAME { 30.0f };
|
||||
|
|
|
@ -106,10 +106,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
|
||||
|
||||
Rig::HeadParameters headParams;
|
||||
headParams.enableLean = qApp->isHMDMode();
|
||||
headParams.leanSideways = head->getFinalLeanSideways();
|
||||
headParams.leanForward = head->getFinalLeanForward();
|
||||
headParams.torsoTwist = head->getTorsoTwist();
|
||||
|
||||
if (qApp->isHMDMode()) {
|
||||
headParams.isInHMD = true;
|
||||
|
@ -131,7 +127,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
|
||||
}
|
||||
|
||||
headParams.leanJointIndex = geometry.leanJointIndex;
|
||||
headParams.neckJointIndex = geometry.neckJointIndex;
|
||||
headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f;
|
||||
|
||||
|
|
|
@ -46,6 +46,12 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
bool instanceMightBeRunning = true;
|
||||
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Try to create a shared memory block - if it can't be created, there is an instance of
|
||||
// interface already running. We only do this on Windows for now because of the potential
|
||||
|
@ -64,12 +70,6 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
// Try to connect - if we can't connect, interface has probably just gone down
|
||||
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
||||
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption urlOption("url", "", "value");
|
||||
parser.addOption(urlOption);
|
||||
|
@ -135,7 +135,7 @@ int main(int argc, const char* argv[]) {
|
|||
// Oculus initialization MUST PRECEDE OpenGL context creation.
|
||||
// The nature of the Application constructor means this has to be either here,
|
||||
// or in the main window ctor, before GL startup.
|
||||
Application::initPlugins();
|
||||
Application::initPlugins(arguments);
|
||||
|
||||
int exitCode;
|
||||
{
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
ClipboardScriptingInterface::ClipboardScriptingInterface() {
|
||||
}
|
||||
|
||||
glm::vec3 ClipboardScriptingInterface::getContentsDimensions() {
|
||||
return qApp->getEntityClipboard()->getContentsDimensions();
|
||||
}
|
||||
|
||||
float ClipboardScriptingInterface::getClipboardContentsLargestDimension() {
|
||||
return qApp->getEntityClipboard()->getContentsLargestDimension();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ signals:
|
|||
void readyToImport();
|
||||
|
||||
public slots:
|
||||
glm::vec3 getContentsDimensions(); /// returns the overall dimensions of everything on the blipboard
|
||||
float getClipboardContentsLargestDimension(); /// returns the largest dimension of everything on the clipboard
|
||||
bool importEntities(const QString& filename);
|
||||
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
|
||||
|
|
|
@ -129,16 +129,6 @@ void setupPreferences() {
|
|||
preference->setStep(1);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getLeanScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setLeanScale(value); };
|
||||
auto preference = new SpinnerPreference(AVATAR_TUNING, "Lean scale (applies to Faceshift users)", getter, setter);
|
||||
preference->setMin(0);
|
||||
preference->setMax(99.9f);
|
||||
preference->setDecimals(2);
|
||||
preference->setStep(1);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getUniformScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setTargetScaleVerbose(value); }; // The hell?
|
||||
|
|
|
@ -931,11 +931,6 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
|
|||
}
|
||||
|
||||
void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) {
|
||||
if (params.enableLean) {
|
||||
updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist);
|
||||
} else {
|
||||
_animVars.unset("lean");
|
||||
}
|
||||
updateNeckJoint(params.neckJointIndex, params);
|
||||
|
||||
_animVars.set("isTalking", params.isTalking);
|
||||
|
@ -953,15 +948,6 @@ static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f);
|
|||
static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f);
|
||||
static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f);
|
||||
|
||||
void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) {
|
||||
if (isIndexValid(index)) {
|
||||
glm::quat absRot = (glm::angleAxis(-RADIANS_PER_DEGREE * leanSideways, Z_AXIS) *
|
||||
glm::angleAxis(-RADIANS_PER_DEGREE * leanForward, X_AXIS) *
|
||||
glm::angleAxis(RADIANS_PER_DEGREE * torsoTwist, Y_AXIS));
|
||||
_animVars.set("lean", absRot);
|
||||
}
|
||||
}
|
||||
|
||||
void Rig::computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut,
|
||||
glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) const {
|
||||
|
||||
|
|
|
@ -42,15 +42,10 @@ public:
|
|||
};
|
||||
|
||||
struct HeadParameters {
|
||||
float leanSideways = 0.0f; // degrees
|
||||
float leanForward = 0.0f; // degrees
|
||||
float torsoTwist = 0.0f; // degrees
|
||||
bool enableLean = false;
|
||||
glm::quat worldHeadOrientation = glm::quat(); // world space (-z forward)
|
||||
glm::quat rigHeadOrientation = glm::quat(); // rig space (-z forward)
|
||||
glm::vec3 rigHeadPosition = glm::vec3(); // rig space
|
||||
bool isInHMD = false;
|
||||
int leanJointIndex = -1;
|
||||
int neckJointIndex = -1;
|
||||
bool isTalking = false;
|
||||
};
|
||||
|
@ -222,7 +217,6 @@ protected:
|
|||
void applyOverridePoses();
|
||||
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut);
|
||||
|
||||
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||
void updateNeckJoint(int index, const HeadParameters& params);
|
||||
void computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut,
|
||||
glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) const;
|
||||
|
|
|
@ -14,552 +14,11 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "AudioSRC.h"
|
||||
#include "AudioSRCData.h"
|
||||
|
||||
//
|
||||
// prototype lowpass filter
|
||||
//
|
||||
// Minimum-phase equiripple FIR
|
||||
// taps = 96, oversampling = 32
|
||||
//
|
||||
// passband = 0.918
|
||||
// stopband = 1.010
|
||||
// passband ripple = +-0.01dB
|
||||
// stopband attn = -125dB (-70dB at 1.000)
|
||||
//
|
||||
static const int PROTOTYPE_TAPS = 96; // filter taps per phase
|
||||
static const int PROTOTYPE_PHASES = 32; // oversampling factor
|
||||
|
||||
static const float prototypeFilter[PROTOTYPE_TAPS * PROTOTYPE_PHASES] = {
|
||||
0.00000000e+00f, 1.55021703e-05f, 1.46054865e-05f, 2.07057160e-05f, 2.91335519e-05f, 4.00091078e-05f,
|
||||
5.33544450e-05f, 7.03618468e-05f, 9.10821639e-05f, 1.16484613e-04f, 1.47165999e-04f, 1.84168304e-04f,
|
||||
2.28429617e-04f, 2.80913884e-04f, 3.42940399e-04f, 4.15773039e-04f, 5.01023255e-04f, 6.00234953e-04f,
|
||||
7.15133271e-04f, 8.47838855e-04f, 1.00032516e-03f, 1.17508881e-03f, 1.37452550e-03f, 1.60147614e-03f,
|
||||
1.85886458e-03f, 2.14985024e-03f, 2.47783071e-03f, 2.84666764e-03f, 3.26016878e-03f, 3.72252797e-03f,
|
||||
4.23825900e-03f, 4.81207874e-03f, 5.44904143e-03f, 6.15447208e-03f, 6.93399929e-03f, 7.79337059e-03f,
|
||||
8.73903392e-03f, 9.77729117e-03f, 1.09149561e-02f, 1.21591316e-02f, 1.35171164e-02f, 1.49965439e-02f,
|
||||
1.66053136e-02f, 1.83515384e-02f, 2.02435362e-02f, 2.22899141e-02f, 2.44995340e-02f, 2.68813362e-02f,
|
||||
2.94443254e-02f, 3.21979928e-02f, 3.51514690e-02f, 3.83143719e-02f, 4.16960560e-02f, 4.53060504e-02f,
|
||||
4.91538115e-02f, 5.32486197e-02f, 5.75998650e-02f, 6.22164253e-02f, 6.71072811e-02f, 7.22809789e-02f,
|
||||
7.77457552e-02f, 8.35095233e-02f, 8.95796944e-02f, 9.59631768e-02f, 1.02666457e-01f, 1.09695215e-01f,
|
||||
1.17054591e-01f, 1.24748885e-01f, 1.32781656e-01f, 1.41155521e-01f, 1.49872243e-01f, 1.58932534e-01f,
|
||||
1.68335961e-01f, 1.78081143e-01f, 1.88165339e-01f, 1.98584621e-01f, 2.09333789e-01f, 2.20406193e-01f,
|
||||
2.31793899e-01f, 2.43487398e-01f, 2.55475740e-01f, 2.67746404e-01f, 2.80285305e-01f, 2.93076743e-01f,
|
||||
3.06103423e-01f, 3.19346351e-01f, 3.32784916e-01f, 3.46396772e-01f, 3.60158039e-01f, 3.74043042e-01f,
|
||||
3.88024564e-01f, 4.02073759e-01f, 4.16160177e-01f, 4.30251886e-01f, 4.44315429e-01f, 4.58315954e-01f,
|
||||
4.72217175e-01f, 4.85981675e-01f, 4.99570709e-01f, 5.12944586e-01f, 5.26062401e-01f, 5.38882630e-01f,
|
||||
5.51362766e-01f, 5.63459860e-01f, 5.75130384e-01f, 5.86330458e-01f, 5.97016050e-01f, 6.07143161e-01f,
|
||||
6.16667840e-01f, 6.25546499e-01f, 6.33735979e-01f, 6.41193959e-01f, 6.47878856e-01f, 6.53750084e-01f,
|
||||
6.58768549e-01f, 6.62896349e-01f, 6.66097381e-01f, 6.68337353e-01f, 6.69583869e-01f, 6.69807061e-01f,
|
||||
6.68979117e-01f, 6.67075139e-01f, 6.64072812e-01f, 6.59952827e-01f, 6.54699116e-01f, 6.48298688e-01f,
|
||||
6.40742160e-01f, 6.32023668e-01f, 6.22141039e-01f, 6.11095903e-01f, 5.98893921e-01f, 5.85544600e-01f,
|
||||
5.71061707e-01f, 5.55463040e-01f, 5.38770639e-01f, 5.21010762e-01f, 5.02213839e-01f, 4.82414572e-01f,
|
||||
4.61651859e-01f, 4.39968628e-01f, 4.17412000e-01f, 3.94032951e-01f, 3.69886464e-01f, 3.45031084e-01f,
|
||||
3.19529091e-01f, 2.93446187e-01f, 2.66851164e-01f, 2.39815999e-01f, 2.12415399e-01f, 1.84726660e-01f,
|
||||
1.56829293e-01f, 1.28804933e-01f, 1.00736965e-01f, 7.27100355e-02f, 4.48100810e-02f, 1.71237415e-02f,
|
||||
-1.02620228e-02f, -3.72599591e-02f, -6.37832871e-02f, -8.97457733e-02f, -1.15062201e-01f, -1.39648782e-01f,
|
||||
-1.63423488e-01f, -1.86306368e-01f, -2.08220103e-01f, -2.29090072e-01f, -2.48845046e-01f, -2.67417270e-01f,
|
||||
-2.84742946e-01f, -3.00762597e-01f, -3.15421127e-01f, -3.28668542e-01f, -3.40459849e-01f, -3.50755400e-01f,
|
||||
-3.59521402e-01f, -3.66729768e-01f, -3.72358475e-01f, -3.76391839e-01f, -3.78820421e-01f, -3.79641287e-01f,
|
||||
-3.78858203e-01f, -3.76481336e-01f, -3.72527677e-01f, -3.67020780e-01f, -3.59990760e-01f, -3.51474372e-01f,
|
||||
-3.41514630e-01f, -3.30160971e-01f, -3.17468898e-01f, -3.03499788e-01f, -2.88320749e-01f, -2.72004315e-01f,
|
||||
-2.54628056e-01f, -2.36274454e-01f, -2.17030464e-01f, -1.96986952e-01f, -1.76238733e-01f, -1.54883647e-01f,
|
||||
-1.33022496e-01f, -1.10758449e-01f, -8.81964466e-02f, -6.54430504e-02f, -4.26055475e-02f, -1.97916415e-02f,
|
||||
2.89108184e-03f, 2.53355868e-02f, 4.74362201e-02f, 6.90887518e-02f, 9.01914308e-02f, 1.10644978e-01f,
|
||||
1.30353494e-01f, 1.49224772e-01f, 1.67170735e-01f, 1.84107975e-01f, 1.99958067e-01f, 2.14648181e-01f,
|
||||
2.28111323e-01f, 2.40286622e-01f, 2.51119890e-01f, 2.60563701e-01f, 2.68577740e-01f, 2.75129027e-01f,
|
||||
2.80192144e-01f, 2.83749177e-01f, 2.85790223e-01f, 2.86312986e-01f, 2.85323221e-01f, 2.82834421e-01f,
|
||||
2.78867915e-01f, 2.73452721e-01f, 2.66625431e-01f, 2.58429983e-01f, 2.48917457e-01f, 2.38145826e-01f,
|
||||
2.26179680e-01f, 2.13089734e-01f, 1.98952740e-01f, 1.83850758e-01f, 1.67870897e-01f, 1.51104879e-01f,
|
||||
1.33648388e-01f, 1.15600665e-01f, 9.70639763e-02f, 7.81429119e-02f, 5.89439889e-02f, 3.95749746e-02f,
|
||||
2.01442353e-02f, 7.60241152e-04f, -1.84690990e-02f, -3.74370397e-02f, -5.60385970e-02f, -7.41711039e-02f,
|
||||
-9.17348686e-02f, -1.08633632e-01f, -1.24775254e-01f, -1.40071993e-01f, -1.54441372e-01f, -1.67806284e-01f,
|
||||
-1.80095654e-01f, -1.91244732e-01f, -2.01195605e-01f, -2.09897310e-01f, -2.17306320e-01f, -2.23386736e-01f,
|
||||
-2.28110407e-01f, -2.31457193e-01f, -2.33415044e-01f, -2.33980051e-01f, -2.33156463e-01f, -2.30956673e-01f,
|
||||
-2.27401097e-01f, -2.22518148e-01f, -2.16343899e-01f, -2.08921985e-01f, -2.00303365e-01f, -1.90545790e-01f,
|
||||
-1.79713804e-01f, -1.67877977e-01f, -1.55114789e-01f, -1.41505907e-01f, -1.27137921e-01f, -1.12101628e-01f,
|
||||
-9.64915640e-02f, -8.04054232e-02f, -6.39434707e-02f, -4.72078814e-02f, -3.03021635e-02f, -1.33305082e-02f,
|
||||
3.60284977e-03f, 2.03942507e-02f, 3.69413014e-02f, 5.31433810e-02f, 6.89024656e-02f, 8.41234679e-02f,
|
||||
9.87150268e-02f, 1.12589969e-01f, 1.25665865e-01f, 1.37865538e-01f, 1.49117506e-01f, 1.59356490e-01f,
|
||||
1.68523664e-01f, 1.76567229e-01f, 1.83442499e-01f, 1.89112308e-01f, 1.93547212e-01f, 1.96725586e-01f,
|
||||
1.98633878e-01f, 1.99266486e-01f, 1.98625999e-01f, 1.96723008e-01f, 1.93576075e-01f, 1.89211557e-01f,
|
||||
1.83663562e-01f, 1.76973516e-01f, 1.69190033e-01f, 1.60368490e-01f, 1.50570805e-01f, 1.39864815e-01f,
|
||||
1.28324021e-01f, 1.16026978e-01f, 1.03056879e-01f, 8.95008829e-02f, 7.54496798e-02f, 6.09968238e-02f,
|
||||
4.62380664e-02f, 3.12708901e-02f, 1.61936956e-02f, 1.10531988e-03f, -1.38957653e-02f, -2.87119784e-02f,
|
||||
-4.32472742e-02f, -5.74078385e-02f, -7.11026311e-02f, -8.42439713e-02f, -9.67481917e-02f, -1.08536049e-01f,
|
||||
-1.19533350e-01f, -1.29671345e-01f, -1.38887238e-01f, -1.47124498e-01f, -1.54333373e-01f, -1.60470968e-01f,
|
||||
-1.65501755e-01f, -1.69397631e-01f, -1.72138140e-01f, -1.73710602e-01f, -1.74110159e-01f, -1.73339798e-01f,
|
||||
-1.71410274e-01f, -1.68340111e-01f, -1.64155335e-01f, -1.58889414e-01f, -1.52582850e-01f, -1.45283122e-01f,
|
||||
-1.37044042e-01f, -1.27925722e-01f, -1.17993860e-01f, -1.07319421e-01f, -9.59781808e-02f, -8.40500777e-02f,
|
||||
-7.16188049e-02f, -5.87710561e-02f, -4.55961475e-02f, -3.21851919e-02f, -1.86306406e-02f, -5.02554942e-03f,
|
||||
8.53698384e-03f, 2.19645467e-02f, 3.51659468e-02f, 4.80518693e-02f, 6.05355056e-02f, 7.25330700e-02f,
|
||||
8.39645094e-02f, 9.47537898e-02f, 1.04829753e-01f, 1.14126254e-01f, 1.22582788e-01f, 1.30144907e-01f,
|
||||
1.36764459e-01f, 1.42400029e-01f, 1.47017076e-01f, 1.50588312e-01f, 1.53093700e-01f, 1.54520736e-01f,
|
||||
1.54864367e-01f, 1.54127119e-01f, 1.52318991e-01f, 1.49457408e-01f, 1.45567062e-01f, 1.40679709e-01f,
|
||||
1.34833933e-01f, 1.28074855e-01f, 1.20453893e-01f, 1.12028129e-01f, 1.02860307e-01f, 9.30178765e-02f,
|
||||
8.25730032e-02f, 7.16016450e-02f, 6.01833134e-02f, 4.84002546e-02f, 3.63370724e-02f, 2.40800037e-02f,
|
||||
1.17163168e-02f, -6.66217400e-04f, -1.29801121e-02f, -2.51385315e-02f, -3.70562030e-02f, -4.86497748e-02f,
|
||||
-5.98384928e-02f, -7.05447859e-02f, -8.06947592e-02f, -9.02187441e-02f, -9.90517313e-02f, -1.07133911e-01f,
|
||||
-1.14410951e-01f, -1.20834483e-01f, -1.26362422e-01f, -1.30959116e-01f, -1.34595787e-01f, -1.37250547e-01f,
|
||||
-1.38908600e-01f, -1.39562374e-01f, -1.39211442e-01f, -1.37862602e-01f, -1.35529795e-01f, -1.32233909e-01f,
|
||||
-1.28002721e-01f, -1.22870611e-01f, -1.16878278e-01f, -1.10072477e-01f, -1.02505698e-01f, -9.42356124e-02f,
|
||||
-8.53248753e-02f, -7.58404912e-02f, -6.58532924e-02f, -5.54376360e-02f, -4.46705953e-02f, -3.36315414e-02f,
|
||||
-2.24015972e-02f, -1.10628991e-02f, 3.01894735e-04f, 1.16101918e-02f, 2.27801642e-02f, 3.37311642e-02f,
|
||||
4.43845430e-02f, 5.46640016e-02f, 6.44962637e-02f, 7.38115400e-02f, 8.25440784e-02f, 9.06325572e-02f,
|
||||
9.80206066e-02f, 1.04657146e-01f, 1.10496723e-01f, 1.15499920e-01f, 1.19633523e-01f, 1.22870824e-01f,
|
||||
1.25191729e-01f, 1.26582959e-01f, 1.27038061e-01f, 1.26557494e-01f, 1.25148528e-01f, 1.22825305e-01f,
|
||||
1.19608512e-01f, 1.15525479e-01f, 1.10609643e-01f, 1.04900592e-01f, 9.84435537e-02f, 9.12890948e-02f,
|
||||
8.34927732e-02f, 7.51146973e-02f, 6.62190194e-02f, 5.68735547e-02f, 4.71491262e-02f, 3.71191855e-02f,
|
||||
2.68591932e-02f, 1.64459573e-02f, 5.95731808e-03f, -4.52874940e-03f, -1.49344723e-02f, -2.51829130e-02f,
|
||||
-3.51986373e-02f, -4.49081427e-02f, -5.42404654e-02f, -6.31276969e-02f, -7.15054163e-02f, -7.93132713e-02f,
|
||||
-8.64953327e-02f, -9.30005042e-02f, -9.87829011e-02f, -1.03802223e-01f, -1.08023943e-01f, -1.11419636e-01f,
|
||||
-1.13967111e-01f, -1.15650603e-01f, -1.16460855e-01f, -1.16395152e-01f, -1.15457368e-01f, -1.13657871e-01f,
|
||||
-1.11013433e-01f, -1.07547117e-01f, -1.03288073e-01f, -9.82712708e-02f, -9.25372646e-02f, -8.61318657e-02f,
|
||||
-7.91057486e-02f, -7.15141053e-02f, -6.34161588e-02f, -5.48747791e-02f, -4.59559696e-02f, -3.67282941e-02f,
|
||||
-2.72624874e-02f, -1.76307914e-02f, -7.90648674e-03f, 1.83670340e-03f, 1.15251424e-02f, 2.10858716e-02f,
|
||||
3.04471304e-02f, 3.95388944e-02f, 4.82933904e-02f, 5.66456655e-02f, 6.45340054e-02f, 7.19003487e-02f,
|
||||
7.86908695e-02f, 8.48562395e-02f, 9.03519908e-02f, 9.51389501e-02f, 9.91834077e-02f, 1.02457361e-01f,
|
||||
1.04938834e-01f, 1.06611872e-01f, 1.07466724e-01f, 1.07499917e-01f, 1.06714213e-01f, 1.05118588e-01f,
|
||||
1.02728167e-01f, 9.95640680e-02f, 9.56532488e-02f, 9.10282406e-02f, 8.57269309e-02f, 7.97922261e-02f,
|
||||
7.32717395e-02f, 6.62174249e-02f, 5.86850536e-02f, 5.07339959e-02f, 4.24265058e-02f, 3.38274345e-02f,
|
||||
2.50036502e-02f, 1.60234844e-02f, 6.95628026e-03f, -2.12820655e-03f, -1.11602438e-02f, -2.00708281e-02f,
|
||||
-2.87920337e-02f, -3.72576320e-02f, -4.54035426e-02f, -5.31684173e-02f, -6.04938939e-02f, -6.73253212e-02f,
|
||||
-7.36119310e-02f, -7.93072981e-02f, -8.43697556e-02f, -8.87625537e-02f, -9.24542939e-02f, -9.54189981e-02f,
|
||||
-9.76364402e-02f, -9.90921435e-02f, -9.97776003e-02f, -9.96902366e-02f, -9.88334463e-02f, -9.72165780e-02f,
|
||||
-9.48547668e-02f, -9.17688999e-02f, -8.79853312e-02f, -8.35357688e-02f, -7.84569594e-02f, -7.27903677e-02f,
|
||||
-6.65818940e-02f, -5.98814932e-02f, -5.27427333e-02f, -4.52224733e-02f, -3.73802459e-02f, -2.92780037e-02f,
|
||||
-2.09794209e-02f, -1.25495498e-02f, -4.05425988e-03f, 4.44034349e-03f, 1.28682571e-02f, 2.11643361e-02f,
|
||||
2.92645357e-02f, 3.71066200e-02f, 4.46305203e-02f, 5.17788267e-02f, 5.84972389e-02f, 6.47349496e-02f,
|
||||
7.04450836e-02f, 7.55849928e-02f, 8.01165748e-02f, 8.40066506e-02f, 8.72270848e-02f, 8.97550618e-02f,
|
||||
9.15732179e-02f, 9.26698315e-02f, 9.30387881e-02f, 9.26796720e-02f, 9.15978025e-02f, 8.98040443e-02f,
|
||||
8.73148489e-02f, 8.41520461e-02f, 8.03426093e-02f, 7.59185468e-02f, 7.09165136e-02f, 6.53776255e-02f,
|
||||
5.93470480e-02f, 5.28736293e-02f, 4.60095655e-02f, 3.88099545e-02f, 3.13323302e-02f, 2.36362162e-02f,
|
||||
1.57827398e-02f, 7.83395091e-03f, -1.47413782e-04f, -8.09864153e-03f, -1.59574406e-02f, -2.36623595e-02f,
|
||||
-3.11534717e-02f, -3.83725840e-02f, -4.52638947e-02f, -5.17743411e-02f, -5.78539729e-02f, -6.34564348e-02f,
|
||||
-6.85392092e-02f, -7.30640654e-02f, -7.69971954e-02f, -8.03096220e-02f, -8.29772975e-02f, -8.49813524e-02f,
|
||||
-8.63081836e-02f, -8.69495746e-02f, -8.69027157e-02f, -8.61702687e-02f, -8.47602668e-02f, -8.26860569e-02f,
|
||||
-7.99661981e-02f, -7.66242997e-02f, -7.26887788e-02f, -6.81926752e-02f, -6.31733712e-02f, -5.76722279e-02f,
|
||||
-5.17343061e-02f, -4.54080069e-02f, -3.87446321e-02f, -3.17980032e-02f, -2.46239897e-02f, -1.72801497e-02f,
|
||||
-9.82518156e-03f, -2.31845300e-03f, 5.18037510e-03f, 1.26119044e-02f, 1.99174857e-02f, 2.70395921e-02f,
|
||||
3.39223499e-02f, 4.05119404e-02f, 4.67570465e-02f, 5.26092142e-02f, 5.80232695e-02f, 6.29576539e-02f,
|
||||
6.73747113e-02f, 7.12410320e-02f, 7.45276905e-02f, 7.72104218e-02f, 7.92698394e-02f, 8.06915952e-02f,
|
||||
8.14664004e-02f, 8.15901977e-02f, 8.10640907e-02f, 7.98943315e-02f, 7.80922975e-02f, 7.56743792e-02f,
|
||||
7.26617861e-02f, 6.90804346e-02f, 6.49606433e-02f, 6.03370049e-02f, 5.52479503e-02f, 4.97355660e-02f,
|
||||
4.38451300e-02f, 3.76248662e-02f, 3.11254263e-02f, 2.43995757e-02f, 1.75017105e-02f, 1.04874823e-02f,
|
||||
3.41321948e-03f, -3.66433362e-03f, -1.06886566e-02f, -1.76037566e-02f, -2.43547422e-02f, -3.08881238e-02f,
|
||||
-3.71523818e-02f, -4.30982377e-02f, -4.86791529e-02f, -5.38515978e-02f, -5.85754991e-02f, -6.28144137e-02f,
|
||||
-6.65359631e-02f, -6.97119559e-02f, -7.23186409e-02f, -7.43369897e-02f, -7.57526047e-02f, -7.65560812e-02f,
|
||||
-7.67428560e-02f, -7.63134051e-02f, -7.52730583e-02f, -7.36321241e-02f, -7.14055927e-02f, -6.86132027e-02f,
|
||||
-6.52791213e-02f, -6.14318004e-02f, -5.71037475e-02f, -5.23312158e-02f, -4.71539306e-02f, -4.16147519e-02f,
|
||||
-3.57593331e-02f, -2.96357023e-02f, -2.32939478e-02f, -1.67857228e-02f, -1.01639251e-02f, -3.48213128e-03f,
|
||||
3.20566951e-03f, 9.84566549e-03f, 1.63845318e-02f, 2.27699627e-02f, 2.89509937e-02f, 3.48784838e-02f,
|
||||
4.05054571e-02f, 4.57875191e-02f, 5.06831561e-02f, 5.51541055e-02f, 5.91656321e-02f, 6.26867948e-02f,
|
||||
6.56907214e-02f, 6.81547545e-02f, 7.00607045e-02f, 7.13948753e-02f, 7.21482790e-02f, 7.23165894e-02f,
|
||||
7.19002973e-02f, 7.09044846e-02f, 6.93390331e-02f, 6.72183039e-02f, 6.45611568e-02f, 6.13906537e-02f,
|
||||
5.77340810e-02f, 5.36223917e-02f, 4.90902973e-02f, 4.41756853e-02f, 3.89195025e-02f, 3.33653266e-02f,
|
||||
2.75589553e-02f, 2.15482187e-02f, 1.53823433e-02f, 9.11173206e-03f, 2.78750380e-03f, -3.53899736e-03f,
|
||||
-9.81648845e-03f, -1.59942887e-02f, -2.20226002e-02f, -2.78530676e-02f, -3.34389835e-02f, -3.87358558e-02f,
|
||||
-4.37015752e-02f, -4.82968641e-02f, -5.24856104e-02f, -5.62350079e-02f, -5.95160314e-02f, -6.23034090e-02f,
|
||||
-6.45760369e-02f, -6.63170246e-02f, -6.75138263e-02f, -6.81583864e-02f, -6.82471093e-02f, -6.77809819e-02f,
|
||||
-6.67654439e-02f, -6.52104027e-02f, -6.31301405e-02f, -6.05431381e-02f, -5.74719510e-02f, -5.39430121e-02f,
|
||||
-4.99864152e-02f, -4.56356108e-02f, -4.09271785e-02f, -3.59005358e-02f, -3.05975021e-02f, -2.50620982e-02f,
|
||||
-1.93400931e-02f, -1.34786109e-02f, -7.52582921e-03f, -1.53047296e-03f, 4.45846396e-03f, 1.03922252e-02f,
|
||||
1.62226043e-02f, 2.19024111e-02f, 2.73857927e-02f, 3.26286453e-02f, 3.75889120e-02f, 4.22270162e-02f,
|
||||
4.65060678e-02f, 5.03922602e-02f, 5.38550360e-02f, 5.68673912e-02f, 5.94061299e-02f, 6.14518959e-02f,
|
||||
6.29894927e-02f, 6.40078422e-02f, 6.45002081e-02f, 6.44641312e-02f, 6.39014463e-02f, 6.28183549e-02f,
|
||||
6.12252434e-02f, 5.91366226e-02f, 5.65710713e-02f, 5.35509478e-02f, 5.01023211e-02f, 4.62546289e-02f,
|
||||
4.20405644e-02f, 3.74956324e-02f, 3.26580309e-02f, 2.75681921e-02f, 2.22685138e-02f, 1.68029869e-02f,
|
||||
1.12168479e-02f, 5.55616360e-03f, -1.32475496e-04f, -5.80242145e-03f, -1.14072870e-02f, -1.69013632e-02f,
|
||||
-2.22399629e-02f, -2.73798231e-02f, -3.22793559e-02f, -3.68992177e-02f, -4.12022700e-02f, -4.51542301e-02f,
|
||||
-4.87237130e-02f, -5.18825743e-02f, -5.46061242e-02f, -5.68733215e-02f, -5.86668721e-02f, -5.99735198e-02f,
|
||||
-6.07838952e-02f, -6.10928895e-02f, -6.08993923e-02f, -6.02064781e-02f, -5.90213291e-02f, -5.73550887e-02f,
|
||||
-5.52228853e-02f, -5.26435817e-02f, -4.96396897e-02f, -4.62371294e-02f, -4.24650256e-02f, -3.83554628e-02f,
|
||||
-3.39432096e-02f, -2.92654225e-02f, -2.43613233e-02f, -1.92718970e-02f, -1.40395616e-02f, -8.70771728e-03f,
|
||||
-3.32056777e-03f, 2.07744785e-03f, 7.44190391e-03f, 1.27287222e-02f, 1.78946228e-02f, 2.28975002e-02f,
|
||||
2.76965843e-02f, 3.22530140e-02f, 3.65299534e-02f, 4.04930363e-02f, 4.41105069e-02f, 4.73536159e-02f,
|
||||
5.01967201e-02f, 5.26175750e-02f, 5.45974724e-02f, 5.61213729e-02f, 5.71780843e-02f, 5.77601946e-02f,
|
||||
5.78643759e-02f, 5.74910914e-02f, 5.66448597e-02f, 5.53340158e-02f, 5.35707338e-02f, 5.13708843e-02f,
|
||||
4.87538683e-02f, 4.57425137e-02f, 4.23627999e-02f, 3.86437075e-02f, 3.46169024e-02f, 3.03165387e-02f,
|
||||
2.57788894e-02f, 2.10421222e-02f, 1.61459251e-02f, 1.11311994e-02f, 6.03970466e-03f, 9.13695817e-04f,
|
||||
-4.20433431e-03f, -9.27218149e-03f, -1.42480682e-02f, -1.90911878e-02f, -2.37618648e-02f, -2.82220093e-02f,
|
||||
-3.24353766e-02f, -3.63678336e-02f, -3.99876924e-02f, -4.32659237e-02f, -4.61764207e-02f, -4.86961602e-02f,
|
||||
-5.08054551e-02f, -5.24880386e-02f, -5.37312181e-02f, -5.45260166e-02f, -5.48671104e-02f, -5.47530531e-02f,
|
||||
-5.41860463e-02f, -5.31721475e-02f, -5.17210363e-02f, -4.98459868e-02f, -4.75637647e-02f, -4.48944406e-02f,
|
||||
-4.18612746e-02f, -3.84904206e-02f, -3.48107925e-02f, -3.08537797e-02f, -2.66529685e-02f, -2.22438695e-02f,
|
||||
-1.76636682e-02f, -1.29507560e-02f, -8.14466071e-03f, -3.28544776e-03f, 1.58643018e-03f, 6.43050440e-03f,
|
||||
1.12067405e-02f, 1.58756642e-02f, 2.03989020e-02f, 2.47393345e-02f, 2.88614617e-02f, 3.27317634e-02f,
|
||||
3.63187992e-02f, 3.95936470e-02f, 4.25300387e-02f, 4.51045672e-02f, 4.72968940e-02f, 4.90899703e-02f,
|
||||
5.04700047e-02f, 5.14267809e-02f, 5.19535643e-02f, 5.20472034e-02f, 5.17082287e-02f, 5.09406434e-02f,
|
||||
4.97521048e-02f, 4.81537188e-02f, 4.61599131e-02f, 4.37884262e-02f, 4.10600706e-02f, 3.79985488e-02f,
|
||||
3.46302622e-02f, 3.09841217e-02f, 2.70912412e-02f, 2.29847199e-02f, 1.86992847e-02f, 1.42711599e-02f,
|
||||
9.73752669e-03f, 5.13643650e-03f, 5.06379454e-04f, -4.11408166e-03f, -8.68649476e-03f, -1.31729621e-02f,
|
||||
-1.75363807e-02f, -2.17408089e-02f, -2.57516979e-02f, -2.95362143e-02f, -3.30635093e-02f, -3.63049622e-02f,
|
||||
-3.92344048e-02f, -4.18283298e-02f, -4.40661418e-02f, -4.59301913e-02f, -4.74060505e-02f, -4.84825511e-02f,
|
||||
-4.91518827e-02f, -4.94096235e-02f, -4.92548579e-02f, -4.86900251e-02f, -4.77210458e-02f, -4.63571741e-02f,
|
||||
-4.46108878e-02f, -4.24979107e-02f, -4.00368564e-02f, -3.72492987e-02f, -3.41594108e-02f, -3.07938448e-02f,
|
||||
-2.71814552e-02f, -2.33531198e-02f, -1.93413598e-02f, -1.51802063e-02f, -1.09048013e-02f, -6.55114338e-03f,
|
||||
-2.15581014e-03f, 2.24443555e-03f, 6.61280814e-03f, 1.09129453e-02f, 1.51091980e-02f, 1.91667630e-02f,
|
||||
2.30522168e-02f, 2.67335907e-02f, 3.01807365e-02f, 3.33655579e-02f, 3.62622051e-02f, 3.88473226e-02f,
|
||||
4.11002204e-02f, 4.30030300e-02f, 4.45408790e-02f, 4.57019705e-02f, 4.64777109e-02f, 4.68627135e-02f,
|
||||
4.68549093e-02f, 4.64554958e-02f, 4.56689373e-02f, 4.45029599e-02f, 4.29683919e-02f, 4.10791386e-02f,
|
||||
3.88520159e-02f, 3.63066475e-02f, 3.34652385e-02f, 3.03523892e-02f, 2.69949681e-02f, 2.34217263e-02f,
|
||||
1.96632025e-02f, 1.57513974e-02f, 1.17194459e-02f, 7.60145677e-03f, 3.43215481e-03f, -7.53454950e-04f,
|
||||
-4.92025229e-03f, -9.03345904e-03f, -1.30587503e-02f, -1.69627406e-02f, -2.07130441e-02f, -2.42787472e-02f,
|
||||
-2.76304969e-02f, -3.07408842e-02f, -3.35845310e-02f, -3.61384026e-02f, -3.83819804e-02f, -4.02973364e-02f,
|
||||
-4.18693911e-02f, -4.30859849e-02f, -4.39379525e-02f, -4.44192202e-02f, -4.45268207e-02f, -4.42609489e-02f,
|
||||
-4.36249417e-02f, -4.26251693e-02f, -4.12710965e-02f, -3.95751119e-02f, -3.75524034e-02f, -3.52209020e-02f,
|
||||
-3.26010732e-02f, -2.97156826e-02f, -2.65897306e-02f, -2.32501339e-02f, -1.97255230e-02f, -1.60459906e-02f,
|
||||
-1.22428645e-02f, -8.34840613e-03f, -4.39555788e-03f, -4.17641093e-04f, 3.55186529e-03f, 7.47969548e-03f,
|
||||
1.13330289e-02f, 1.50796895e-02f, 1.86886063e-02f, 2.21298440e-02f, 2.53750227e-02f, 2.83974776e-02f,
|
||||
3.11724713e-02f, 3.36774564e-02f, 3.58921485e-02f, 3.77988281e-02f, 3.93823848e-02f, 4.06304645e-02f,
|
||||
4.15335460e-02f, 4.20850895e-02f, 4.22814530e-02f, 4.21220657e-02f, 4.16092724e-02f, 4.07484568e-02f,
|
||||
3.95478256e-02f, 3.80185099e-02f, 3.61742882e-02f, 3.40316228e-02f, 3.16093467e-02f, 2.89286854e-02f,
|
||||
2.60129143e-02f, 2.28872072e-02f, 1.95785162e-02f, 1.61151429e-02f, 1.25266872e-02f, 8.84367289e-03f,
|
||||
5.09737541e-03f, 1.31946573e-03f, -2.45819207e-03f, -6.20382907e-03f, -9.88599514e-03f, -1.34739714e-02f,
|
||||
-1.69377975e-02f, -2.02487225e-02f, -2.33793144e-02f, -2.63038233e-02f, -2.89981802e-02f, -3.14404213e-02f,
|
||||
-3.36107546e-02f, -3.54916723e-02f, -3.70682427e-02f, -3.83280672e-02f, -3.92614736e-02f, -3.98615776e-02f,
|
||||
-4.01243243e-02f, -4.00484517e-02f, -3.96356708e-02f, -3.88903731e-02f, -3.78198781e-02f, -3.64341365e-02f,
|
||||
-3.47457457e-02f, -3.27698392e-02f, -3.05238882e-02f, -2.80276282e-02f, -2.53028218e-02f, -2.23730957e-02f,
|
||||
-1.92637467e-02f, -1.60015029e-02f, -1.26142882e-02f, -9.13104283e-03f, -5.58138981e-03f, -1.99542434e-03f,
|
||||
1.59649307e-03f, 5.16408174e-03f, 8.67737144e-03f, 1.21068581e-02f, 1.54239205e-02f, 1.86009100e-02f,
|
||||
2.16114772e-02f, 2.44306994e-02f, 2.70354163e-02f, 2.94042665e-02f, 3.15179985e-02f, 3.33595356e-02f,
|
||||
3.49141593e-02f, 3.61696229e-02f, 3.71161871e-02f, 3.77468512e-02f, 3.80571878e-02f, 3.80455485e-02f,
|
||||
3.77129900e-02f, 3.70632810e-02f, 3.61028508e-02f, 3.48407199e-02f, 3.32884428e-02f, 3.14600053e-02f,
|
||||
2.93716228e-02f, 2.70417408e-02f, 2.44907277e-02f, 2.17407576e-02f, 1.88156734e-02f, 1.57406803e-02f,
|
||||
1.25421761e-02f, 9.24754692e-03f, 5.88488640e-03f, 2.48280587e-03f, -9.29864758e-04f, -4.32426314e-03f,
|
||||
-7.67179184e-03f, -1.09442952e-02f, -1.41143886e-02f, -1.71555974e-02f, -2.00425787e-02f, -2.27514891e-02f,
|
||||
-2.52599054e-02f, -2.75472706e-02f, -2.95949315e-02f, -3.13863062e-02f, -3.29069832e-02f, -3.41450096e-02f,
|
||||
-3.50907101e-02f, -3.57369992e-02f, -3.60793163e-02f, -3.61156751e-02f, -3.58467080e-02f, -3.52755740e-02f,
|
||||
-3.44080617e-02f, -3.32523628e-02f, -3.18191314e-02f, -3.01213186e-02f, -2.81740846e-02f, -2.59946393e-02f,
|
||||
-2.36021125e-02f, -2.10173975e-02f, -1.82629132e-02f, -1.53624700e-02f, -1.23410560e-02f, -9.22456599e-03f,
|
||||
-6.03967755e-03f, -2.81350877e-03f, 4.26514319e-04f, 3.65292660e-03f, 6.83848944e-03f, 9.95638508e-03f,
|
||||
1.29804234e-02f, 1.58853076e-02f, 1.86468203e-02f, 2.12420277e-02f, 2.36494909e-02f, 2.58493792e-02f,
|
||||
2.78237450e-02f, 2.95565060e-02f, 3.10338053e-02f, 3.22438572e-02f, 3.31772716e-02f, 3.38269627e-02f,
|
||||
3.41883176e-02f, 3.42591610e-02f, 3.40397435e-02f, 3.35328606e-02f, 3.27436351e-02f, 3.16796573e-02f,
|
||||
3.03507246e-02f, 2.87689689e-02f, 2.69484839e-02f, 2.49054827e-02f, 2.26579086e-02f, 2.02254442e-02f,
|
||||
1.76292617e-02f, 1.48918382e-02f, 1.20368159e-02f, 9.08872468e-03f, 6.07283273e-03f, 3.01489838e-03f,
|
||||
-5.90212194e-05f, -3.12287666e-03f, -6.15069532e-03f, -9.11695091e-03f, -1.19967033e-02f, -1.47657868e-02f,
|
||||
-1.74011004e-02f, -1.98807214e-02f, -2.21841025e-02f, -2.42922632e-02f, -2.61879368e-02f, -2.78557311e-02f,
|
||||
-2.92821801e-02f, -3.04559562e-02f, -3.13678907e-02f, -3.20110632e-02f, -3.23808087e-02f, -3.24749193e-02f,
|
||||
-3.22933847e-02f, -3.18386269e-02f, -3.11153366e-02f, -3.01304804e-02f, -2.88932552e-02f, -2.74148734e-02f,
|
||||
-2.57086673e-02f, -2.37898314e-02f, -2.16752343e-02f, -1.93835013e-02f, -1.69345799e-02f, -1.43497284e-02f,
|
||||
-1.16513243e-02f, -8.86259097e-03f, -6.00748525e-03f, -3.11044903e-03f, -1.96143386e-04f, 2.71056658e-03f,
|
||||
5.58512222e-03f, 8.40318833e-03f, 1.11410160e-02f, 1.37756382e-02f, 1.62850338e-02f, 1.86482666e-02f,
|
||||
2.08457445e-02f, 2.28593437e-02f, 2.46725329e-02f, 2.62705694e-02f, 2.76405329e-02f, 2.87715470e-02f,
|
||||
2.96547092e-02f, 3.02833419e-02f, 3.06529059e-02f, 3.07610441e-02f, 3.06076742e-02f, 3.01949567e-02f,
|
||||
2.95271502e-02f, 2.86107876e-02f, 2.74543883e-02f, 2.60685701e-02f, 2.44657863e-02f, 2.26603655e-02f,
|
||||
2.06682557e-02f, 1.85070033e-02f, 1.61954603e-02f, 1.37537720e-02f, 1.12030588e-02f, 8.56537064e-03f,
|
||||
5.86336215e-03f, 3.12021752e-03f, 3.59345288e-04f, -2.39571357e-03f, -5.12158252e-03f, -7.79518527e-03f,
|
||||
-1.03939536e-02f, -1.28961026e-02f, -1.52805838e-02f, -1.75275761e-02f, -1.96183935e-02f, -2.15357712e-02f,
|
||||
-2.32639542e-02f, -2.47888545e-02f, -2.60981899e-02f, -2.71814567e-02f, -2.80302370e-02f, -2.86380088e-02f,
|
||||
-2.90003996e-02f, -2.91151172e-02f, -2.89819544e-02f, -2.86028697e-02f, -2.79818317e-02f, -2.71249297e-02f,
|
||||
-2.60401957e-02f, -2.47375751e-02f, -2.32288414e-02f, -2.15275091e-02f, -1.96486443e-02f, -1.76087964e-02f,
|
||||
-1.54258426e-02f, -1.31187994e-02f, -1.07076937e-02f, -8.21335282e-03f, -5.65730582e-03f, -3.06143405e-03f,
|
||||
-4.47990175e-04f, 2.16074548e-03f, 4.74260737e-03f, 7.27569124e-03f, 9.73864733e-03f, 1.21106824e-02f,
|
||||
1.43719841e-02f, 1.65036001e-02f, 1.84878471e-02f, 2.03083286e-02f, 2.19500531e-02f, 2.33996493e-02f,
|
||||
2.46453861e-02f, 2.56773512e-02f, 2.64874345e-02f, 2.70694463e-02f, 2.74192279e-02f, 2.75344951e-02f,
|
||||
2.74150667e-02f, 2.70627089e-02f, 2.64811913e-02f, 2.56761950e-02f, 2.46553112e-02f, 2.34279326e-02f,
|
||||
2.20051823e-02f, 2.03998041e-02f, 1.86260730e-02f, 1.66996483e-02f, 1.46373888e-02f, 1.24573628e-02f,
|
||||
1.01784699e-02f, 7.82046099e-03f, 5.40366356e-03f, 2.94886537e-03f, 4.77074685e-04f, -1.99056008e-03f,
|
||||
-4.43309957e-03f, -6.82975366e-03f, -9.16032780e-03f, -1.14051392e-02f, -1.35453571e-02f, -1.55631186e-02f,
|
||||
-1.74416221e-02f, -1.91653203e-02f, -2.07200521e-02f, -2.20931290e-02f, -2.32734389e-02f, -2.42515770e-02f,
|
||||
-2.50198790e-02f, -2.55724740e-02f, -2.59053977e-02f, -2.60165073e-02f, -2.59056121e-02f, -2.55744100e-02f,
|
||||
-2.50263861e-02f, -2.42670139e-02f, -2.33034172e-02f, -2.21444752e-02f, -2.08007704e-02f, -1.92843016e-02f,
|
||||
-1.76086143e-02f, -1.57885066e-02f, -1.38399632e-02f, -1.17800468e-02f, -9.62665505e-03f, -7.39846180e-03f,
|
||||
-5.11473979e-03f, -2.79509520e-03f, -4.59475153e-04f, 1.87219411e-03f, 4.18004886e-03f, 6.44446028e-03f,
|
||||
8.64630036e-03f, 1.07670050e-02f, 1.27887263e-02f, 1.46946183e-02f, 1.64687696e-02f, 1.80965074e-02f,
|
||||
1.95644657e-02f, 2.08606409e-02f, 2.19745569e-02f, 2.28973400e-02f, 2.36217678e-02f, 2.41423032e-02f,
|
||||
2.44552329e-02f, 2.45585559e-02f, 2.44521268e-02f, 2.41375247e-02f, 2.36181843e-02f, 2.28991883e-02f,
|
||||
2.19873596e-02f, 2.08911372e-02f, 1.96204854e-02f, 1.81868423e-02f, 1.66029686e-02f, 1.48829260e-02f,
|
||||
1.30418196e-02f, 1.10957823e-02f, 9.06176569e-03f, 6.95742371e-03f, 4.80095797e-03f, 2.61094572e-03f,
|
||||
4.06163422e-04f, -1.79448120e-03f, -3.97227507e-03f, -6.10867089e-03f, -8.18559133e-03f, -1.01855447e-02f,
|
||||
-1.20916775e-02f, -1.38880736e-02f, -1.55597947e-02f, -1.70929424e-02f, -1.84749792e-02f, -1.96945768e-02f,
|
||||
-2.07419008e-02f, -2.16086011e-02f, -2.22879060e-02f, -2.27746496e-02f, -2.30653527e-02f, -2.31582122e-02f,
|
||||
-2.30530853e-02f, -2.27516002e-02f, -2.22569518e-02f, -2.15740851e-02f, -2.07094459e-02f, -1.96710504e-02f,
|
||||
-1.84683607e-02f, -1.71122258e-02f, -1.56147530e-02f, -1.39891960e-02f, -1.22499260e-02f, -1.04121226e-02f,
|
||||
-8.49187069e-03f, -6.50583812e-03f, -4.47121574e-03f, -2.40553061e-03f, -3.26560349e-04f, 1.74792849e-03f,
|
||||
3.80020986e-03f, 5.81284812e-03f, 7.76878436e-03f, 9.65152189e-03f, 1.14452321e-02f, 1.31348903e-02f,
|
||||
1.47064602e-02f, 1.61469015e-02f, 1.74443880e-02f, 1.85883329e-02f, 1.95694960e-02f, 2.03800747e-02f,
|
||||
2.10137416e-02f, 2.14657028e-02f, 2.17327470e-02f, 2.18132189e-02f, 2.17071096e-02f, 2.14159688e-02f,
|
||||
2.09429396e-02f, 2.02927056e-02f, 1.94714591e-02f, 1.84867806e-02f, 1.73476996e-02f, 1.60644888e-02f,
|
||||
1.46486021e-02f, 1.31126305e-02f, 1.14700918e-02f, 9.73543186e-03f, 7.92379251e-03f, 6.05090462e-03f,
|
||||
4.13301608e-03f, 2.18669055e-03f, 2.28581333e-04f, -1.72441072e-03f, -3.65572200e-03f, -5.54887990e-03f,
|
||||
-7.38782061e-03f, -9.15706782e-03f, -1.08417082e-02f, -1.24276657e-02f, -1.39017311e-02f, -1.52516970e-02f,
|
||||
-1.64664949e-02f, -1.75361817e-02f, -1.84521823e-02f, -1.92071599e-02f, -1.97953056e-02f, -2.02121243e-02f,
|
||||
-2.04547147e-02f, -2.05216098e-02f, -2.04128534e-02f, -2.01300439e-02f, -1.96761990e-02f, -1.90558123e-02f,
|
||||
-1.82748056e-02f, -1.73404276e-02f, -1.62612067e-02f, -1.50469098e-02f, -1.37084115e-02f, -1.22575769e-02f,
|
||||
-1.07072432e-02f, -9.07102930e-03f, -7.36320826e-03f, -5.59869147e-03f, -3.79270806e-03f, -1.96092013e-03f,
|
||||
-1.19027325e-04f, 1.71713152e-03f, 3.53191747e-03f, 5.30986343e-03f, 7.03590331e-03f, 8.69547560e-03f,
|
||||
1.02746006e-02f, 1.17601122e-02f, 1.31396009e-02f, 1.44016653e-02f, 1.55359973e-02f, 1.65332483e-02f,
|
||||
1.73855033e-02f, 1.80859434e-02f, 1.86291305e-02f, 1.90110277e-02f, 1.92289384e-02f, 1.92815880e-02f,
|
||||
1.91691688e-02f, 1.88932135e-02f, 1.84567183e-02f, 1.78639790e-02f, 1.71206377e-02f, 1.62336473e-02f,
|
||||
1.52110920e-02f, 1.40622274e-02f, 1.27973510e-02f, 1.14277163e-02f, 9.96541843e-03f, 8.42333112e-03f,
|
||||
6.81491991e-03f, 5.15420944e-03f, 3.45559138e-03f, 1.73374462e-03f, 3.49154958e-06f, -1.72033182e-03f,
|
||||
-3.42300908e-03f, -5.09002877e-03f, -6.70728983e-03f, -8.26110592e-03f, -9.73843101e-03f, -1.11269177e-02f,
|
||||
-1.24149972e-02f, -1.35920411e-02f, -1.46483675e-02f, -1.55754162e-02f, -1.63657097e-02f, -1.70130158e-02f,
|
||||
-1.75123254e-02f, -1.78599156e-02f, -1.80533642e-02f, -1.80916471e-02f, -1.79749596e-02f, -1.77049199e-02f,
|
||||
-1.72844059e-02f, -1.67175734e-02f, -1.60098348e-02f, -1.51677846e-02f, -1.41991369e-02f, -1.31126308e-02f,
|
||||
-1.19180614e-02f, -1.06260158e-02f, -9.24795820e-03f, -7.79599691e-03f, -6.28282689e-03f, -4.72166017e-03f,
|
||||
-3.12602130e-03f, -1.50971188e-03f, 1.13358008e-04f, 1.72924640e-03f, 3.32419869e-03f, 4.88457483e-03f,
|
||||
6.39719332e-03f, 7.84928507e-03f, 9.22860374e-03f, 1.05236737e-02f, 1.17237027e-02f, 1.28187631e-02f,
|
||||
1.37999219e-02f, 1.46591627e-02f, 1.53896448e-02f, 1.59855771e-02f, 1.64423748e-02f, 1.67566705e-02f,
|
||||
1.69263151e-02f, 1.69504088e-02f, 1.68293192e-02f, 1.65646048e-02f, 1.61591292e-02f, 1.56168830e-02f,
|
||||
1.49430466e-02f, 1.41438870e-02f, 1.32267343e-02f, 1.21999194e-02f, 1.10726150e-02f, 9.85491162e-03f,
|
||||
8.55755480e-03f, 7.19198626e-03f, 5.77013714e-03f, 4.30443841e-03f, 2.80758857e-03f, 1.29252809e-03f,
|
||||
-2.27683018e-04f, -1.74000213e-03f, -3.23153173e-03f, -4.68956247e-03f, -6.10171563e-03f, -7.45612506e-03f,
|
||||
-8.74136426e-03f, -9.94672023e-03f, -1.10621909e-02f, -1.20785406e-02f, -1.29874795e-02f, -1.37816456e-02f,
|
||||
-1.44546479e-02f, -1.50012468e-02f, -1.54172106e-02f, -1.56995155e-02f, -1.58462779e-02f, -1.58567437e-02f,
|
||||
-1.57313825e-02f, -1.54717967e-02f, -1.50807184e-02f, -1.45620705e-02f, -1.39207297e-02f, -1.31627253e-02f,
|
||||
-1.22950111e-02f, -1.13254027e-02f, -1.02626834e-02f, -9.11627932e-03f, -7.89634415e-03f, -6.61364765e-03f,
|
||||
-5.27939952e-03f, -3.90525708e-03f, -2.50314317e-03f, -1.08517576e-03f, 3.36418391e-04f, 1.74945190e-03f,
|
||||
3.14186033e-03f, 4.50178261e-03f, 5.81769448e-03f, 7.07851939e-03f, 8.27365386e-03f, 9.39310326e-03f,
|
||||
1.04276320e-02f, 1.13686527e-02f, 1.22085379e-02f, 1.29404450e-02f, 1.35585678e-02f, 1.40580446e-02f,
|
||||
1.44350939e-02f, 1.46869568e-02f, 1.48120098e-02f, 1.48096348e-02f, 1.46804295e-02f, 1.44259781e-02f,
|
||||
1.40489668e-02f, 1.35531325e-02f, 1.29432014e-02f, 1.22248563e-02f, 1.14046959e-02f, 1.04901687e-02f,
|
||||
9.48948107e-03f, 8.41156632e-03f, 7.26596347e-03f, 6.06280447e-03f, 4.81257444e-03f, 3.52622627e-03f,
|
||||
2.21492506e-03f, 8.89983592e-04f, -4.37153812e-04f, -1.75513167e-03f, -3.05265494e-03f, -4.31872834e-03f,
|
||||
-5.54261874e-03f, -6.71396264e-03f, -7.82302244e-03f, -8.86045250e-03f, -9.81773278e-03f, -1.06869351e-02f,
|
||||
-1.14610023e-02f, -1.21336754e-02f, -1.26995953e-02f, -1.31543908e-02f, -1.34945718e-02f, -1.37177266e-02f,
|
||||
-1.38224110e-02f, -1.38082286e-02f, -1.36757739e-02f, -1.34266887e-02f, -1.30635886e-02f, -1.25900369e-02f,
|
||||
-1.20105709e-02f, -1.13305978e-02f, -1.05563538e-02f, -9.69485926e-03f, -8.75389081e-03f, -7.74181164e-03f,
|
||||
-6.66761679e-03f, -5.54076187e-03f, -4.37111830e-03f, -3.16893052e-03f, -1.94457115e-03f, -7.08705149e-04f,
|
||||
5.28079290e-04f, 1.75515870e-03f, 2.96204304e-03f, 4.13848585e-03f, 5.27451557e-03f, 6.36060039e-03f,
|
||||
7.38755863e-03f, 8.34692530e-03f, 9.23070802e-03f, 1.00316534e-02f, 1.07432528e-02f, 1.13597680e-02f,
|
||||
1.18763350e-02f, 1.22889283e-02f, 1.25944631e-02f, 1.27907515e-02f, 1.28765994e-02f, 1.28517102e-02f,
|
||||
1.27167966e-02f, 1.24734480e-02f, 1.21242371e-02f, 1.16725839e-02f, 1.11228281e-02f, 1.04800592e-02f,
|
||||
9.75022575e-03f, 8.93990424e-03f, 8.05644990e-03f, 7.10768601e-03f, 6.10205625e-03f, 5.04843878e-03f,
|
||||
3.95605458e-03f, 2.83441418e-03f, 1.69331277e-03f, 5.42568186e-04f, -6.07877124e-04f, -1.74818575e-03f,
|
||||
-2.86860405e-03f, -3.95962685e-03f, -5.01201657e-03f, -6.01690058e-03f, -6.96589716e-03f, -7.85110424e-03f,
|
||||
-8.66518231e-03f, -9.40145619e-03f, -1.00540095e-02f, -1.06175123e-02f, -1.10876024e-02f, -1.14606062e-02f,
|
||||
-1.17337519e-02f, -1.19051415e-02f, -1.19737311e-02f, -1.19393909e-02f, -1.18028751e-02f, -1.15657387e-02f,
|
||||
-1.12305357e-02f, -1.08005049e-02f, -1.02797519e-02f, -9.67318729e-03f, -8.98632838e-03f, -8.22543877e-03f,
|
||||
-7.39737215e-03f, -6.50950785e-03f, -5.56975395e-03f, -4.58632875e-03f, -3.56792674e-03f, -2.52340823e-03f,
|
||||
-1.46183597e-03f, -3.92391156e-04f, 6.75701684e-04f, 1.73331709e-03f, 2.77141530e-03f, 3.78118353e-03f,
|
||||
4.75407672e-03f, 5.68193005e-03f, 6.55698994e-03f, 7.37195674e-03f, 8.12013345e-03f, 8.79539509e-03f,
|
||||
9.39225030e-03f, 9.90597190e-03f, 1.03324819e-02f, 1.06685242e-02f, 1.09116177e-02f, 1.10600973e-02f,
|
||||
1.11130936e-02f, 1.10705983e-02f, 1.09333788e-02f, 1.07030445e-02f, 1.03819949e-02f, 9.97335332e-03f,
|
||||
9.48107464e-03f, 8.90968434e-03f, 8.26449756e-03f, 7.55132972e-03f, 6.77664458e-03f, 5.94731079e-03f,
|
||||
5.07073939e-03f, 4.15462520e-03f, 3.20700306e-03f, 2.23616222e-03f, 1.25050340e-03f, 2.58592562e-04f,
|
||||
-7.31105992e-04f, -1.71003848e-03f, -2.66991104e-03f, -3.60254805e-03f, -4.50009626e-03f, -5.35500152e-03f,
|
||||
-6.16013372e-03f, -6.90880302e-03f, -7.59484887e-03f, -8.21267759e-03f, -8.75730297e-03f, -9.22437062e-03f,
|
||||
-9.61022818e-03f, -9.91196266e-03f, -1.01273334e-02f, -1.02549146e-02f, -1.02939949e-02f, -1.02446487e-02f,
|
||||
-1.01077102e-02f, -9.88473930e-03f, -9.57804506e-03f, -9.19065219e-03f, -8.72623997e-03f, -8.18914967e-03f,
|
||||
-7.58431711e-03f, -6.91725624e-03f, -6.19393169e-03f, -5.42085678e-03f, -4.60486090e-03f, -3.75314479e-03f,
|
||||
-2.87318400e-03f, -1.97263669e-03f, -1.05936420e-03f, -1.41184633e-04f, 7.73935206e-04f, 1.67818033e-03f,
|
||||
2.56387121e-03f, 3.42348245e-03f, 4.24972968e-03f, 5.03575853e-03f, 5.77493594e-03f, 6.46117800e-03f,
|
||||
7.08885263e-03f, 7.65282423e-03f, 8.14856911e-03f, 8.57214716e-03f, 8.92027019e-03f, 9.19029194e-03f,
|
||||
9.38027470e-03f, 9.48895025e-03f, 9.51578399e-03f, 9.46091429e-03f, 9.32518284e-03f, 9.11016180e-03f,
|
||||
8.81806173e-03f, 8.45171440e-03f, 8.01466407e-03f, 7.51094572e-03f, 6.94521826e-03f, 6.32261691e-03f,
|
||||
5.64875255e-03f, 4.92963671e-03f, 4.17165548e-03f, 3.38149573e-03f, 2.56610069e-03f, 1.73253154e-03f,
|
||||
8.88083719e-04f, 4.00140997e-05f, -8.04377007e-04f, -1.63786496e-03f, -2.45336348e-03f, -3.24394120e-03f,
|
||||
-4.00297149e-03f, -4.72406012e-03f, -5.40122825e-03f, -6.02886353e-03f, -6.60184564e-03f, -7.11547043e-03f,
|
||||
-7.56567204e-03f, -7.94886879e-03f, -8.26207948e-03f, -8.50298133e-03f, -8.66984745e-03f, -8.76158174e-03f,
|
||||
-8.77778600e-03f, -8.71866903e-03f, -8.58510255e-03f, -8.37858953e-03f, -8.10125332e-03f, -7.75580633e-03f,
|
||||
-7.34555568e-03f, -6.87431135e-03f, -6.34642360e-03f, -5.76669768e-03f, -5.14031767e-03f, -4.47294897e-03f,
|
||||
-3.77043291e-03f, -3.03903272e-03f, -2.28511456e-03f, -1.51527024e-03f, -7.36178447e-04f, 4.54225562e-05f,
|
||||
8.22859022e-04f, 1.58943109e-03f, 2.33866278e-03f, 3.06420334e-03f, 3.75990680e-03f, 4.42002538e-03f,
|
||||
5.03901750e-03f, 5.61180111e-03f, 6.13366220e-03f, 6.60043272e-03f, 7.00831931e-03f, 7.35414500e-03f,
|
||||
7.63524392e-03f, 7.84953557e-03f, 7.99547645e-03f, 8.07218955e-03f, 8.07933095e-03f, 8.01721906e-03f,
|
||||
7.88666864e-03f, 7.68919343e-03f, 7.42679720e-03f, 7.10202788e-03f, 6.71802523e-03f, 6.27832934e-03f,
|
||||
5.78702253e-03f, 5.24853339e-03f, 4.66776048e-03f, 4.04985033e-03f, 3.40032055e-03f, 2.72486114e-03f,
|
||||
2.02943382e-03f, 1.32005555e-03f, 6.02922229e-04f, -1.15810889e-04f, -8.29962401e-04f, -1.53344695e-03f,
|
||||
-2.22024937e-03f, -2.88460828e-03f, -3.52090915e-03f, -4.12386103e-03f, -4.68844782e-03f, -5.21000854e-03f,
|
||||
-5.68433641e-03f, -6.10753890e-03f, -6.47629357e-03f, -6.78770430e-03f, -7.03936807e-03f, -7.22944790e-03f,
|
||||
-7.35662441e-03f, -7.42012069e-03f, -7.41971164e-03f, -7.35573757e-03f, -7.22905724e-03f, -7.04107429e-03f,
|
||||
-6.79370122e-03f, -6.48940038e-03f, -6.13102314e-03f, -5.72192873e-03f, -5.26590521e-03f, -4.76707464e-03f,
|
||||
-4.22993214e-03f, -3.65930825e-03f, -3.06022345e-03f, -2.43797793e-03f, -1.79803310e-03f, -1.14594988e-03f,
|
||||
-4.87389180e-04f, 1.71985886e-04f, 8.26505744e-04f, 1.47057292e-03f, 2.09875564e-03f, 2.70572827e-03f,
|
||||
3.28638788e-03f, 3.83592350e-03f, 4.34975506e-03f, 4.82368759e-03f, 5.25383132e-03f, 5.63677359e-03f,
|
||||
5.96942535e-03f, 6.24924092e-03f, 6.47405650e-03f, 6.64226721e-03f, 6.75269253e-03f, 6.80469430e-03f,
|
||||
6.79815717e-03f, 6.73340631e-03f, 6.61130455e-03f, 6.43322863e-03f, 6.20094526e-03f, 5.91677710e-03f,
|
||||
5.58340169e-03f, 5.20393196e-03f, 4.78187614e-03f, 4.32106320e-03f, 3.82565711e-03f, 3.30005613e-03f,
|
||||
2.74895362e-03f, 2.17719303e-03f, 1.58978015e-03f, 9.91844057e-04f, 3.88540330e-04f, -2.14916878e-04f,
|
||||
-8.13361192e-04f, -1.40168257e-03f, -1.97489740e-03f, -2.52818059e-03f, -3.05688539e-03f, -3.55662656e-03f,
|
||||
-4.02326574e-03f, -4.45296958e-03f, -4.84228652e-03f, -5.18803438e-03f, -5.48755315e-03f, -5.73848611e-03f,
|
||||
-5.93891991e-03f, -6.08745626e-03f, -6.18305471e-03f, -6.22520840e-03f, -6.21382472e-03f, -6.14928419e-03f,
|
||||
-6.03244633e-03f, -5.86455879e-03f, -5.64736180e-03f, -5.38296537e-03f, -5.07389363e-03f, -4.72301916e-03f,
|
||||
-4.33361321e-03f, -3.90915761e-03f, -3.45353173e-03f, -2.97077347e-03f, -2.46516689e-03f, -1.94119584e-03f,
|
||||
-1.40340595e-03f, -8.56512644e-04f, -3.05232133e-04f, 2.45691031e-04f, 7.91538060e-04f, 1.32763724e-03f,
|
||||
1.84949345e-03f, 2.35267547e-03f, 2.83299113e-03f, 3.28645035e-03f, 3.70931698e-03f, 4.09812665e-03f,
|
||||
4.44973511e-03f, 4.76135341e-03f, 5.03050354e-03f, 5.25513155e-03f, 5.43353323e-03f, 5.56447821e-03f,
|
||||
5.64705544e-03f, 5.68083601e-03f, 5.66583437e-03f, 5.60238431e-03f, 5.49135375e-03f, 5.33391723e-03f,
|
||||
5.13169207e-03f, 4.88664671e-03f, 4.60113202e-03f, 4.27780860e-03f, 3.91964875e-03f, 3.52989866e-03f,
|
||||
3.11212090e-03f, 2.66999053e-03f, 2.20744344e-03f, 1.72859110e-03f, 1.23756351e-03f, 7.38678150e-04f,
|
||||
2.36236760e-04f, -2.65462378e-04f, -7.62072815e-04f, -1.24943395e-03f, -1.72337956e-03f, -2.17993754e-03f,
|
||||
-2.61530935e-03f, -3.02588421e-03f, -3.40825196e-03f, -3.75935360e-03f, -4.07630652e-03f, -4.35660760e-03f,
|
||||
-4.59808398e-03f, -4.79883718e-03f, -4.95743843e-03f, -5.07271280e-03f, -5.14393833e-03f, -5.17077608e-03f,
|
||||
-5.15318763e-03f, -5.09164480e-03f, -4.98686807e-03f, -4.84002285e-03f, -4.65260103e-03f, -4.42642977e-03f,
|
||||
-4.16366446e-03f, -3.86678300e-03f, -3.53847751e-03f, -3.18177292e-03f, -2.79986847e-03f, -2.39618401e-03f,
|
||||
-1.97429017e-03f, -1.53788782e-03f, -1.09083664e-03f, -6.36973406e-04f, -1.80264329e-04f, 2.75399352e-04f,
|
||||
7.26104424e-04f, 1.16802598e-03f, 1.59744046e-03f, 2.01073128e-03f, 2.40446819e-03f, 2.77538562e-03f,
|
||||
3.12044615e-03f, 3.43683203e-03f, 3.72202393e-03f, 3.97374850e-03f, 4.19002854e-03f, 4.36925418e-03f,
|
||||
4.51006070e-03f, 4.61152219e-03f, 4.67293053e-03f, 4.69404975e-03f, 4.67490366e-03f, 4.61589307e-03f,
|
||||
4.51775252e-03f, 4.38154991e-03f, 4.20868532e-03f, 4.00082377e-03f, 3.75997274e-03f, 3.48836415e-03f,
|
||||
3.18851504e-03f, 2.86314343e-03f, 2.51519536e-03f, 2.14776743e-03f, 1.76411750e-03f, 1.36763070e-03f,
|
||||
9.61751835e-04f, 5.50052405e-04f, 1.36015058e-04f, -2.76720943e-04f, -6.84698152e-04f, -1.08442387e-03f,
|
||||
-1.47253691e-03f, -1.84578853e-03f, -2.20105818e-03f, -2.53544188e-03f, -2.84616998e-03f, -3.13076058e-03f,
|
||||
-3.38689733e-03f, -3.61260297e-03f, -3.80606518e-03f, -3.96589267e-03f, -4.09087232e-03f, -4.18013173e-03f,
|
||||
-4.23315965e-03f, -4.24970953e-03f, -4.22981560e-03f, -4.17392494e-03f, -4.08267808e-03f, -3.95709577e-03f,
|
||||
-3.79845153e-03f, -3.60829670e-03f, -3.38844338e-03f, -3.14094669e-03f, -2.86809742e-03f, -2.57237442e-03f,
|
||||
-2.25643831e-03f, -1.92312165e-03f, -1.57535841e-03f, -1.21624129e-03f, -8.48868370e-04f, -4.76457354e-04f,
|
||||
-1.02227062e-04f, 2.70659894e-04f, 6.38948957e-04f, 9.99596773e-04f, 1.34950884e-03f, 1.68579412e-03f,
|
||||
2.00565112e-03f, 2.30644176e-03f, 2.58570970e-03f, 2.84121989e-03f, 3.07087670e-03f, 3.27296771e-03f,
|
||||
3.44584695e-03f, 3.58825627e-03f, 3.69915439e-03f, 3.77779535e-03f, 3.82369144e-03f, 3.83666312e-03f,
|
||||
3.81678507e-03f, 3.76444486e-03f, 3.68027755e-03f, 3.56519883e-03f, 3.42038694e-03f, 3.24725992e-03f,
|
||||
3.04745181e-03f, 2.82287635e-03f, 2.57555610e-03f, 2.30778342e-03f, 2.02193938e-03f, 1.72060684e-03f,
|
||||
1.40642226e-03f, 1.08218540e-03f, 7.50708128e-04f, 4.14852040e-04f, 7.75468400e-05f, -2.58336678e-04f,
|
||||
-5.89954675e-04f, -9.14464553e-04f, -1.22917409e-03f, -1.53142096e-03f, -1.81874942e-03f, -2.08875765e-03f,
|
||||
-2.33925204e-03f, -2.56824046e-03f, -2.77387464e-03f, -2.95457151e-03f, -3.10891286e-03f, -3.23576957e-03f,
|
||||
-3.33422309e-03f, -3.40361730e-03f, -3.44352432e-03f, -3.45380945e-03f, -3.43454926e-03f, -3.38612359e-03f,
|
||||
-3.30910238e-03f, -3.20434413e-03f, -3.07289782e-03f, -2.91605448e-03f, -2.73534798e-03f, -2.53242439e-03f,
|
||||
-2.30918427e-03f, -2.06766744e-03f, -1.81002532e-03f, -1.53857461e-03f, -1.25572213e-03f, -9.63956082e-04f,
|
||||
-6.65804929e-04f, -3.63875198e-04f, -6.07622519e-05f, 2.40955893e-04f, 5.38685581e-04f, 8.29936911e-04f,
|
||||
1.11224977e-03f, 1.38328230e-03f, 1.64080028e-03f, 1.88265574e-03f, 2.10694670e-03f, 2.31181334e-03f,
|
||||
2.49567938e-03f, 2.65707799e-03f, 2.79477329e-03f, 2.90778929e-03f, 2.99526804e-03f, 3.05666792e-03f,
|
||||
3.09159989e-03f, 3.09996074e-03f, 3.08183486e-03f, 3.03757314e-03f, 2.96768997e-03f, 2.87296391e-03f,
|
||||
2.75438271e-03f, 2.61305979e-03f, 2.45041225e-03f, 2.26792371e-03f, 2.06728115e-03f, 1.85034398e-03f,
|
||||
1.61901728e-03f, 1.37543970e-03f, 1.12168235e-03f, 8.60048928e-04f, 5.92781787e-04f, 3.22217129e-04f,
|
||||
5.06437951e-05f, -2.19547817e-04f, -4.86132510e-04f, -7.46817210e-04f, -9.99443627e-04f, -1.24188233e-03f,
|
||||
-1.47217245e-03f, -1.68839648e-03f, -1.88883105e-03f, -2.07184785e-03f, -2.23601745e-03f, -2.38006048e-03f,
|
||||
-2.50288118e-03f, -2.60358292e-03f, -2.68144174e-03f, -2.73595307e-03f, -2.76679595e-03f, -2.77388624e-03f,
|
||||
-2.75729794e-03f, -2.71735188e-03f, -2.65451985e-03f, -2.56952130e-03f, -2.46319204e-03f, -2.33660956e-03f,
|
||||
-2.19096493e-03f, -2.02765268e-03f, -1.84815939e-03f, -1.65412932e-03f, -1.44731483e-03f, -1.22956426e-03f,
|
||||
-1.00280075e-03f, -7.69022668e-04f, -5.30268510e-04f, -2.88586883e-04f, -4.60956253e-05f, 1.95186584e-04f,
|
||||
4.33161045e-04f, 6.65873263e-04f, 8.91328897e-04f, 1.10770620e-03f, 1.31316296e-03f, 1.50610067e-03f,
|
||||
1.68489795e-03f, 1.84814923e-03f, 1.99458512e-03f, 2.12304250e-03f, 2.23258384e-03f, 2.32237953e-03f,
|
||||
2.39181962e-03f, 2.44043032e-03f, 2.46796938e-03f, 2.47430968e-03f, 2.45957831e-03f, 2.42401283e-03f,
|
||||
2.36808884e-03f, 2.29238471e-03f, 2.19773378e-03f, 2.08501666e-03f, 1.95534528e-03f, 1.80993801e-03f,
|
||||
1.65014053e-03f, 1.47739854e-03f, 1.29329221e-03f, 1.09944593e-03f, 8.97596290e-04f, 6.89486470e-04f,
|
||||
4.76967544e-04f, 2.61847472e-04f, 4.59979030e-05f, -1.68770369e-04f, -3.80612759e-04f, -5.87744421e-04f,
|
||||
-7.88452414e-04f, -9.81081718e-04f, -1.16402219e-03f, -1.33580811e-03f, -1.49504859e-03f, -1.64047131e-03f,
|
||||
-1.77095587e-03f, -1.88548340e-03f, -1.98318254e-03f, -2.06335667e-03f, -2.12544333e-03f, -2.16903096e-03f,
|
||||
-2.19389731e-03f, -2.19994674e-03f, -2.18726700e-03f, -2.15609170e-03f, -2.10683457e-03f, -2.04002290e-03f,
|
||||
-1.95633800e-03f, -1.85665258e-03f, -1.74189023e-03f, -1.61313165e-03f, -1.47159921e-03f, -1.31856217e-03f,
|
||||
-1.15541374e-03f, -9.83590913e-04f, -8.04645529e-04f, -6.20138811e-04f, -4.31664744e-04f, -2.40859759e-04f,
|
||||
-4.93718861e-05f, 1.41183920e-04f, 3.29184443e-04f, 5.13049545e-04f, 6.91252710e-04f, 8.62329668e-04f,
|
||||
1.02486089e-03f, 1.17753306e-03f, 1.31912530e-03f, 1.44851584e-03f, 1.56468190e-03f, 1.66675270e-03f,
|
||||
1.75393226e-03f, 1.82562545e-03f, 1.88129935e-03f, 1.92062935e-03f, 1.94336360e-03f, 1.94946381e-03f,
|
||||
1.93898469e-03f, 1.91211060e-03f, 1.86925265e-03f, 1.81081128e-03f, 1.73745800e-03f, 1.64989979e-03f,
|
||||
1.54896085e-03f, 1.43565148e-03f, 1.31095906e-03f, 1.17607031e-03f, 1.03219054e-03f, 8.80596006e-04f,
|
||||
7.22634695e-04f, 5.59715925e-04f, 3.93223384e-04f, 2.24602808e-04f, 5.53223372e-05f, -1.13204206e-04f,
|
||||
-2.79527886e-04f, -4.42273875e-04f, -6.00090187e-04f, -7.51646708e-04f, -8.95738714e-04f, -1.03117771e-03f,
|
||||
-1.15687770e-03f, -1.27187587e-03f, -1.37523688e-03f, -1.46618576e-03f, -1.54403989e-03f, -1.60825931e-03f,
|
||||
-1.65836399e-03f, -1.69405240e-03f, -1.71514183e-03f, -1.72154028e-03f, -1.71331327e-03f, -1.69063272e-03f,
|
||||
-1.65381037e-03f, -1.60326168e-03f, -1.53948863e-03f, -1.46318779e-03f, -1.37503217e-03f, -1.27591969e-03f,
|
||||
-1.16672308e-03f, -1.04846883e-03f, -9.22232848e-04f, -7.89108246e-04f, -6.50329911e-04f, -5.07057241e-04f,
|
||||
-3.60579584e-04f, -2.12138548e-04f, -6.30166060e-05f, 8.55107333e-05f, 2.32212191e-04f, 3.75851456e-04f,
|
||||
5.15213418e-04f, 6.49182851e-04f, 7.76642588e-04f, 8.96585347e-04f, 1.00803198e-03f, 1.11010987e-03f,
|
||||
1.20203475e-03f, 1.28308439e-03f, 1.35268783e-03f, 1.41030687e-03f, 1.45558664e-03f, 1.48819124e-03f,
|
||||
1.50798717e-03f, 1.51486502e-03f, 1.50888467e-03f, 1.49022209e-03f, 1.45906012e-03f, 1.41583581e-03f,
|
||||
1.36095722e-03f, 1.29499749e-03f, 1.21859138e-03f, 1.13249419e-03f, 1.03745344e-03f, 9.34384957e-04f,
|
||||
8.24209226e-04f, 7.07921644e-04f, 5.86535461e-04f, 4.61118668e-04f, 3.32797940e-04f, 2.02615430e-04f,
|
||||
7.17560319e-05f, -5.87215139e-05f, -1.87700771e-04f, -3.14093799e-04f, -4.36855019e-04f, -5.54982470e-04f,
|
||||
-6.67514567e-04f, -7.73539543e-04f, -8.72216549e-04f, -9.62754726e-04f, -1.04446836e-03f, -1.11673823e-03f,
|
||||
-1.17901020e-03f, -1.23084835e-03f, -1.27191263e-03f, -1.30189831e-03f, -1.32066941e-03f, -1.32816613e-03f,
|
||||
-1.32437715e-03f, -1.30944714e-03f, -1.28360668e-03f, -1.24710492e-03f, -1.20038313e-03f, -1.14391116e-03f,
|
||||
-1.07822250e-03f, -1.00394823e-03f, -9.21799577e-04f, -8.32520513e-04f, -7.36916195e-04f, -6.35853312e-04f,
|
||||
-5.30218398e-04f, -4.20950684e-04f, -3.08981087e-04f, -1.95310152e-04f, -8.08721649e-05f, 3.33481785e-05f,
|
||||
1.46369769e-04f, 2.57271691e-04f, 3.65123878e-04f, 4.69053422e-04f, 5.68205019e-04f, 6.61777482e-04f,
|
||||
7.49035427e-04f, 8.29295760e-04f, 9.01919035e-04f, 9.66370937e-04f, 1.02218113e-03f, 1.06892877e-03f,
|
||||
1.10630552e-03f, 1.13406370e-03f, 1.15204451e-03f, 1.16019052e-03f, 1.15848806e-03f, 1.14706630e-03f,
|
||||
1.12606449e-03f, 1.09574589e-03f, 1.05645362e-03f, 1.00859266e-03f, 9.52601766e-04f, 8.89057609e-04f,
|
||||
8.18535938e-04f, 7.41697389e-04f, 6.59241262e-04f, 5.71884368e-04f, 4.80414698e-04f, 3.85677252e-04f,
|
||||
2.88406796e-04f, 1.89536836e-04f, 8.98491837e-05f, -9.79888746e-06f, -1.08531507e-04f, -2.05575498e-04f,
|
||||
-3.00092231e-04f, -3.91327952e-04f, -4.78537671e-04f, -5.61003964e-04f, -6.38090388e-04f, -7.09209697e-04f,
|
||||
-7.73747838e-04f, -8.31297964e-04f, -8.81364804e-04f, -9.23641236e-04f, -9.57793553e-04f, -9.83624619e-04f,
|
||||
-1.00098424e-03f, -1.00979404e-03f, -1.01003977e-03f, -1.00180772e-03f, -9.85219816e-04f, -9.60506778e-04f,
|
||||
-9.27905874e-04f, -8.87790902e-04f, -8.40553609e-04f, -7.86632276e-04f, -7.26559669e-04f, -6.60872173e-04f,
|
||||
-5.90177860e-04f, -5.15099219e-04f, -4.36341554e-04f, -3.54526447e-04f, -2.70436804e-04f, -1.84757234e-04f,
|
||||
-9.82406108e-05f, -1.16228429e-05f, 7.44116225e-05f, 1.59099493e-04f, 2.41739119e-04f, 3.21707034e-04f,
|
||||
3.98276352e-04f, 4.70887555e-04f, 5.38973046e-04f, 6.01940918e-04f, 6.59368174e-04f, 7.10783030e-04f,
|
||||
7.55802336e-04f, 7.94127086e-04f, 8.25478803e-04f, 8.49639386e-04f, 8.66487952e-04f, 8.75935969e-04f,
|
||||
8.77948893e-04f, 8.72611584e-04f, 8.59994515e-04f, 8.40271458e-04f, 8.13696181e-04f, 7.80491851e-04f,
|
||||
7.41053306e-04f, 6.95727202e-04f, 6.44936090e-04f, 5.89181503e-04f, 5.28946796e-04f, 4.64790448e-04f,
|
||||
3.97272420e-04f, 3.27000597e-04f, 2.54559578e-04f, 1.80597276e-04f, 1.05760446e-04f, 3.06209047e-05f,
|
||||
-4.41172003e-05f, -1.17884760e-04f, -1.90032814e-04f, -2.60000039e-04f, -3.27213235e-04f, -3.91110007e-04f,
|
||||
-4.51226928e-04f, -5.07042112e-04f, -5.58194586e-04f, -6.04189222e-04f, -6.44816381e-04f, -6.79653847e-04f,
|
||||
-7.08557315e-04f, -7.31282579e-04f, -7.47702169e-04f, -7.57731688e-04f, -7.61359812e-04f, -7.58589885e-04f,
|
||||
-7.49503361e-04f, -7.34226582e-04f, -7.12935677e-04f, -6.85882645e-04f, -6.53307567e-04f, -6.15569562e-04f,
|
||||
-5.72978650e-04f, -5.25977418e-04f, -4.74963705e-04f, -4.20426590e-04f, -3.62819514e-04f, -3.02647353e-04f,
|
||||
-2.40497241e-04f, -1.76810216e-04f, -1.12210871e-04f, -4.71976690e-05f, 1.76624641e-05f, 8.18440593e-05f,
|
||||
1.44804207e-04f, 2.06021410e-04f, 2.65025446e-04f, 3.21327783e-04f, 3.74487008e-04f, 4.24062432e-04f,
|
||||
4.69715655e-04f, 5.11042943e-04f, 5.47794530e-04f, 5.79655168e-04f, 6.06446384e-04f, 6.27934546e-04f,
|
||||
6.44010762e-04f, 6.54614698e-04f, 6.59636425e-04f, 6.59157826e-04f, 6.53158826e-04f, 6.41794049e-04f,
|
||||
6.25154916e-04f, 6.03470855e-04f, 5.76917242e-04f, 5.45789736e-04f, 5.10368292e-04f, 4.70998661e-04f,
|
||||
4.28021656e-04f, 3.81834126e-04f, 3.32863326e-04f, 2.81489629e-04f, 2.28231239e-04f, 1.73484261e-04f,
|
||||
1.17756607e-04f, 6.14881351e-05f, 5.17778269e-06f, -5.07352374e-05f, -1.05745987e-04f, -1.59454662e-04f,
|
||||
-2.11394268e-04f, -2.61151905e-04f, -3.08351703e-04f, -3.52598590e-04f, -3.93545002e-04f, -4.30916147e-04f,
|
||||
-4.64387406e-04f, -4.93756593e-04f, -5.18755281e-04f, -5.39265493e-04f, -5.55137934e-04f, -5.66259303e-04f,
|
||||
-5.72606783e-04f, -5.74140344e-04f, -5.70903292e-04f, -5.62934741e-04f, -5.50388898e-04f, -5.33351962e-04f,
|
||||
-5.12028510e-04f, -4.86612455e-04f, -4.57392981e-04f, -4.24578939e-04f, -3.88503808e-04f, -3.49487518e-04f,
|
||||
-3.07895836e-04f, -2.64036522e-04f, -2.18356445e-04f, -1.71198300e-04f, -1.22998901e-04f, -7.41392080e-05f,
|
||||
-2.50280393e-05f, 2.38852047e-05f, 7.22663332e-05f, 1.19659647e-04f, 1.65718806e-04f, 2.10055385e-04f,
|
||||
2.52324173e-04f, 2.92190427e-04f, 3.29337577e-04f, 3.63510150e-04f, 3.94385715e-04f, 4.21803288e-04f,
|
||||
4.45519433e-04f, 4.65391876e-04f, 4.81270460e-04f, 4.93057625e-04f, 5.00688030e-04f, 5.04121708e-04f,
|
||||
5.03379627e-04f, 4.98485604e-04f, 4.89499566e-04f, 4.76539317e-04f, 4.59760023e-04f, 4.39274612e-04f,
|
||||
4.15334876e-04f, 3.88103885e-04f, 3.57902146e-04f, 3.24908089e-04f, 2.89490480e-04f, 2.51922687e-04f,
|
||||
2.12512220e-04f, 1.71637404e-04f, 1.29609890e-04f, 8.67866183e-05f, 4.35312276e-05f, 1.98808307e-07f,
|
||||
-4.28589070e-05f, -8.52865394e-05f, -1.26765698e-04f, -1.66922292e-04f, -2.05456466e-04f, -2.42095652e-04f,
|
||||
-2.76487494e-04f, -3.08425602e-04f, -3.37638832e-04f, -3.63923042e-04f, -3.87022898e-04f, -4.06875144e-04f,
|
||||
-4.23245129e-04f, -4.36071615e-04f, -4.45236993e-04f, -4.50724682e-04f, -4.52491230e-04f, -4.50548104e-04f,
|
||||
-4.44936790e-04f, -4.35725612e-04f, -4.22987381e-04f, -4.06882738e-04f, -3.87548587e-04f, -3.65123104e-04f,
|
||||
-3.39860288e-04f, -3.11947486e-04f, -2.81618569e-04f, -2.49166817e-04f, -2.14824344e-04f, -1.78876370e-04f,
|
||||
-1.41684861e-04f, -1.03466427e-04f, -6.45996088e-05f, -2.53738050e-05f, 1.39035721e-05f, 5.28977578e-05f,
|
||||
9.13010773e-05f, 1.28809554e-04f, 1.65139924e-04f, 2.00005346e-04f, 2.33095696e-04f, 2.64232233e-04f,
|
||||
2.93070034e-04f, 3.19508024e-04f, 3.43252648e-04f, 3.64165224e-04f, 3.82074036e-04f, 3.96868082e-04f,
|
||||
4.08408250e-04f, 4.16671952e-04f, 4.21556517e-04f, 4.23035822e-04f, 4.21172111e-04f, 4.15928838e-04f,
|
||||
4.07377025e-04f, 3.95568598e-04f, 3.80628038e-04f, 3.62729177e-04f, 3.41921136e-04f, 3.18489958e-04f,
|
||||
2.92497406e-04f, 2.64266550e-04f, 2.33955571e-04f, 2.01809261e-04f, 1.68092145e-04f, 1.33141461e-04f,
|
||||
9.71043460e-05f, 6.03452880e-05f, 2.31264055e-05f, -1.43105089e-05f, -5.15607083e-05f, -8.84833364e-05f,
|
||||
-1.24679461e-04f, -1.59910519e-04f, -1.93952723e-04f, -2.26496145e-04f, -2.57307566e-04f, -2.86175538e-04f,
|
||||
-3.12853472e-04f, -3.37140613e-04f, -3.58914997e-04f, -3.77932329e-04f, -3.94117065e-04f, -4.07317063e-04f,
|
||||
-4.17422308e-04f, -4.24419479e-04f, -4.28161231e-04f, -4.28700484e-04f, -4.26016659e-04f, -4.20088126e-04f,
|
||||
-4.11009185e-04f, -3.98835037e-04f, -3.83585114e-04f, -3.65493072e-04f, -3.44616197e-04f, -3.21064387e-04f,
|
||||
-2.95119418e-04f, -2.66863117e-04f, -2.36549174e-04f, -2.04391686e-04f, -1.70585806e-04f, -1.35432614e-04f,
|
||||
-9.91006984e-05f, -6.19152828e-05f, -2.41012311e-05f, 1.40621144e-05f, 5.22867497e-05f, 9.03199843e-05f,
|
||||
1.27917614e-04f, 1.64740292e-04f, 2.00634478e-04f, 2.35261402e-04f, 2.68377430e-04f, 2.99818019e-04f,
|
||||
3.29273634e-04f, 3.56562766e-04f, 3.81532332e-04f, 4.03948113e-04f, 4.23655375e-04f, 4.40488930e-04f,
|
||||
4.54376777e-04f, 4.65137195e-04f, 4.72679704e-04f, 4.77014073e-04f, 4.77982201e-04f, 4.75625277e-04f,
|
||||
4.69878507e-04f, 4.60802987e-04f, 4.48367418e-04f, 4.32641679e-04f, 4.13709630e-04f, 3.91634147e-04f,
|
||||
3.66512902e-04f, 3.38481392e-04f, 3.07634938e-04f, 2.74189182e-04f, 2.38229594e-04f, 1.99985879e-04f,
|
||||
1.59632210e-04f, 1.17351364e-04f, 7.33404728e-05f, 2.78844831e-05f, -1.89099461e-05f, -6.67343638e-05f,
|
||||
-1.15367449e-04f, -1.64649983e-04f, -2.14224348e-04f, -2.64019844e-04f, -3.13654244e-04f, -3.62990333e-04f,
|
||||
-4.11800705e-04f, -4.59821928e-04f, -5.06946486e-04f, -5.52847863e-04f, -5.97397068e-04f, -6.40454770e-04f,
|
||||
-6.81765968e-04f, -7.21210131e-04f, -7.58634477e-04f, -7.93939572e-04f, -8.26964876e-04f, -8.57585335e-04f,
|
||||
-8.85733438e-04f, -9.11351007e-04f, -9.34300512e-04f, -9.54617442e-04f, -9.72159416e-04f, -9.87012089e-04f,
|
||||
-9.99095133e-04f, -1.00846242e-03f, -1.01506022e-03f, -1.01897105e-03f, -1.02021427e-03f, -1.01887259e-03f,
|
||||
-1.01497557e-03f, -1.00861358e-03f, -9.99877741e-04f, -9.88823136e-04f, -9.75617693e-04f, -9.60303769e-04f,
|
||||
-9.43035535e-04f, -9.23922797e-04f, -9.03105429e-04f, -8.80708716e-04f, -8.56853281e-04f, -8.31685264e-04f,
|
||||
-8.05348207e-04f, -7.77961627e-04f, -7.49713086e-04f, -7.20674604e-04f, -6.91032783e-04f, -6.60888020e-04f,
|
||||
-6.30372917e-04f, -5.99673349e-04f, -5.68830563e-04f, -5.38013304e-04f, -5.07353303e-04f, -4.76915043e-04f,
|
||||
-4.46832926e-04f, -4.17179291e-04f, -3.88083307e-04f, -3.59575024e-04f, -3.31820735e-04f, -3.04804303e-04f,
|
||||
-2.78616041e-04f, -2.53335964e-04f, -2.28986996e-04f, -2.05619529e-04f, -1.83318449e-04f, -1.61979425e-04f,
|
||||
-1.41791423e-04f, -1.22648816e-04f, -1.04625498e-04f, -8.77122910e-05f, -7.18653457e-05f, -5.71787106e-05f,
|
||||
-4.34807639e-05f, -3.09618857e-05f, -1.94074401e-05f, -8.88017971e-06f, 6.09625220e-07f, 9.14020334e-06f,
|
||||
1.67805558e-05f, 2.35369965e-05f, 2.94278194e-05f, 3.45049751e-05f, 3.88373828e-05f, 4.24291966e-05f,
|
||||
4.53445665e-05f, 4.76965834e-05f, 4.93395567e-05f, 5.05392111e-05f, 5.12257065e-05f, 5.14579340e-05f,
|
||||
5.12651750e-05f, 5.07312551e-05f, 4.98486765e-05f, 4.87082573e-05f, 4.73439631e-05f, 4.56740817e-05f,
|
||||
4.38653618e-05f, 4.19399075e-05f, 3.99125668e-05f, 3.77616021e-05f, 3.56135997e-05f, 3.33554815e-05f,
|
||||
3.11656899e-05f, 2.89038150e-05f, 2.67281634e-05f, 2.46192762e-05f, 2.24899205e-05f, 2.04698700e-05f,
|
||||
1.84927655e-05f, 1.66762886e-05f, 1.49393771e-05f, 1.32258081e-05f, 1.16985586e-05f, 1.01874391e-05f,
|
||||
8.99882100e-06f, 7.61267073e-06f, 6.57702907e-06f, 5.59829210e-06f, 4.27698546e-06f, 1.03248674e-05f,
|
||||
};
|
||||
|
||||
//
|
||||
// polyphase filter
|
||||
//
|
||||
static const int SRC_PHASEBITS = 8;
|
||||
static const int SRC_PHASES = (1 << SRC_PHASEBITS);
|
||||
static const int SRC_FRACBITS = 32 - SRC_PHASEBITS;
|
||||
static const uint32_t SRC_FRACMASK = (1 << SRC_FRACBITS) - 1;
|
||||
|
||||
static const float QFRAC_TO_FLOAT = 1.0f / (1 << SRC_FRACBITS);
|
||||
static const float Q32_TO_FLOAT = 1.0f / (1ULL << 32);
|
||||
|
||||
// blocking size in frames, chosen so block processing fits in L1 cache
|
||||
static const int SRC_BLOCK = 1024;
|
||||
|
||||
#define lo32(a) ((uint32_t)(a))
|
||||
#define hi32(a) ((int32_t)((a) >> 32))
|
||||
// high/low part of int64_t
|
||||
#define LO32(a) ((uint32_t)(a))
|
||||
#define HI32(a) ((int32_t)((a) >> 32))
|
||||
|
||||
//
|
||||
// Portable aligned malloc/free
|
||||
|
@ -610,8 +69,8 @@ static void cubicInterpolation(const float* input, float* output, int inputSize,
|
|||
// Lagrange interpolation using Farrow structure
|
||||
for (int j = 0; j < outputSize; j++) {
|
||||
|
||||
int32_t i = hi32(offset);
|
||||
uint32_t f = lo32(offset);
|
||||
int32_t i = HI32(offset);
|
||||
uint32_t f = LO32(offset);
|
||||
|
||||
// values outside the window are zero
|
||||
float x0 = (i - 1 < 0) ? 0.0f : input[i - 1];
|
||||
|
@ -649,7 +108,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) {
|
|||
numTaps = (numCoefs + upFactor - 1) / upFactor;
|
||||
gain *= (float)oldCoefs / numCoefs;
|
||||
}
|
||||
numTaps = (numTaps + 3) & ~3; // SIMD4
|
||||
numTaps = (numTaps + 7) & ~7; // SIMD8
|
||||
|
||||
// interpolate the coefficients of the prototype filter
|
||||
float* tempFilter = new float[numTaps * numPhases];
|
||||
|
@ -658,7 +117,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) {
|
|||
cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain);
|
||||
|
||||
// create the polyphase filter
|
||||
_polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 16); // SIMD4
|
||||
_polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 32); // SIMD8
|
||||
|
||||
// rearrange into polyphase form, ordered by use
|
||||
for (int i = 0; i < numPhases; i++) {
|
||||
|
@ -699,7 +158,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) {
|
|||
numTaps = (numCoefs + upFactor - 1) / upFactor;
|
||||
gain *= (float)oldCoefs / numCoefs;
|
||||
}
|
||||
numTaps = (numTaps + 3) & ~3; // SIMD4
|
||||
numTaps = (numTaps + 7) & ~7; // SIMD8
|
||||
|
||||
// interpolate the coefficients of the prototype filter
|
||||
float* tempFilter = new float[numTaps * numPhases];
|
||||
|
@ -708,7 +167,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) {
|
|||
cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain);
|
||||
|
||||
// create the polyphase filter, with extra phase at the end to simplify coef interpolation
|
||||
_polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 16); // SIMD4
|
||||
_polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 32); // SIMD8
|
||||
|
||||
// rearrange into polyphase form, ordered by fractional delay
|
||||
for (int phase = 0; phase < numPhases; phase++) {
|
||||
|
@ -741,14 +200,14 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) {
|
|||
|
||||
#include <emmintrin.h>
|
||||
|
||||
int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) {
|
||||
int AudioSRC::multirateFilter1_SSE(const float* input0, float* output0, int inputFrames) {
|
||||
int outputFrames = 0;
|
||||
|
||||
assert((_numTaps & 0x3) == 0); // SIMD4
|
||||
assert(_numTaps % 4 == 0); // SIMD4
|
||||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
|
@ -761,7 +220,7 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
//float coef = c0[j];
|
||||
__m128 coef0 = _mm_loadu_ps(&c0[j]);
|
||||
|
||||
//acc0 += input0[i + j] * coef;
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0);
|
||||
}
|
||||
|
||||
|
@ -781,10 +240,10 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
|
||||
} else { // irrational
|
||||
|
||||
while (hi32(_offset) < inputFrames) {
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
uint32_t f = lo32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
__m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT);
|
||||
|
@ -802,7 +261,7 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
coef1 = _mm_sub_ps(coef1, coef0);
|
||||
coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0);
|
||||
|
||||
//acc0 += input0[i + j] * coef;
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0);
|
||||
}
|
||||
|
||||
|
@ -821,14 +280,14 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
return outputFrames;
|
||||
}
|
||||
|
||||
int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) {
|
||||
int AudioSRC::multirateFilter2_SSE(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) {
|
||||
int outputFrames = 0;
|
||||
|
||||
assert((_numTaps & 0x3) == 0); // SIMD4
|
||||
assert(_numTaps % 4 == 0); // SIMD4
|
||||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
|
@ -842,7 +301,7 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
//float coef = c0[j];
|
||||
__m128 coef0 = _mm_loadu_ps(&c0[j]);
|
||||
|
||||
//acc0 += input0[i + j] * coef;
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0);
|
||||
acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1);
|
||||
}
|
||||
|
@ -866,10 +325,10 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
|
||||
} else { // irrational
|
||||
|
||||
while (hi32(_offset) < inputFrames) {
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
uint32_t f = lo32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
__m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT);
|
||||
|
@ -888,7 +347,7 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
coef1 = _mm_sub_ps(coef1, coef0);
|
||||
coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0);
|
||||
|
||||
//acc0 += input0[i + j] * coef;
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0);
|
||||
acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1);
|
||||
}
|
||||
|
@ -911,6 +370,24 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
return outputFrames;
|
||||
}
|
||||
|
||||
//
|
||||
// Runtime CPU dispatch
|
||||
//
|
||||
|
||||
#include "CPUDetect.h"
|
||||
|
||||
int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) {
|
||||
|
||||
static auto f = cpuSupportsAVX2() ? &AudioSRC::multirateFilter1_AVX2 : &AudioSRC::multirateFilter1_SSE;
|
||||
return (this->*f)(input0, output0, inputFrames); // dispatch
|
||||
}
|
||||
|
||||
int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) {
|
||||
|
||||
static auto f = cpuSupportsAVX2() ? &AudioSRC::multirateFilter2_AVX2 : &AudioSRC::multirateFilter2_SSE;
|
||||
return (this->*f)(input0, input1, output0, output1, inputFrames); // dispatch
|
||||
}
|
||||
|
||||
// convert int16_t to float, deinterleave stereo
|
||||
void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) {
|
||||
__m128 scale = _mm_set1_ps(1/32768.0f);
|
||||
|
@ -1069,7 +546,7 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
|
@ -1096,10 +573,10 @@ int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFra
|
|||
|
||||
} else { // irrational
|
||||
|
||||
while (hi32(_offset) < inputFrames) {
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
uint32_t f = lo32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT;
|
||||
|
@ -1132,7 +609,7 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
|
@ -1162,10 +639,10 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float*
|
|||
|
||||
} else { // irrational
|
||||
|
||||
while (hi32(_offset) < inputFrames) {
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = hi32(_offset);
|
||||
uint32_t f = lo32(_offset);
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT;
|
||||
|
@ -1320,7 +797,7 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) {
|
|||
assert(inputSampleRate > 0);
|
||||
assert(outputSampleRate > 0);
|
||||
assert(numChannels > 0);
|
||||
assert(numChannels <= MAX_CHANNELS);
|
||||
assert(numChannels <= SRC_MAX_CHANNELS);
|
||||
|
||||
_inputSampleRate = inputSampleRate;
|
||||
_outputSampleRate = outputSampleRate;
|
||||
|
@ -1349,7 +826,7 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) {
|
|||
_numTaps = createIrrationalFilter(_upFactor, _downFactor, 1.0f);
|
||||
}
|
||||
|
||||
//printf("up=%d down=%.3f taps=%d\n", _upFactor, _downFactor + (lo32(_step)<<SRC_PHASEBITS) * Q32_TO_FLOAT, _numTaps);
|
||||
//printf("up=%d down=%.3f taps=%d\n", _upFactor, _downFactor + (LO32(_step)<<SRC_PHASEBITS) * Q32_TO_FLOAT, _numTaps);
|
||||
|
||||
// filter history buffers
|
||||
_numHistory = _numTaps - 1;
|
||||
|
@ -1357,10 +834,10 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) {
|
|||
_history[1] = new float[2 * _numHistory];
|
||||
|
||||
// format conversion buffers
|
||||
_inputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); // SIMD4
|
||||
_inputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16);
|
||||
_outputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16);
|
||||
_outputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16);
|
||||
_inputs[0] = (float*)aligned_malloc(4*SRC_BLOCK * sizeof(float), 16); // SIMD4
|
||||
_inputs[1] = _inputs[0] + 1*SRC_BLOCK;
|
||||
_outputs[0] = _inputs[0] + 2*SRC_BLOCK;
|
||||
_outputs[1] = _inputs[0] + 3*SRC_BLOCK;
|
||||
|
||||
// input blocking size, such that input and output are both guaranteed not to exceed SRC_BLOCK frames
|
||||
_inputBlock = std::min(SRC_BLOCK, getMaxInput(SRC_BLOCK));
|
||||
|
@ -1380,9 +857,6 @@ AudioSRC::~AudioSRC() {
|
|||
delete[] _history[1];
|
||||
|
||||
aligned_free(_inputs[0]);
|
||||
aligned_free(_inputs[1]);
|
||||
aligned_free(_outputs[0]);
|
||||
aligned_free(_outputs[1]);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -14,11 +14,23 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
static const int SRC_MAX_CHANNELS = 2;
|
||||
|
||||
// polyphase filter
|
||||
static const int SRC_PHASEBITS = 8;
|
||||
static const int SRC_PHASES = (1 << SRC_PHASEBITS);
|
||||
static const int SRC_FRACBITS = 32 - SRC_PHASEBITS;
|
||||
static const uint32_t SRC_FRACMASK = (1 << SRC_FRACBITS) - 1;
|
||||
|
||||
static const float QFRAC_TO_FLOAT = 1.0f / (1 << SRC_FRACBITS);
|
||||
static const float Q32_TO_FLOAT = 1.0f / (1ULL << 32);
|
||||
|
||||
// blocking size in frames, chosen so block processing fits in L1 cache
|
||||
static const int SRC_BLOCK = 256;
|
||||
|
||||
class AudioSRC {
|
||||
|
||||
public:
|
||||
static const int MAX_CHANNELS = 2;
|
||||
|
||||
AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels);
|
||||
~AudioSRC();
|
||||
|
||||
|
@ -33,9 +45,9 @@ private:
|
|||
float* _polyphaseFilter;
|
||||
int* _stepTable;
|
||||
|
||||
float* _history[MAX_CHANNELS];
|
||||
float* _inputs[MAX_CHANNELS];
|
||||
float* _outputs[MAX_CHANNELS];
|
||||
float* _history[SRC_MAX_CHANNELS];
|
||||
float* _inputs[SRC_MAX_CHANNELS];
|
||||
float* _outputs[SRC_MAX_CHANNELS];
|
||||
|
||||
int _inputSampleRate;
|
||||
int _outputSampleRate;
|
||||
|
@ -57,6 +69,12 @@ private:
|
|||
int multirateFilter1(const float* input0, float* output0, int inputFrames);
|
||||
int multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||
|
||||
int multirateFilter1_SSE(const float* input0, float* output0, int inputFrames);
|
||||
int multirateFilter2_SSE(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||
|
||||
int multirateFilter1_AVX2(const float* input0, float* output0, int inputFrames);
|
||||
int multirateFilter2_AVX2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||
|
||||
void convertInputFromInt16(const int16_t* input, float** outputs, int numFrames);
|
||||
void convertOutputToInt16(float** inputs, int16_t* output, int numFrames);
|
||||
|
||||
|
|
548
libraries/audio/src/AudioSRCData.h
Normal file
548
libraries/audio/src/AudioSRCData.h
Normal file
|
@ -0,0 +1,548 @@
|
|||
//
|
||||
// AudioSRCData.h
|
||||
// libraries/audio/src
|
||||
//
|
||||
// Created by Ken Cooke on 6/6/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
//
|
||||
// Prototype filter coefficients for audio sampling rate conversion.
|
||||
//
|
||||
// See "Design of Optimal Minimum Phase Digital FIR Filters Using Discrete Hilbert Transforms"
|
||||
// IEEE TRANSACTIONS ON SIGNAL PROCESSING, May 2000
|
||||
//
|
||||
// Minimum-phase equiripple FIR lowpass
|
||||
// taps = 96, phases = 32
|
||||
//
|
||||
// passband = 0.918 (20.2khz @ 44.1khz sampling rate)
|
||||
// stopband = 1.010 (22.2khz @ 44.1khz sampling rate)
|
||||
// passband ripple = +-0.01dB
|
||||
// stopband attn = -125dB (-70dB at 1.000)
|
||||
//
|
||||
// Resampling algorithm:
|
||||
// One of two methods is used, depending on whether the conversion is reducible to a ratio of small integers L/M.
|
||||
// For rational ratio, the prototype is upsampled to L/M polyphase filter using 3rd-order Lagrange interpolation.
|
||||
// For irrational ratio, the prototype is upsampled to 256/M polyphase filter, followed by linear interpolation.
|
||||
// For both cases, oversampling at each stage ensures the original passband and stopband specifications are met.
|
||||
//
|
||||
static const int PROTOTYPE_TAPS = 96; // filter taps per phase
|
||||
static const int PROTOTYPE_PHASES = 32; // oversampling factor
|
||||
|
||||
static const float prototypeFilter[PROTOTYPE_TAPS * PROTOTYPE_PHASES] = {
|
||||
0.00000000e+00f, 1.55021703e-05f, 1.46054865e-05f, 2.07057160e-05f, 2.91335519e-05f, 4.00091078e-05f,
|
||||
5.33544450e-05f, 7.03618468e-05f, 9.10821639e-05f, 1.16484613e-04f, 1.47165999e-04f, 1.84168304e-04f,
|
||||
2.28429617e-04f, 2.80913884e-04f, 3.42940399e-04f, 4.15773039e-04f, 5.01023255e-04f, 6.00234953e-04f,
|
||||
7.15133271e-04f, 8.47838855e-04f, 1.00032516e-03f, 1.17508881e-03f, 1.37452550e-03f, 1.60147614e-03f,
|
||||
1.85886458e-03f, 2.14985024e-03f, 2.47783071e-03f, 2.84666764e-03f, 3.26016878e-03f, 3.72252797e-03f,
|
||||
4.23825900e-03f, 4.81207874e-03f, 5.44904143e-03f, 6.15447208e-03f, 6.93399929e-03f, 7.79337059e-03f,
|
||||
8.73903392e-03f, 9.77729117e-03f, 1.09149561e-02f, 1.21591316e-02f, 1.35171164e-02f, 1.49965439e-02f,
|
||||
1.66053136e-02f, 1.83515384e-02f, 2.02435362e-02f, 2.22899141e-02f, 2.44995340e-02f, 2.68813362e-02f,
|
||||
2.94443254e-02f, 3.21979928e-02f, 3.51514690e-02f, 3.83143719e-02f, 4.16960560e-02f, 4.53060504e-02f,
|
||||
4.91538115e-02f, 5.32486197e-02f, 5.75998650e-02f, 6.22164253e-02f, 6.71072811e-02f, 7.22809789e-02f,
|
||||
7.77457552e-02f, 8.35095233e-02f, 8.95796944e-02f, 9.59631768e-02f, 1.02666457e-01f, 1.09695215e-01f,
|
||||
1.17054591e-01f, 1.24748885e-01f, 1.32781656e-01f, 1.41155521e-01f, 1.49872243e-01f, 1.58932534e-01f,
|
||||
1.68335961e-01f, 1.78081143e-01f, 1.88165339e-01f, 1.98584621e-01f, 2.09333789e-01f, 2.20406193e-01f,
|
||||
2.31793899e-01f, 2.43487398e-01f, 2.55475740e-01f, 2.67746404e-01f, 2.80285305e-01f, 2.93076743e-01f,
|
||||
3.06103423e-01f, 3.19346351e-01f, 3.32784916e-01f, 3.46396772e-01f, 3.60158039e-01f, 3.74043042e-01f,
|
||||
3.88024564e-01f, 4.02073759e-01f, 4.16160177e-01f, 4.30251886e-01f, 4.44315429e-01f, 4.58315954e-01f,
|
||||
4.72217175e-01f, 4.85981675e-01f, 4.99570709e-01f, 5.12944586e-01f, 5.26062401e-01f, 5.38882630e-01f,
|
||||
5.51362766e-01f, 5.63459860e-01f, 5.75130384e-01f, 5.86330458e-01f, 5.97016050e-01f, 6.07143161e-01f,
|
||||
6.16667840e-01f, 6.25546499e-01f, 6.33735979e-01f, 6.41193959e-01f, 6.47878856e-01f, 6.53750084e-01f,
|
||||
6.58768549e-01f, 6.62896349e-01f, 6.66097381e-01f, 6.68337353e-01f, 6.69583869e-01f, 6.69807061e-01f,
|
||||
6.68979117e-01f, 6.67075139e-01f, 6.64072812e-01f, 6.59952827e-01f, 6.54699116e-01f, 6.48298688e-01f,
|
||||
6.40742160e-01f, 6.32023668e-01f, 6.22141039e-01f, 6.11095903e-01f, 5.98893921e-01f, 5.85544600e-01f,
|
||||
5.71061707e-01f, 5.55463040e-01f, 5.38770639e-01f, 5.21010762e-01f, 5.02213839e-01f, 4.82414572e-01f,
|
||||
4.61651859e-01f, 4.39968628e-01f, 4.17412000e-01f, 3.94032951e-01f, 3.69886464e-01f, 3.45031084e-01f,
|
||||
3.19529091e-01f, 2.93446187e-01f, 2.66851164e-01f, 2.39815999e-01f, 2.12415399e-01f, 1.84726660e-01f,
|
||||
1.56829293e-01f, 1.28804933e-01f, 1.00736965e-01f, 7.27100355e-02f, 4.48100810e-02f, 1.71237415e-02f,
|
||||
-1.02620228e-02f, -3.72599591e-02f, -6.37832871e-02f, -8.97457733e-02f, -1.15062201e-01f, -1.39648782e-01f,
|
||||
-1.63423488e-01f, -1.86306368e-01f, -2.08220103e-01f, -2.29090072e-01f, -2.48845046e-01f, -2.67417270e-01f,
|
||||
-2.84742946e-01f, -3.00762597e-01f, -3.15421127e-01f, -3.28668542e-01f, -3.40459849e-01f, -3.50755400e-01f,
|
||||
-3.59521402e-01f, -3.66729768e-01f, -3.72358475e-01f, -3.76391839e-01f, -3.78820421e-01f, -3.79641287e-01f,
|
||||
-3.78858203e-01f, -3.76481336e-01f, -3.72527677e-01f, -3.67020780e-01f, -3.59990760e-01f, -3.51474372e-01f,
|
||||
-3.41514630e-01f, -3.30160971e-01f, -3.17468898e-01f, -3.03499788e-01f, -2.88320749e-01f, -2.72004315e-01f,
|
||||
-2.54628056e-01f, -2.36274454e-01f, -2.17030464e-01f, -1.96986952e-01f, -1.76238733e-01f, -1.54883647e-01f,
|
||||
-1.33022496e-01f, -1.10758449e-01f, -8.81964466e-02f, -6.54430504e-02f, -4.26055475e-02f, -1.97916415e-02f,
|
||||
2.89108184e-03f, 2.53355868e-02f, 4.74362201e-02f, 6.90887518e-02f, 9.01914308e-02f, 1.10644978e-01f,
|
||||
1.30353494e-01f, 1.49224772e-01f, 1.67170735e-01f, 1.84107975e-01f, 1.99958067e-01f, 2.14648181e-01f,
|
||||
2.28111323e-01f, 2.40286622e-01f, 2.51119890e-01f, 2.60563701e-01f, 2.68577740e-01f, 2.75129027e-01f,
|
||||
2.80192144e-01f, 2.83749177e-01f, 2.85790223e-01f, 2.86312986e-01f, 2.85323221e-01f, 2.82834421e-01f,
|
||||
2.78867915e-01f, 2.73452721e-01f, 2.66625431e-01f, 2.58429983e-01f, 2.48917457e-01f, 2.38145826e-01f,
|
||||
2.26179680e-01f, 2.13089734e-01f, 1.98952740e-01f, 1.83850758e-01f, 1.67870897e-01f, 1.51104879e-01f,
|
||||
1.33648388e-01f, 1.15600665e-01f, 9.70639763e-02f, 7.81429119e-02f, 5.89439889e-02f, 3.95749746e-02f,
|
||||
2.01442353e-02f, 7.60241152e-04f, -1.84690990e-02f, -3.74370397e-02f, -5.60385970e-02f, -7.41711039e-02f,
|
||||
-9.17348686e-02f, -1.08633632e-01f, -1.24775254e-01f, -1.40071993e-01f, -1.54441372e-01f, -1.67806284e-01f,
|
||||
-1.80095654e-01f, -1.91244732e-01f, -2.01195605e-01f, -2.09897310e-01f, -2.17306320e-01f, -2.23386736e-01f,
|
||||
-2.28110407e-01f, -2.31457193e-01f, -2.33415044e-01f, -2.33980051e-01f, -2.33156463e-01f, -2.30956673e-01f,
|
||||
-2.27401097e-01f, -2.22518148e-01f, -2.16343899e-01f, -2.08921985e-01f, -2.00303365e-01f, -1.90545790e-01f,
|
||||
-1.79713804e-01f, -1.67877977e-01f, -1.55114789e-01f, -1.41505907e-01f, -1.27137921e-01f, -1.12101628e-01f,
|
||||
-9.64915640e-02f, -8.04054232e-02f, -6.39434707e-02f, -4.72078814e-02f, -3.03021635e-02f, -1.33305082e-02f,
|
||||
3.60284977e-03f, 2.03942507e-02f, 3.69413014e-02f, 5.31433810e-02f, 6.89024656e-02f, 8.41234679e-02f,
|
||||
9.87150268e-02f, 1.12589969e-01f, 1.25665865e-01f, 1.37865538e-01f, 1.49117506e-01f, 1.59356490e-01f,
|
||||
1.68523664e-01f, 1.76567229e-01f, 1.83442499e-01f, 1.89112308e-01f, 1.93547212e-01f, 1.96725586e-01f,
|
||||
1.98633878e-01f, 1.99266486e-01f, 1.98625999e-01f, 1.96723008e-01f, 1.93576075e-01f, 1.89211557e-01f,
|
||||
1.83663562e-01f, 1.76973516e-01f, 1.69190033e-01f, 1.60368490e-01f, 1.50570805e-01f, 1.39864815e-01f,
|
||||
1.28324021e-01f, 1.16026978e-01f, 1.03056879e-01f, 8.95008829e-02f, 7.54496798e-02f, 6.09968238e-02f,
|
||||
4.62380664e-02f, 3.12708901e-02f, 1.61936956e-02f, 1.10531988e-03f, -1.38957653e-02f, -2.87119784e-02f,
|
||||
-4.32472742e-02f, -5.74078385e-02f, -7.11026311e-02f, -8.42439713e-02f, -9.67481917e-02f, -1.08536049e-01f,
|
||||
-1.19533350e-01f, -1.29671345e-01f, -1.38887238e-01f, -1.47124498e-01f, -1.54333373e-01f, -1.60470968e-01f,
|
||||
-1.65501755e-01f, -1.69397631e-01f, -1.72138140e-01f, -1.73710602e-01f, -1.74110159e-01f, -1.73339798e-01f,
|
||||
-1.71410274e-01f, -1.68340111e-01f, -1.64155335e-01f, -1.58889414e-01f, -1.52582850e-01f, -1.45283122e-01f,
|
||||
-1.37044042e-01f, -1.27925722e-01f, -1.17993860e-01f, -1.07319421e-01f, -9.59781808e-02f, -8.40500777e-02f,
|
||||
-7.16188049e-02f, -5.87710561e-02f, -4.55961475e-02f, -3.21851919e-02f, -1.86306406e-02f, -5.02554942e-03f,
|
||||
8.53698384e-03f, 2.19645467e-02f, 3.51659468e-02f, 4.80518693e-02f, 6.05355056e-02f, 7.25330700e-02f,
|
||||
8.39645094e-02f, 9.47537898e-02f, 1.04829753e-01f, 1.14126254e-01f, 1.22582788e-01f, 1.30144907e-01f,
|
||||
1.36764459e-01f, 1.42400029e-01f, 1.47017076e-01f, 1.50588312e-01f, 1.53093700e-01f, 1.54520736e-01f,
|
||||
1.54864367e-01f, 1.54127119e-01f, 1.52318991e-01f, 1.49457408e-01f, 1.45567062e-01f, 1.40679709e-01f,
|
||||
1.34833933e-01f, 1.28074855e-01f, 1.20453893e-01f, 1.12028129e-01f, 1.02860307e-01f, 9.30178765e-02f,
|
||||
8.25730032e-02f, 7.16016450e-02f, 6.01833134e-02f, 4.84002546e-02f, 3.63370724e-02f, 2.40800037e-02f,
|
||||
1.17163168e-02f, -6.66217400e-04f, -1.29801121e-02f, -2.51385315e-02f, -3.70562030e-02f, -4.86497748e-02f,
|
||||
-5.98384928e-02f, -7.05447859e-02f, -8.06947592e-02f, -9.02187441e-02f, -9.90517313e-02f, -1.07133911e-01f,
|
||||
-1.14410951e-01f, -1.20834483e-01f, -1.26362422e-01f, -1.30959116e-01f, -1.34595787e-01f, -1.37250547e-01f,
|
||||
-1.38908600e-01f, -1.39562374e-01f, -1.39211442e-01f, -1.37862602e-01f, -1.35529795e-01f, -1.32233909e-01f,
|
||||
-1.28002721e-01f, -1.22870611e-01f, -1.16878278e-01f, -1.10072477e-01f, -1.02505698e-01f, -9.42356124e-02f,
|
||||
-8.53248753e-02f, -7.58404912e-02f, -6.58532924e-02f, -5.54376360e-02f, -4.46705953e-02f, -3.36315414e-02f,
|
||||
-2.24015972e-02f, -1.10628991e-02f, 3.01894735e-04f, 1.16101918e-02f, 2.27801642e-02f, 3.37311642e-02f,
|
||||
4.43845430e-02f, 5.46640016e-02f, 6.44962637e-02f, 7.38115400e-02f, 8.25440784e-02f, 9.06325572e-02f,
|
||||
9.80206066e-02f, 1.04657146e-01f, 1.10496723e-01f, 1.15499920e-01f, 1.19633523e-01f, 1.22870824e-01f,
|
||||
1.25191729e-01f, 1.26582959e-01f, 1.27038061e-01f, 1.26557494e-01f, 1.25148528e-01f, 1.22825305e-01f,
|
||||
1.19608512e-01f, 1.15525479e-01f, 1.10609643e-01f, 1.04900592e-01f, 9.84435537e-02f, 9.12890948e-02f,
|
||||
8.34927732e-02f, 7.51146973e-02f, 6.62190194e-02f, 5.68735547e-02f, 4.71491262e-02f, 3.71191855e-02f,
|
||||
2.68591932e-02f, 1.64459573e-02f, 5.95731808e-03f, -4.52874940e-03f, -1.49344723e-02f, -2.51829130e-02f,
|
||||
-3.51986373e-02f, -4.49081427e-02f, -5.42404654e-02f, -6.31276969e-02f, -7.15054163e-02f, -7.93132713e-02f,
|
||||
-8.64953327e-02f, -9.30005042e-02f, -9.87829011e-02f, -1.03802223e-01f, -1.08023943e-01f, -1.11419636e-01f,
|
||||
-1.13967111e-01f, -1.15650603e-01f, -1.16460855e-01f, -1.16395152e-01f, -1.15457368e-01f, -1.13657871e-01f,
|
||||
-1.11013433e-01f, -1.07547117e-01f, -1.03288073e-01f, -9.82712708e-02f, -9.25372646e-02f, -8.61318657e-02f,
|
||||
-7.91057486e-02f, -7.15141053e-02f, -6.34161588e-02f, -5.48747791e-02f, -4.59559696e-02f, -3.67282941e-02f,
|
||||
-2.72624874e-02f, -1.76307914e-02f, -7.90648674e-03f, 1.83670340e-03f, 1.15251424e-02f, 2.10858716e-02f,
|
||||
3.04471304e-02f, 3.95388944e-02f, 4.82933904e-02f, 5.66456655e-02f, 6.45340054e-02f, 7.19003487e-02f,
|
||||
7.86908695e-02f, 8.48562395e-02f, 9.03519908e-02f, 9.51389501e-02f, 9.91834077e-02f, 1.02457361e-01f,
|
||||
1.04938834e-01f, 1.06611872e-01f, 1.07466724e-01f, 1.07499917e-01f, 1.06714213e-01f, 1.05118588e-01f,
|
||||
1.02728167e-01f, 9.95640680e-02f, 9.56532488e-02f, 9.10282406e-02f, 8.57269309e-02f, 7.97922261e-02f,
|
||||
7.32717395e-02f, 6.62174249e-02f, 5.86850536e-02f, 5.07339959e-02f, 4.24265058e-02f, 3.38274345e-02f,
|
||||
2.50036502e-02f, 1.60234844e-02f, 6.95628026e-03f, -2.12820655e-03f, -1.11602438e-02f, -2.00708281e-02f,
|
||||
-2.87920337e-02f, -3.72576320e-02f, -4.54035426e-02f, -5.31684173e-02f, -6.04938939e-02f, -6.73253212e-02f,
|
||||
-7.36119310e-02f, -7.93072981e-02f, -8.43697556e-02f, -8.87625537e-02f, -9.24542939e-02f, -9.54189981e-02f,
|
||||
-9.76364402e-02f, -9.90921435e-02f, -9.97776003e-02f, -9.96902366e-02f, -9.88334463e-02f, -9.72165780e-02f,
|
||||
-9.48547668e-02f, -9.17688999e-02f, -8.79853312e-02f, -8.35357688e-02f, -7.84569594e-02f, -7.27903677e-02f,
|
||||
-6.65818940e-02f, -5.98814932e-02f, -5.27427333e-02f, -4.52224733e-02f, -3.73802459e-02f, -2.92780037e-02f,
|
||||
-2.09794209e-02f, -1.25495498e-02f, -4.05425988e-03f, 4.44034349e-03f, 1.28682571e-02f, 2.11643361e-02f,
|
||||
2.92645357e-02f, 3.71066200e-02f, 4.46305203e-02f, 5.17788267e-02f, 5.84972389e-02f, 6.47349496e-02f,
|
||||
7.04450836e-02f, 7.55849928e-02f, 8.01165748e-02f, 8.40066506e-02f, 8.72270848e-02f, 8.97550618e-02f,
|
||||
9.15732179e-02f, 9.26698315e-02f, 9.30387881e-02f, 9.26796720e-02f, 9.15978025e-02f, 8.98040443e-02f,
|
||||
8.73148489e-02f, 8.41520461e-02f, 8.03426093e-02f, 7.59185468e-02f, 7.09165136e-02f, 6.53776255e-02f,
|
||||
5.93470480e-02f, 5.28736293e-02f, 4.60095655e-02f, 3.88099545e-02f, 3.13323302e-02f, 2.36362162e-02f,
|
||||
1.57827398e-02f, 7.83395091e-03f, -1.47413782e-04f, -8.09864153e-03f, -1.59574406e-02f, -2.36623595e-02f,
|
||||
-3.11534717e-02f, -3.83725840e-02f, -4.52638947e-02f, -5.17743411e-02f, -5.78539729e-02f, -6.34564348e-02f,
|
||||
-6.85392092e-02f, -7.30640654e-02f, -7.69971954e-02f, -8.03096220e-02f, -8.29772975e-02f, -8.49813524e-02f,
|
||||
-8.63081836e-02f, -8.69495746e-02f, -8.69027157e-02f, -8.61702687e-02f, -8.47602668e-02f, -8.26860569e-02f,
|
||||
-7.99661981e-02f, -7.66242997e-02f, -7.26887788e-02f, -6.81926752e-02f, -6.31733712e-02f, -5.76722279e-02f,
|
||||
-5.17343061e-02f, -4.54080069e-02f, -3.87446321e-02f, -3.17980032e-02f, -2.46239897e-02f, -1.72801497e-02f,
|
||||
-9.82518156e-03f, -2.31845300e-03f, 5.18037510e-03f, 1.26119044e-02f, 1.99174857e-02f, 2.70395921e-02f,
|
||||
3.39223499e-02f, 4.05119404e-02f, 4.67570465e-02f, 5.26092142e-02f, 5.80232695e-02f, 6.29576539e-02f,
|
||||
6.73747113e-02f, 7.12410320e-02f, 7.45276905e-02f, 7.72104218e-02f, 7.92698394e-02f, 8.06915952e-02f,
|
||||
8.14664004e-02f, 8.15901977e-02f, 8.10640907e-02f, 7.98943315e-02f, 7.80922975e-02f, 7.56743792e-02f,
|
||||
7.26617861e-02f, 6.90804346e-02f, 6.49606433e-02f, 6.03370049e-02f, 5.52479503e-02f, 4.97355660e-02f,
|
||||
4.38451300e-02f, 3.76248662e-02f, 3.11254263e-02f, 2.43995757e-02f, 1.75017105e-02f, 1.04874823e-02f,
|
||||
3.41321948e-03f, -3.66433362e-03f, -1.06886566e-02f, -1.76037566e-02f, -2.43547422e-02f, -3.08881238e-02f,
|
||||
-3.71523818e-02f, -4.30982377e-02f, -4.86791529e-02f, -5.38515978e-02f, -5.85754991e-02f, -6.28144137e-02f,
|
||||
-6.65359631e-02f, -6.97119559e-02f, -7.23186409e-02f, -7.43369897e-02f, -7.57526047e-02f, -7.65560812e-02f,
|
||||
-7.67428560e-02f, -7.63134051e-02f, -7.52730583e-02f, -7.36321241e-02f, -7.14055927e-02f, -6.86132027e-02f,
|
||||
-6.52791213e-02f, -6.14318004e-02f, -5.71037475e-02f, -5.23312158e-02f, -4.71539306e-02f, -4.16147519e-02f,
|
||||
-3.57593331e-02f, -2.96357023e-02f, -2.32939478e-02f, -1.67857228e-02f, -1.01639251e-02f, -3.48213128e-03f,
|
||||
3.20566951e-03f, 9.84566549e-03f, 1.63845318e-02f, 2.27699627e-02f, 2.89509937e-02f, 3.48784838e-02f,
|
||||
4.05054571e-02f, 4.57875191e-02f, 5.06831561e-02f, 5.51541055e-02f, 5.91656321e-02f, 6.26867948e-02f,
|
||||
6.56907214e-02f, 6.81547545e-02f, 7.00607045e-02f, 7.13948753e-02f, 7.21482790e-02f, 7.23165894e-02f,
|
||||
7.19002973e-02f, 7.09044846e-02f, 6.93390331e-02f, 6.72183039e-02f, 6.45611568e-02f, 6.13906537e-02f,
|
||||
5.77340810e-02f, 5.36223917e-02f, 4.90902973e-02f, 4.41756853e-02f, 3.89195025e-02f, 3.33653266e-02f,
|
||||
2.75589553e-02f, 2.15482187e-02f, 1.53823433e-02f, 9.11173206e-03f, 2.78750380e-03f, -3.53899736e-03f,
|
||||
-9.81648845e-03f, -1.59942887e-02f, -2.20226002e-02f, -2.78530676e-02f, -3.34389835e-02f, -3.87358558e-02f,
|
||||
-4.37015752e-02f, -4.82968641e-02f, -5.24856104e-02f, -5.62350079e-02f, -5.95160314e-02f, -6.23034090e-02f,
|
||||
-6.45760369e-02f, -6.63170246e-02f, -6.75138263e-02f, -6.81583864e-02f, -6.82471093e-02f, -6.77809819e-02f,
|
||||
-6.67654439e-02f, -6.52104027e-02f, -6.31301405e-02f, -6.05431381e-02f, -5.74719510e-02f, -5.39430121e-02f,
|
||||
-4.99864152e-02f, -4.56356108e-02f, -4.09271785e-02f, -3.59005358e-02f, -3.05975021e-02f, -2.50620982e-02f,
|
||||
-1.93400931e-02f, -1.34786109e-02f, -7.52582921e-03f, -1.53047296e-03f, 4.45846396e-03f, 1.03922252e-02f,
|
||||
1.62226043e-02f, 2.19024111e-02f, 2.73857927e-02f, 3.26286453e-02f, 3.75889120e-02f, 4.22270162e-02f,
|
||||
4.65060678e-02f, 5.03922602e-02f, 5.38550360e-02f, 5.68673912e-02f, 5.94061299e-02f, 6.14518959e-02f,
|
||||
6.29894927e-02f, 6.40078422e-02f, 6.45002081e-02f, 6.44641312e-02f, 6.39014463e-02f, 6.28183549e-02f,
|
||||
6.12252434e-02f, 5.91366226e-02f, 5.65710713e-02f, 5.35509478e-02f, 5.01023211e-02f, 4.62546289e-02f,
|
||||
4.20405644e-02f, 3.74956324e-02f, 3.26580309e-02f, 2.75681921e-02f, 2.22685138e-02f, 1.68029869e-02f,
|
||||
1.12168479e-02f, 5.55616360e-03f, -1.32475496e-04f, -5.80242145e-03f, -1.14072870e-02f, -1.69013632e-02f,
|
||||
-2.22399629e-02f, -2.73798231e-02f, -3.22793559e-02f, -3.68992177e-02f, -4.12022700e-02f, -4.51542301e-02f,
|
||||
-4.87237130e-02f, -5.18825743e-02f, -5.46061242e-02f, -5.68733215e-02f, -5.86668721e-02f, -5.99735198e-02f,
|
||||
-6.07838952e-02f, -6.10928895e-02f, -6.08993923e-02f, -6.02064781e-02f, -5.90213291e-02f, -5.73550887e-02f,
|
||||
-5.52228853e-02f, -5.26435817e-02f, -4.96396897e-02f, -4.62371294e-02f, -4.24650256e-02f, -3.83554628e-02f,
|
||||
-3.39432096e-02f, -2.92654225e-02f, -2.43613233e-02f, -1.92718970e-02f, -1.40395616e-02f, -8.70771728e-03f,
|
||||
-3.32056777e-03f, 2.07744785e-03f, 7.44190391e-03f, 1.27287222e-02f, 1.78946228e-02f, 2.28975002e-02f,
|
||||
2.76965843e-02f, 3.22530140e-02f, 3.65299534e-02f, 4.04930363e-02f, 4.41105069e-02f, 4.73536159e-02f,
|
||||
5.01967201e-02f, 5.26175750e-02f, 5.45974724e-02f, 5.61213729e-02f, 5.71780843e-02f, 5.77601946e-02f,
|
||||
5.78643759e-02f, 5.74910914e-02f, 5.66448597e-02f, 5.53340158e-02f, 5.35707338e-02f, 5.13708843e-02f,
|
||||
4.87538683e-02f, 4.57425137e-02f, 4.23627999e-02f, 3.86437075e-02f, 3.46169024e-02f, 3.03165387e-02f,
|
||||
2.57788894e-02f, 2.10421222e-02f, 1.61459251e-02f, 1.11311994e-02f, 6.03970466e-03f, 9.13695817e-04f,
|
||||
-4.20433431e-03f, -9.27218149e-03f, -1.42480682e-02f, -1.90911878e-02f, -2.37618648e-02f, -2.82220093e-02f,
|
||||
-3.24353766e-02f, -3.63678336e-02f, -3.99876924e-02f, -4.32659237e-02f, -4.61764207e-02f, -4.86961602e-02f,
|
||||
-5.08054551e-02f, -5.24880386e-02f, -5.37312181e-02f, -5.45260166e-02f, -5.48671104e-02f, -5.47530531e-02f,
|
||||
-5.41860463e-02f, -5.31721475e-02f, -5.17210363e-02f, -4.98459868e-02f, -4.75637647e-02f, -4.48944406e-02f,
|
||||
-4.18612746e-02f, -3.84904206e-02f, -3.48107925e-02f, -3.08537797e-02f, -2.66529685e-02f, -2.22438695e-02f,
|
||||
-1.76636682e-02f, -1.29507560e-02f, -8.14466071e-03f, -3.28544776e-03f, 1.58643018e-03f, 6.43050440e-03f,
|
||||
1.12067405e-02f, 1.58756642e-02f, 2.03989020e-02f, 2.47393345e-02f, 2.88614617e-02f, 3.27317634e-02f,
|
||||
3.63187992e-02f, 3.95936470e-02f, 4.25300387e-02f, 4.51045672e-02f, 4.72968940e-02f, 4.90899703e-02f,
|
||||
5.04700047e-02f, 5.14267809e-02f, 5.19535643e-02f, 5.20472034e-02f, 5.17082287e-02f, 5.09406434e-02f,
|
||||
4.97521048e-02f, 4.81537188e-02f, 4.61599131e-02f, 4.37884262e-02f, 4.10600706e-02f, 3.79985488e-02f,
|
||||
3.46302622e-02f, 3.09841217e-02f, 2.70912412e-02f, 2.29847199e-02f, 1.86992847e-02f, 1.42711599e-02f,
|
||||
9.73752669e-03f, 5.13643650e-03f, 5.06379454e-04f, -4.11408166e-03f, -8.68649476e-03f, -1.31729621e-02f,
|
||||
-1.75363807e-02f, -2.17408089e-02f, -2.57516979e-02f, -2.95362143e-02f, -3.30635093e-02f, -3.63049622e-02f,
|
||||
-3.92344048e-02f, -4.18283298e-02f, -4.40661418e-02f, -4.59301913e-02f, -4.74060505e-02f, -4.84825511e-02f,
|
||||
-4.91518827e-02f, -4.94096235e-02f, -4.92548579e-02f, -4.86900251e-02f, -4.77210458e-02f, -4.63571741e-02f,
|
||||
-4.46108878e-02f, -4.24979107e-02f, -4.00368564e-02f, -3.72492987e-02f, -3.41594108e-02f, -3.07938448e-02f,
|
||||
-2.71814552e-02f, -2.33531198e-02f, -1.93413598e-02f, -1.51802063e-02f, -1.09048013e-02f, -6.55114338e-03f,
|
||||
-2.15581014e-03f, 2.24443555e-03f, 6.61280814e-03f, 1.09129453e-02f, 1.51091980e-02f, 1.91667630e-02f,
|
||||
2.30522168e-02f, 2.67335907e-02f, 3.01807365e-02f, 3.33655579e-02f, 3.62622051e-02f, 3.88473226e-02f,
|
||||
4.11002204e-02f, 4.30030300e-02f, 4.45408790e-02f, 4.57019705e-02f, 4.64777109e-02f, 4.68627135e-02f,
|
||||
4.68549093e-02f, 4.64554958e-02f, 4.56689373e-02f, 4.45029599e-02f, 4.29683919e-02f, 4.10791386e-02f,
|
||||
3.88520159e-02f, 3.63066475e-02f, 3.34652385e-02f, 3.03523892e-02f, 2.69949681e-02f, 2.34217263e-02f,
|
||||
1.96632025e-02f, 1.57513974e-02f, 1.17194459e-02f, 7.60145677e-03f, 3.43215481e-03f, -7.53454950e-04f,
|
||||
-4.92025229e-03f, -9.03345904e-03f, -1.30587503e-02f, -1.69627406e-02f, -2.07130441e-02f, -2.42787472e-02f,
|
||||
-2.76304969e-02f, -3.07408842e-02f, -3.35845310e-02f, -3.61384026e-02f, -3.83819804e-02f, -4.02973364e-02f,
|
||||
-4.18693911e-02f, -4.30859849e-02f, -4.39379525e-02f, -4.44192202e-02f, -4.45268207e-02f, -4.42609489e-02f,
|
||||
-4.36249417e-02f, -4.26251693e-02f, -4.12710965e-02f, -3.95751119e-02f, -3.75524034e-02f, -3.52209020e-02f,
|
||||
-3.26010732e-02f, -2.97156826e-02f, -2.65897306e-02f, -2.32501339e-02f, -1.97255230e-02f, -1.60459906e-02f,
|
||||
-1.22428645e-02f, -8.34840613e-03f, -4.39555788e-03f, -4.17641093e-04f, 3.55186529e-03f, 7.47969548e-03f,
|
||||
1.13330289e-02f, 1.50796895e-02f, 1.86886063e-02f, 2.21298440e-02f, 2.53750227e-02f, 2.83974776e-02f,
|
||||
3.11724713e-02f, 3.36774564e-02f, 3.58921485e-02f, 3.77988281e-02f, 3.93823848e-02f, 4.06304645e-02f,
|
||||
4.15335460e-02f, 4.20850895e-02f, 4.22814530e-02f, 4.21220657e-02f, 4.16092724e-02f, 4.07484568e-02f,
|
||||
3.95478256e-02f, 3.80185099e-02f, 3.61742882e-02f, 3.40316228e-02f, 3.16093467e-02f, 2.89286854e-02f,
|
||||
2.60129143e-02f, 2.28872072e-02f, 1.95785162e-02f, 1.61151429e-02f, 1.25266872e-02f, 8.84367289e-03f,
|
||||
5.09737541e-03f, 1.31946573e-03f, -2.45819207e-03f, -6.20382907e-03f, -9.88599514e-03f, -1.34739714e-02f,
|
||||
-1.69377975e-02f, -2.02487225e-02f, -2.33793144e-02f, -2.63038233e-02f, -2.89981802e-02f, -3.14404213e-02f,
|
||||
-3.36107546e-02f, -3.54916723e-02f, -3.70682427e-02f, -3.83280672e-02f, -3.92614736e-02f, -3.98615776e-02f,
|
||||
-4.01243243e-02f, -4.00484517e-02f, -3.96356708e-02f, -3.88903731e-02f, -3.78198781e-02f, -3.64341365e-02f,
|
||||
-3.47457457e-02f, -3.27698392e-02f, -3.05238882e-02f, -2.80276282e-02f, -2.53028218e-02f, -2.23730957e-02f,
|
||||
-1.92637467e-02f, -1.60015029e-02f, -1.26142882e-02f, -9.13104283e-03f, -5.58138981e-03f, -1.99542434e-03f,
|
||||
1.59649307e-03f, 5.16408174e-03f, 8.67737144e-03f, 1.21068581e-02f, 1.54239205e-02f, 1.86009100e-02f,
|
||||
2.16114772e-02f, 2.44306994e-02f, 2.70354163e-02f, 2.94042665e-02f, 3.15179985e-02f, 3.33595356e-02f,
|
||||
3.49141593e-02f, 3.61696229e-02f, 3.71161871e-02f, 3.77468512e-02f, 3.80571878e-02f, 3.80455485e-02f,
|
||||
3.77129900e-02f, 3.70632810e-02f, 3.61028508e-02f, 3.48407199e-02f, 3.32884428e-02f, 3.14600053e-02f,
|
||||
2.93716228e-02f, 2.70417408e-02f, 2.44907277e-02f, 2.17407576e-02f, 1.88156734e-02f, 1.57406803e-02f,
|
||||
1.25421761e-02f, 9.24754692e-03f, 5.88488640e-03f, 2.48280587e-03f, -9.29864758e-04f, -4.32426314e-03f,
|
||||
-7.67179184e-03f, -1.09442952e-02f, -1.41143886e-02f, -1.71555974e-02f, -2.00425787e-02f, -2.27514891e-02f,
|
||||
-2.52599054e-02f, -2.75472706e-02f, -2.95949315e-02f, -3.13863062e-02f, -3.29069832e-02f, -3.41450096e-02f,
|
||||
-3.50907101e-02f, -3.57369992e-02f, -3.60793163e-02f, -3.61156751e-02f, -3.58467080e-02f, -3.52755740e-02f,
|
||||
-3.44080617e-02f, -3.32523628e-02f, -3.18191314e-02f, -3.01213186e-02f, -2.81740846e-02f, -2.59946393e-02f,
|
||||
-2.36021125e-02f, -2.10173975e-02f, -1.82629132e-02f, -1.53624700e-02f, -1.23410560e-02f, -9.22456599e-03f,
|
||||
-6.03967755e-03f, -2.81350877e-03f, 4.26514319e-04f, 3.65292660e-03f, 6.83848944e-03f, 9.95638508e-03f,
|
||||
1.29804234e-02f, 1.58853076e-02f, 1.86468203e-02f, 2.12420277e-02f, 2.36494909e-02f, 2.58493792e-02f,
|
||||
2.78237450e-02f, 2.95565060e-02f, 3.10338053e-02f, 3.22438572e-02f, 3.31772716e-02f, 3.38269627e-02f,
|
||||
3.41883176e-02f, 3.42591610e-02f, 3.40397435e-02f, 3.35328606e-02f, 3.27436351e-02f, 3.16796573e-02f,
|
||||
3.03507246e-02f, 2.87689689e-02f, 2.69484839e-02f, 2.49054827e-02f, 2.26579086e-02f, 2.02254442e-02f,
|
||||
1.76292617e-02f, 1.48918382e-02f, 1.20368159e-02f, 9.08872468e-03f, 6.07283273e-03f, 3.01489838e-03f,
|
||||
-5.90212194e-05f, -3.12287666e-03f, -6.15069532e-03f, -9.11695091e-03f, -1.19967033e-02f, -1.47657868e-02f,
|
||||
-1.74011004e-02f, -1.98807214e-02f, -2.21841025e-02f, -2.42922632e-02f, -2.61879368e-02f, -2.78557311e-02f,
|
||||
-2.92821801e-02f, -3.04559562e-02f, -3.13678907e-02f, -3.20110632e-02f, -3.23808087e-02f, -3.24749193e-02f,
|
||||
-3.22933847e-02f, -3.18386269e-02f, -3.11153366e-02f, -3.01304804e-02f, -2.88932552e-02f, -2.74148734e-02f,
|
||||
-2.57086673e-02f, -2.37898314e-02f, -2.16752343e-02f, -1.93835013e-02f, -1.69345799e-02f, -1.43497284e-02f,
|
||||
-1.16513243e-02f, -8.86259097e-03f, -6.00748525e-03f, -3.11044903e-03f, -1.96143386e-04f, 2.71056658e-03f,
|
||||
5.58512222e-03f, 8.40318833e-03f, 1.11410160e-02f, 1.37756382e-02f, 1.62850338e-02f, 1.86482666e-02f,
|
||||
2.08457445e-02f, 2.28593437e-02f, 2.46725329e-02f, 2.62705694e-02f, 2.76405329e-02f, 2.87715470e-02f,
|
||||
2.96547092e-02f, 3.02833419e-02f, 3.06529059e-02f, 3.07610441e-02f, 3.06076742e-02f, 3.01949567e-02f,
|
||||
2.95271502e-02f, 2.86107876e-02f, 2.74543883e-02f, 2.60685701e-02f, 2.44657863e-02f, 2.26603655e-02f,
|
||||
2.06682557e-02f, 1.85070033e-02f, 1.61954603e-02f, 1.37537720e-02f, 1.12030588e-02f, 8.56537064e-03f,
|
||||
5.86336215e-03f, 3.12021752e-03f, 3.59345288e-04f, -2.39571357e-03f, -5.12158252e-03f, -7.79518527e-03f,
|
||||
-1.03939536e-02f, -1.28961026e-02f, -1.52805838e-02f, -1.75275761e-02f, -1.96183935e-02f, -2.15357712e-02f,
|
||||
-2.32639542e-02f, -2.47888545e-02f, -2.60981899e-02f, -2.71814567e-02f, -2.80302370e-02f, -2.86380088e-02f,
|
||||
-2.90003996e-02f, -2.91151172e-02f, -2.89819544e-02f, -2.86028697e-02f, -2.79818317e-02f, -2.71249297e-02f,
|
||||
-2.60401957e-02f, -2.47375751e-02f, -2.32288414e-02f, -2.15275091e-02f, -1.96486443e-02f, -1.76087964e-02f,
|
||||
-1.54258426e-02f, -1.31187994e-02f, -1.07076937e-02f, -8.21335282e-03f, -5.65730582e-03f, -3.06143405e-03f,
|
||||
-4.47990175e-04f, 2.16074548e-03f, 4.74260737e-03f, 7.27569124e-03f, 9.73864733e-03f, 1.21106824e-02f,
|
||||
1.43719841e-02f, 1.65036001e-02f, 1.84878471e-02f, 2.03083286e-02f, 2.19500531e-02f, 2.33996493e-02f,
|
||||
2.46453861e-02f, 2.56773512e-02f, 2.64874345e-02f, 2.70694463e-02f, 2.74192279e-02f, 2.75344951e-02f,
|
||||
2.74150667e-02f, 2.70627089e-02f, 2.64811913e-02f, 2.56761950e-02f, 2.46553112e-02f, 2.34279326e-02f,
|
||||
2.20051823e-02f, 2.03998041e-02f, 1.86260730e-02f, 1.66996483e-02f, 1.46373888e-02f, 1.24573628e-02f,
|
||||
1.01784699e-02f, 7.82046099e-03f, 5.40366356e-03f, 2.94886537e-03f, 4.77074685e-04f, -1.99056008e-03f,
|
||||
-4.43309957e-03f, -6.82975366e-03f, -9.16032780e-03f, -1.14051392e-02f, -1.35453571e-02f, -1.55631186e-02f,
|
||||
-1.74416221e-02f, -1.91653203e-02f, -2.07200521e-02f, -2.20931290e-02f, -2.32734389e-02f, -2.42515770e-02f,
|
||||
-2.50198790e-02f, -2.55724740e-02f, -2.59053977e-02f, -2.60165073e-02f, -2.59056121e-02f, -2.55744100e-02f,
|
||||
-2.50263861e-02f, -2.42670139e-02f, -2.33034172e-02f, -2.21444752e-02f, -2.08007704e-02f, -1.92843016e-02f,
|
||||
-1.76086143e-02f, -1.57885066e-02f, -1.38399632e-02f, -1.17800468e-02f, -9.62665505e-03f, -7.39846180e-03f,
|
||||
-5.11473979e-03f, -2.79509520e-03f, -4.59475153e-04f, 1.87219411e-03f, 4.18004886e-03f, 6.44446028e-03f,
|
||||
8.64630036e-03f, 1.07670050e-02f, 1.27887263e-02f, 1.46946183e-02f, 1.64687696e-02f, 1.80965074e-02f,
|
||||
1.95644657e-02f, 2.08606409e-02f, 2.19745569e-02f, 2.28973400e-02f, 2.36217678e-02f, 2.41423032e-02f,
|
||||
2.44552329e-02f, 2.45585559e-02f, 2.44521268e-02f, 2.41375247e-02f, 2.36181843e-02f, 2.28991883e-02f,
|
||||
2.19873596e-02f, 2.08911372e-02f, 1.96204854e-02f, 1.81868423e-02f, 1.66029686e-02f, 1.48829260e-02f,
|
||||
1.30418196e-02f, 1.10957823e-02f, 9.06176569e-03f, 6.95742371e-03f, 4.80095797e-03f, 2.61094572e-03f,
|
||||
4.06163422e-04f, -1.79448120e-03f, -3.97227507e-03f, -6.10867089e-03f, -8.18559133e-03f, -1.01855447e-02f,
|
||||
-1.20916775e-02f, -1.38880736e-02f, -1.55597947e-02f, -1.70929424e-02f, -1.84749792e-02f, -1.96945768e-02f,
|
||||
-2.07419008e-02f, -2.16086011e-02f, -2.22879060e-02f, -2.27746496e-02f, -2.30653527e-02f, -2.31582122e-02f,
|
||||
-2.30530853e-02f, -2.27516002e-02f, -2.22569518e-02f, -2.15740851e-02f, -2.07094459e-02f, -1.96710504e-02f,
|
||||
-1.84683607e-02f, -1.71122258e-02f, -1.56147530e-02f, -1.39891960e-02f, -1.22499260e-02f, -1.04121226e-02f,
|
||||
-8.49187069e-03f, -6.50583812e-03f, -4.47121574e-03f, -2.40553061e-03f, -3.26560349e-04f, 1.74792849e-03f,
|
||||
3.80020986e-03f, 5.81284812e-03f, 7.76878436e-03f, 9.65152189e-03f, 1.14452321e-02f, 1.31348903e-02f,
|
||||
1.47064602e-02f, 1.61469015e-02f, 1.74443880e-02f, 1.85883329e-02f, 1.95694960e-02f, 2.03800747e-02f,
|
||||
2.10137416e-02f, 2.14657028e-02f, 2.17327470e-02f, 2.18132189e-02f, 2.17071096e-02f, 2.14159688e-02f,
|
||||
2.09429396e-02f, 2.02927056e-02f, 1.94714591e-02f, 1.84867806e-02f, 1.73476996e-02f, 1.60644888e-02f,
|
||||
1.46486021e-02f, 1.31126305e-02f, 1.14700918e-02f, 9.73543186e-03f, 7.92379251e-03f, 6.05090462e-03f,
|
||||
4.13301608e-03f, 2.18669055e-03f, 2.28581333e-04f, -1.72441072e-03f, -3.65572200e-03f, -5.54887990e-03f,
|
||||
-7.38782061e-03f, -9.15706782e-03f, -1.08417082e-02f, -1.24276657e-02f, -1.39017311e-02f, -1.52516970e-02f,
|
||||
-1.64664949e-02f, -1.75361817e-02f, -1.84521823e-02f, -1.92071599e-02f, -1.97953056e-02f, -2.02121243e-02f,
|
||||
-2.04547147e-02f, -2.05216098e-02f, -2.04128534e-02f, -2.01300439e-02f, -1.96761990e-02f, -1.90558123e-02f,
|
||||
-1.82748056e-02f, -1.73404276e-02f, -1.62612067e-02f, -1.50469098e-02f, -1.37084115e-02f, -1.22575769e-02f,
|
||||
-1.07072432e-02f, -9.07102930e-03f, -7.36320826e-03f, -5.59869147e-03f, -3.79270806e-03f, -1.96092013e-03f,
|
||||
-1.19027325e-04f, 1.71713152e-03f, 3.53191747e-03f, 5.30986343e-03f, 7.03590331e-03f, 8.69547560e-03f,
|
||||
1.02746006e-02f, 1.17601122e-02f, 1.31396009e-02f, 1.44016653e-02f, 1.55359973e-02f, 1.65332483e-02f,
|
||||
1.73855033e-02f, 1.80859434e-02f, 1.86291305e-02f, 1.90110277e-02f, 1.92289384e-02f, 1.92815880e-02f,
|
||||
1.91691688e-02f, 1.88932135e-02f, 1.84567183e-02f, 1.78639790e-02f, 1.71206377e-02f, 1.62336473e-02f,
|
||||
1.52110920e-02f, 1.40622274e-02f, 1.27973510e-02f, 1.14277163e-02f, 9.96541843e-03f, 8.42333112e-03f,
|
||||
6.81491991e-03f, 5.15420944e-03f, 3.45559138e-03f, 1.73374462e-03f, 3.49154958e-06f, -1.72033182e-03f,
|
||||
-3.42300908e-03f, -5.09002877e-03f, -6.70728983e-03f, -8.26110592e-03f, -9.73843101e-03f, -1.11269177e-02f,
|
||||
-1.24149972e-02f, -1.35920411e-02f, -1.46483675e-02f, -1.55754162e-02f, -1.63657097e-02f, -1.70130158e-02f,
|
||||
-1.75123254e-02f, -1.78599156e-02f, -1.80533642e-02f, -1.80916471e-02f, -1.79749596e-02f, -1.77049199e-02f,
|
||||
-1.72844059e-02f, -1.67175734e-02f, -1.60098348e-02f, -1.51677846e-02f, -1.41991369e-02f, -1.31126308e-02f,
|
||||
-1.19180614e-02f, -1.06260158e-02f, -9.24795820e-03f, -7.79599691e-03f, -6.28282689e-03f, -4.72166017e-03f,
|
||||
-3.12602130e-03f, -1.50971188e-03f, 1.13358008e-04f, 1.72924640e-03f, 3.32419869e-03f, 4.88457483e-03f,
|
||||
6.39719332e-03f, 7.84928507e-03f, 9.22860374e-03f, 1.05236737e-02f, 1.17237027e-02f, 1.28187631e-02f,
|
||||
1.37999219e-02f, 1.46591627e-02f, 1.53896448e-02f, 1.59855771e-02f, 1.64423748e-02f, 1.67566705e-02f,
|
||||
1.69263151e-02f, 1.69504088e-02f, 1.68293192e-02f, 1.65646048e-02f, 1.61591292e-02f, 1.56168830e-02f,
|
||||
1.49430466e-02f, 1.41438870e-02f, 1.32267343e-02f, 1.21999194e-02f, 1.10726150e-02f, 9.85491162e-03f,
|
||||
8.55755480e-03f, 7.19198626e-03f, 5.77013714e-03f, 4.30443841e-03f, 2.80758857e-03f, 1.29252809e-03f,
|
||||
-2.27683018e-04f, -1.74000213e-03f, -3.23153173e-03f, -4.68956247e-03f, -6.10171563e-03f, -7.45612506e-03f,
|
||||
-8.74136426e-03f, -9.94672023e-03f, -1.10621909e-02f, -1.20785406e-02f, -1.29874795e-02f, -1.37816456e-02f,
|
||||
-1.44546479e-02f, -1.50012468e-02f, -1.54172106e-02f, -1.56995155e-02f, -1.58462779e-02f, -1.58567437e-02f,
|
||||
-1.57313825e-02f, -1.54717967e-02f, -1.50807184e-02f, -1.45620705e-02f, -1.39207297e-02f, -1.31627253e-02f,
|
||||
-1.22950111e-02f, -1.13254027e-02f, -1.02626834e-02f, -9.11627932e-03f, -7.89634415e-03f, -6.61364765e-03f,
|
||||
-5.27939952e-03f, -3.90525708e-03f, -2.50314317e-03f, -1.08517576e-03f, 3.36418391e-04f, 1.74945190e-03f,
|
||||
3.14186033e-03f, 4.50178261e-03f, 5.81769448e-03f, 7.07851939e-03f, 8.27365386e-03f, 9.39310326e-03f,
|
||||
1.04276320e-02f, 1.13686527e-02f, 1.22085379e-02f, 1.29404450e-02f, 1.35585678e-02f, 1.40580446e-02f,
|
||||
1.44350939e-02f, 1.46869568e-02f, 1.48120098e-02f, 1.48096348e-02f, 1.46804295e-02f, 1.44259781e-02f,
|
||||
1.40489668e-02f, 1.35531325e-02f, 1.29432014e-02f, 1.22248563e-02f, 1.14046959e-02f, 1.04901687e-02f,
|
||||
9.48948107e-03f, 8.41156632e-03f, 7.26596347e-03f, 6.06280447e-03f, 4.81257444e-03f, 3.52622627e-03f,
|
||||
2.21492506e-03f, 8.89983592e-04f, -4.37153812e-04f, -1.75513167e-03f, -3.05265494e-03f, -4.31872834e-03f,
|
||||
-5.54261874e-03f, -6.71396264e-03f, -7.82302244e-03f, -8.86045250e-03f, -9.81773278e-03f, -1.06869351e-02f,
|
||||
-1.14610023e-02f, -1.21336754e-02f, -1.26995953e-02f, -1.31543908e-02f, -1.34945718e-02f, -1.37177266e-02f,
|
||||
-1.38224110e-02f, -1.38082286e-02f, -1.36757739e-02f, -1.34266887e-02f, -1.30635886e-02f, -1.25900369e-02f,
|
||||
-1.20105709e-02f, -1.13305978e-02f, -1.05563538e-02f, -9.69485926e-03f, -8.75389081e-03f, -7.74181164e-03f,
|
||||
-6.66761679e-03f, -5.54076187e-03f, -4.37111830e-03f, -3.16893052e-03f, -1.94457115e-03f, -7.08705149e-04f,
|
||||
5.28079290e-04f, 1.75515870e-03f, 2.96204304e-03f, 4.13848585e-03f, 5.27451557e-03f, 6.36060039e-03f,
|
||||
7.38755863e-03f, 8.34692530e-03f, 9.23070802e-03f, 1.00316534e-02f, 1.07432528e-02f, 1.13597680e-02f,
|
||||
1.18763350e-02f, 1.22889283e-02f, 1.25944631e-02f, 1.27907515e-02f, 1.28765994e-02f, 1.28517102e-02f,
|
||||
1.27167966e-02f, 1.24734480e-02f, 1.21242371e-02f, 1.16725839e-02f, 1.11228281e-02f, 1.04800592e-02f,
|
||||
9.75022575e-03f, 8.93990424e-03f, 8.05644990e-03f, 7.10768601e-03f, 6.10205625e-03f, 5.04843878e-03f,
|
||||
3.95605458e-03f, 2.83441418e-03f, 1.69331277e-03f, 5.42568186e-04f, -6.07877124e-04f, -1.74818575e-03f,
|
||||
-2.86860405e-03f, -3.95962685e-03f, -5.01201657e-03f, -6.01690058e-03f, -6.96589716e-03f, -7.85110424e-03f,
|
||||
-8.66518231e-03f, -9.40145619e-03f, -1.00540095e-02f, -1.06175123e-02f, -1.10876024e-02f, -1.14606062e-02f,
|
||||
-1.17337519e-02f, -1.19051415e-02f, -1.19737311e-02f, -1.19393909e-02f, -1.18028751e-02f, -1.15657387e-02f,
|
||||
-1.12305357e-02f, -1.08005049e-02f, -1.02797519e-02f, -9.67318729e-03f, -8.98632838e-03f, -8.22543877e-03f,
|
||||
-7.39737215e-03f, -6.50950785e-03f, -5.56975395e-03f, -4.58632875e-03f, -3.56792674e-03f, -2.52340823e-03f,
|
||||
-1.46183597e-03f, -3.92391156e-04f, 6.75701684e-04f, 1.73331709e-03f, 2.77141530e-03f, 3.78118353e-03f,
|
||||
4.75407672e-03f, 5.68193005e-03f, 6.55698994e-03f, 7.37195674e-03f, 8.12013345e-03f, 8.79539509e-03f,
|
||||
9.39225030e-03f, 9.90597190e-03f, 1.03324819e-02f, 1.06685242e-02f, 1.09116177e-02f, 1.10600973e-02f,
|
||||
1.11130936e-02f, 1.10705983e-02f, 1.09333788e-02f, 1.07030445e-02f, 1.03819949e-02f, 9.97335332e-03f,
|
||||
9.48107464e-03f, 8.90968434e-03f, 8.26449756e-03f, 7.55132972e-03f, 6.77664458e-03f, 5.94731079e-03f,
|
||||
5.07073939e-03f, 4.15462520e-03f, 3.20700306e-03f, 2.23616222e-03f, 1.25050340e-03f, 2.58592562e-04f,
|
||||
-7.31105992e-04f, -1.71003848e-03f, -2.66991104e-03f, -3.60254805e-03f, -4.50009626e-03f, -5.35500152e-03f,
|
||||
-6.16013372e-03f, -6.90880302e-03f, -7.59484887e-03f, -8.21267759e-03f, -8.75730297e-03f, -9.22437062e-03f,
|
||||
-9.61022818e-03f, -9.91196266e-03f, -1.01273334e-02f, -1.02549146e-02f, -1.02939949e-02f, -1.02446487e-02f,
|
||||
-1.01077102e-02f, -9.88473930e-03f, -9.57804506e-03f, -9.19065219e-03f, -8.72623997e-03f, -8.18914967e-03f,
|
||||
-7.58431711e-03f, -6.91725624e-03f, -6.19393169e-03f, -5.42085678e-03f, -4.60486090e-03f, -3.75314479e-03f,
|
||||
-2.87318400e-03f, -1.97263669e-03f, -1.05936420e-03f, -1.41184633e-04f, 7.73935206e-04f, 1.67818033e-03f,
|
||||
2.56387121e-03f, 3.42348245e-03f, 4.24972968e-03f, 5.03575853e-03f, 5.77493594e-03f, 6.46117800e-03f,
|
||||
7.08885263e-03f, 7.65282423e-03f, 8.14856911e-03f, 8.57214716e-03f, 8.92027019e-03f, 9.19029194e-03f,
|
||||
9.38027470e-03f, 9.48895025e-03f, 9.51578399e-03f, 9.46091429e-03f, 9.32518284e-03f, 9.11016180e-03f,
|
||||
8.81806173e-03f, 8.45171440e-03f, 8.01466407e-03f, 7.51094572e-03f, 6.94521826e-03f, 6.32261691e-03f,
|
||||
5.64875255e-03f, 4.92963671e-03f, 4.17165548e-03f, 3.38149573e-03f, 2.56610069e-03f, 1.73253154e-03f,
|
||||
8.88083719e-04f, 4.00140997e-05f, -8.04377007e-04f, -1.63786496e-03f, -2.45336348e-03f, -3.24394120e-03f,
|
||||
-4.00297149e-03f, -4.72406012e-03f, -5.40122825e-03f, -6.02886353e-03f, -6.60184564e-03f, -7.11547043e-03f,
|
||||
-7.56567204e-03f, -7.94886879e-03f, -8.26207948e-03f, -8.50298133e-03f, -8.66984745e-03f, -8.76158174e-03f,
|
||||
-8.77778600e-03f, -8.71866903e-03f, -8.58510255e-03f, -8.37858953e-03f, -8.10125332e-03f, -7.75580633e-03f,
|
||||
-7.34555568e-03f, -6.87431135e-03f, -6.34642360e-03f, -5.76669768e-03f, -5.14031767e-03f, -4.47294897e-03f,
|
||||
-3.77043291e-03f, -3.03903272e-03f, -2.28511456e-03f, -1.51527024e-03f, -7.36178447e-04f, 4.54225562e-05f,
|
||||
8.22859022e-04f, 1.58943109e-03f, 2.33866278e-03f, 3.06420334e-03f, 3.75990680e-03f, 4.42002538e-03f,
|
||||
5.03901750e-03f, 5.61180111e-03f, 6.13366220e-03f, 6.60043272e-03f, 7.00831931e-03f, 7.35414500e-03f,
|
||||
7.63524392e-03f, 7.84953557e-03f, 7.99547645e-03f, 8.07218955e-03f, 8.07933095e-03f, 8.01721906e-03f,
|
||||
7.88666864e-03f, 7.68919343e-03f, 7.42679720e-03f, 7.10202788e-03f, 6.71802523e-03f, 6.27832934e-03f,
|
||||
5.78702253e-03f, 5.24853339e-03f, 4.66776048e-03f, 4.04985033e-03f, 3.40032055e-03f, 2.72486114e-03f,
|
||||
2.02943382e-03f, 1.32005555e-03f, 6.02922229e-04f, -1.15810889e-04f, -8.29962401e-04f, -1.53344695e-03f,
|
||||
-2.22024937e-03f, -2.88460828e-03f, -3.52090915e-03f, -4.12386103e-03f, -4.68844782e-03f, -5.21000854e-03f,
|
||||
-5.68433641e-03f, -6.10753890e-03f, -6.47629357e-03f, -6.78770430e-03f, -7.03936807e-03f, -7.22944790e-03f,
|
||||
-7.35662441e-03f, -7.42012069e-03f, -7.41971164e-03f, -7.35573757e-03f, -7.22905724e-03f, -7.04107429e-03f,
|
||||
-6.79370122e-03f, -6.48940038e-03f, -6.13102314e-03f, -5.72192873e-03f, -5.26590521e-03f, -4.76707464e-03f,
|
||||
-4.22993214e-03f, -3.65930825e-03f, -3.06022345e-03f, -2.43797793e-03f, -1.79803310e-03f, -1.14594988e-03f,
|
||||
-4.87389180e-04f, 1.71985886e-04f, 8.26505744e-04f, 1.47057292e-03f, 2.09875564e-03f, 2.70572827e-03f,
|
||||
3.28638788e-03f, 3.83592350e-03f, 4.34975506e-03f, 4.82368759e-03f, 5.25383132e-03f, 5.63677359e-03f,
|
||||
5.96942535e-03f, 6.24924092e-03f, 6.47405650e-03f, 6.64226721e-03f, 6.75269253e-03f, 6.80469430e-03f,
|
||||
6.79815717e-03f, 6.73340631e-03f, 6.61130455e-03f, 6.43322863e-03f, 6.20094526e-03f, 5.91677710e-03f,
|
||||
5.58340169e-03f, 5.20393196e-03f, 4.78187614e-03f, 4.32106320e-03f, 3.82565711e-03f, 3.30005613e-03f,
|
||||
2.74895362e-03f, 2.17719303e-03f, 1.58978015e-03f, 9.91844057e-04f, 3.88540330e-04f, -2.14916878e-04f,
|
||||
-8.13361192e-04f, -1.40168257e-03f, -1.97489740e-03f, -2.52818059e-03f, -3.05688539e-03f, -3.55662656e-03f,
|
||||
-4.02326574e-03f, -4.45296958e-03f, -4.84228652e-03f, -5.18803438e-03f, -5.48755315e-03f, -5.73848611e-03f,
|
||||
-5.93891991e-03f, -6.08745626e-03f, -6.18305471e-03f, -6.22520840e-03f, -6.21382472e-03f, -6.14928419e-03f,
|
||||
-6.03244633e-03f, -5.86455879e-03f, -5.64736180e-03f, -5.38296537e-03f, -5.07389363e-03f, -4.72301916e-03f,
|
||||
-4.33361321e-03f, -3.90915761e-03f, -3.45353173e-03f, -2.97077347e-03f, -2.46516689e-03f, -1.94119584e-03f,
|
||||
-1.40340595e-03f, -8.56512644e-04f, -3.05232133e-04f, 2.45691031e-04f, 7.91538060e-04f, 1.32763724e-03f,
|
||||
1.84949345e-03f, 2.35267547e-03f, 2.83299113e-03f, 3.28645035e-03f, 3.70931698e-03f, 4.09812665e-03f,
|
||||
4.44973511e-03f, 4.76135341e-03f, 5.03050354e-03f, 5.25513155e-03f, 5.43353323e-03f, 5.56447821e-03f,
|
||||
5.64705544e-03f, 5.68083601e-03f, 5.66583437e-03f, 5.60238431e-03f, 5.49135375e-03f, 5.33391723e-03f,
|
||||
5.13169207e-03f, 4.88664671e-03f, 4.60113202e-03f, 4.27780860e-03f, 3.91964875e-03f, 3.52989866e-03f,
|
||||
3.11212090e-03f, 2.66999053e-03f, 2.20744344e-03f, 1.72859110e-03f, 1.23756351e-03f, 7.38678150e-04f,
|
||||
2.36236760e-04f, -2.65462378e-04f, -7.62072815e-04f, -1.24943395e-03f, -1.72337956e-03f, -2.17993754e-03f,
|
||||
-2.61530935e-03f, -3.02588421e-03f, -3.40825196e-03f, -3.75935360e-03f, -4.07630652e-03f, -4.35660760e-03f,
|
||||
-4.59808398e-03f, -4.79883718e-03f, -4.95743843e-03f, -5.07271280e-03f, -5.14393833e-03f, -5.17077608e-03f,
|
||||
-5.15318763e-03f, -5.09164480e-03f, -4.98686807e-03f, -4.84002285e-03f, -4.65260103e-03f, -4.42642977e-03f,
|
||||
-4.16366446e-03f, -3.86678300e-03f, -3.53847751e-03f, -3.18177292e-03f, -2.79986847e-03f, -2.39618401e-03f,
|
||||
-1.97429017e-03f, -1.53788782e-03f, -1.09083664e-03f, -6.36973406e-04f, -1.80264329e-04f, 2.75399352e-04f,
|
||||
7.26104424e-04f, 1.16802598e-03f, 1.59744046e-03f, 2.01073128e-03f, 2.40446819e-03f, 2.77538562e-03f,
|
||||
3.12044615e-03f, 3.43683203e-03f, 3.72202393e-03f, 3.97374850e-03f, 4.19002854e-03f, 4.36925418e-03f,
|
||||
4.51006070e-03f, 4.61152219e-03f, 4.67293053e-03f, 4.69404975e-03f, 4.67490366e-03f, 4.61589307e-03f,
|
||||
4.51775252e-03f, 4.38154991e-03f, 4.20868532e-03f, 4.00082377e-03f, 3.75997274e-03f, 3.48836415e-03f,
|
||||
3.18851504e-03f, 2.86314343e-03f, 2.51519536e-03f, 2.14776743e-03f, 1.76411750e-03f, 1.36763070e-03f,
|
||||
9.61751835e-04f, 5.50052405e-04f, 1.36015058e-04f, -2.76720943e-04f, -6.84698152e-04f, -1.08442387e-03f,
|
||||
-1.47253691e-03f, -1.84578853e-03f, -2.20105818e-03f, -2.53544188e-03f, -2.84616998e-03f, -3.13076058e-03f,
|
||||
-3.38689733e-03f, -3.61260297e-03f, -3.80606518e-03f, -3.96589267e-03f, -4.09087232e-03f, -4.18013173e-03f,
|
||||
-4.23315965e-03f, -4.24970953e-03f, -4.22981560e-03f, -4.17392494e-03f, -4.08267808e-03f, -3.95709577e-03f,
|
||||
-3.79845153e-03f, -3.60829670e-03f, -3.38844338e-03f, -3.14094669e-03f, -2.86809742e-03f, -2.57237442e-03f,
|
||||
-2.25643831e-03f, -1.92312165e-03f, -1.57535841e-03f, -1.21624129e-03f, -8.48868370e-04f, -4.76457354e-04f,
|
||||
-1.02227062e-04f, 2.70659894e-04f, 6.38948957e-04f, 9.99596773e-04f, 1.34950884e-03f, 1.68579412e-03f,
|
||||
2.00565112e-03f, 2.30644176e-03f, 2.58570970e-03f, 2.84121989e-03f, 3.07087670e-03f, 3.27296771e-03f,
|
||||
3.44584695e-03f, 3.58825627e-03f, 3.69915439e-03f, 3.77779535e-03f, 3.82369144e-03f, 3.83666312e-03f,
|
||||
3.81678507e-03f, 3.76444486e-03f, 3.68027755e-03f, 3.56519883e-03f, 3.42038694e-03f, 3.24725992e-03f,
|
||||
3.04745181e-03f, 2.82287635e-03f, 2.57555610e-03f, 2.30778342e-03f, 2.02193938e-03f, 1.72060684e-03f,
|
||||
1.40642226e-03f, 1.08218540e-03f, 7.50708128e-04f, 4.14852040e-04f, 7.75468400e-05f, -2.58336678e-04f,
|
||||
-5.89954675e-04f, -9.14464553e-04f, -1.22917409e-03f, -1.53142096e-03f, -1.81874942e-03f, -2.08875765e-03f,
|
||||
-2.33925204e-03f, -2.56824046e-03f, -2.77387464e-03f, -2.95457151e-03f, -3.10891286e-03f, -3.23576957e-03f,
|
||||
-3.33422309e-03f, -3.40361730e-03f, -3.44352432e-03f, -3.45380945e-03f, -3.43454926e-03f, -3.38612359e-03f,
|
||||
-3.30910238e-03f, -3.20434413e-03f, -3.07289782e-03f, -2.91605448e-03f, -2.73534798e-03f, -2.53242439e-03f,
|
||||
-2.30918427e-03f, -2.06766744e-03f, -1.81002532e-03f, -1.53857461e-03f, -1.25572213e-03f, -9.63956082e-04f,
|
||||
-6.65804929e-04f, -3.63875198e-04f, -6.07622519e-05f, 2.40955893e-04f, 5.38685581e-04f, 8.29936911e-04f,
|
||||
1.11224977e-03f, 1.38328230e-03f, 1.64080028e-03f, 1.88265574e-03f, 2.10694670e-03f, 2.31181334e-03f,
|
||||
2.49567938e-03f, 2.65707799e-03f, 2.79477329e-03f, 2.90778929e-03f, 2.99526804e-03f, 3.05666792e-03f,
|
||||
3.09159989e-03f, 3.09996074e-03f, 3.08183486e-03f, 3.03757314e-03f, 2.96768997e-03f, 2.87296391e-03f,
|
||||
2.75438271e-03f, 2.61305979e-03f, 2.45041225e-03f, 2.26792371e-03f, 2.06728115e-03f, 1.85034398e-03f,
|
||||
1.61901728e-03f, 1.37543970e-03f, 1.12168235e-03f, 8.60048928e-04f, 5.92781787e-04f, 3.22217129e-04f,
|
||||
5.06437951e-05f, -2.19547817e-04f, -4.86132510e-04f, -7.46817210e-04f, -9.99443627e-04f, -1.24188233e-03f,
|
||||
-1.47217245e-03f, -1.68839648e-03f, -1.88883105e-03f, -2.07184785e-03f, -2.23601745e-03f, -2.38006048e-03f,
|
||||
-2.50288118e-03f, -2.60358292e-03f, -2.68144174e-03f, -2.73595307e-03f, -2.76679595e-03f, -2.77388624e-03f,
|
||||
-2.75729794e-03f, -2.71735188e-03f, -2.65451985e-03f, -2.56952130e-03f, -2.46319204e-03f, -2.33660956e-03f,
|
||||
-2.19096493e-03f, -2.02765268e-03f, -1.84815939e-03f, -1.65412932e-03f, -1.44731483e-03f, -1.22956426e-03f,
|
||||
-1.00280075e-03f, -7.69022668e-04f, -5.30268510e-04f, -2.88586883e-04f, -4.60956253e-05f, 1.95186584e-04f,
|
||||
4.33161045e-04f, 6.65873263e-04f, 8.91328897e-04f, 1.10770620e-03f, 1.31316296e-03f, 1.50610067e-03f,
|
||||
1.68489795e-03f, 1.84814923e-03f, 1.99458512e-03f, 2.12304250e-03f, 2.23258384e-03f, 2.32237953e-03f,
|
||||
2.39181962e-03f, 2.44043032e-03f, 2.46796938e-03f, 2.47430968e-03f, 2.45957831e-03f, 2.42401283e-03f,
|
||||
2.36808884e-03f, 2.29238471e-03f, 2.19773378e-03f, 2.08501666e-03f, 1.95534528e-03f, 1.80993801e-03f,
|
||||
1.65014053e-03f, 1.47739854e-03f, 1.29329221e-03f, 1.09944593e-03f, 8.97596290e-04f, 6.89486470e-04f,
|
||||
4.76967544e-04f, 2.61847472e-04f, 4.59979030e-05f, -1.68770369e-04f, -3.80612759e-04f, -5.87744421e-04f,
|
||||
-7.88452414e-04f, -9.81081718e-04f, -1.16402219e-03f, -1.33580811e-03f, -1.49504859e-03f, -1.64047131e-03f,
|
||||
-1.77095587e-03f, -1.88548340e-03f, -1.98318254e-03f, -2.06335667e-03f, -2.12544333e-03f, -2.16903096e-03f,
|
||||
-2.19389731e-03f, -2.19994674e-03f, -2.18726700e-03f, -2.15609170e-03f, -2.10683457e-03f, -2.04002290e-03f,
|
||||
-1.95633800e-03f, -1.85665258e-03f, -1.74189023e-03f, -1.61313165e-03f, -1.47159921e-03f, -1.31856217e-03f,
|
||||
-1.15541374e-03f, -9.83590913e-04f, -8.04645529e-04f, -6.20138811e-04f, -4.31664744e-04f, -2.40859759e-04f,
|
||||
-4.93718861e-05f, 1.41183920e-04f, 3.29184443e-04f, 5.13049545e-04f, 6.91252710e-04f, 8.62329668e-04f,
|
||||
1.02486089e-03f, 1.17753306e-03f, 1.31912530e-03f, 1.44851584e-03f, 1.56468190e-03f, 1.66675270e-03f,
|
||||
1.75393226e-03f, 1.82562545e-03f, 1.88129935e-03f, 1.92062935e-03f, 1.94336360e-03f, 1.94946381e-03f,
|
||||
1.93898469e-03f, 1.91211060e-03f, 1.86925265e-03f, 1.81081128e-03f, 1.73745800e-03f, 1.64989979e-03f,
|
||||
1.54896085e-03f, 1.43565148e-03f, 1.31095906e-03f, 1.17607031e-03f, 1.03219054e-03f, 8.80596006e-04f,
|
||||
7.22634695e-04f, 5.59715925e-04f, 3.93223384e-04f, 2.24602808e-04f, 5.53223372e-05f, -1.13204206e-04f,
|
||||
-2.79527886e-04f, -4.42273875e-04f, -6.00090187e-04f, -7.51646708e-04f, -8.95738714e-04f, -1.03117771e-03f,
|
||||
-1.15687770e-03f, -1.27187587e-03f, -1.37523688e-03f, -1.46618576e-03f, -1.54403989e-03f, -1.60825931e-03f,
|
||||
-1.65836399e-03f, -1.69405240e-03f, -1.71514183e-03f, -1.72154028e-03f, -1.71331327e-03f, -1.69063272e-03f,
|
||||
-1.65381037e-03f, -1.60326168e-03f, -1.53948863e-03f, -1.46318779e-03f, -1.37503217e-03f, -1.27591969e-03f,
|
||||
-1.16672308e-03f, -1.04846883e-03f, -9.22232848e-04f, -7.89108246e-04f, -6.50329911e-04f, -5.07057241e-04f,
|
||||
-3.60579584e-04f, -2.12138548e-04f, -6.30166060e-05f, 8.55107333e-05f, 2.32212191e-04f, 3.75851456e-04f,
|
||||
5.15213418e-04f, 6.49182851e-04f, 7.76642588e-04f, 8.96585347e-04f, 1.00803198e-03f, 1.11010987e-03f,
|
||||
1.20203475e-03f, 1.28308439e-03f, 1.35268783e-03f, 1.41030687e-03f, 1.45558664e-03f, 1.48819124e-03f,
|
||||
1.50798717e-03f, 1.51486502e-03f, 1.50888467e-03f, 1.49022209e-03f, 1.45906012e-03f, 1.41583581e-03f,
|
||||
1.36095722e-03f, 1.29499749e-03f, 1.21859138e-03f, 1.13249419e-03f, 1.03745344e-03f, 9.34384957e-04f,
|
||||
8.24209226e-04f, 7.07921644e-04f, 5.86535461e-04f, 4.61118668e-04f, 3.32797940e-04f, 2.02615430e-04f,
|
||||
7.17560319e-05f, -5.87215139e-05f, -1.87700771e-04f, -3.14093799e-04f, -4.36855019e-04f, -5.54982470e-04f,
|
||||
-6.67514567e-04f, -7.73539543e-04f, -8.72216549e-04f, -9.62754726e-04f, -1.04446836e-03f, -1.11673823e-03f,
|
||||
-1.17901020e-03f, -1.23084835e-03f, -1.27191263e-03f, -1.30189831e-03f, -1.32066941e-03f, -1.32816613e-03f,
|
||||
-1.32437715e-03f, -1.30944714e-03f, -1.28360668e-03f, -1.24710492e-03f, -1.20038313e-03f, -1.14391116e-03f,
|
||||
-1.07822250e-03f, -1.00394823e-03f, -9.21799577e-04f, -8.32520513e-04f, -7.36916195e-04f, -6.35853312e-04f,
|
||||
-5.30218398e-04f, -4.20950684e-04f, -3.08981087e-04f, -1.95310152e-04f, -8.08721649e-05f, 3.33481785e-05f,
|
||||
1.46369769e-04f, 2.57271691e-04f, 3.65123878e-04f, 4.69053422e-04f, 5.68205019e-04f, 6.61777482e-04f,
|
||||
7.49035427e-04f, 8.29295760e-04f, 9.01919035e-04f, 9.66370937e-04f, 1.02218113e-03f, 1.06892877e-03f,
|
||||
1.10630552e-03f, 1.13406370e-03f, 1.15204451e-03f, 1.16019052e-03f, 1.15848806e-03f, 1.14706630e-03f,
|
||||
1.12606449e-03f, 1.09574589e-03f, 1.05645362e-03f, 1.00859266e-03f, 9.52601766e-04f, 8.89057609e-04f,
|
||||
8.18535938e-04f, 7.41697389e-04f, 6.59241262e-04f, 5.71884368e-04f, 4.80414698e-04f, 3.85677252e-04f,
|
||||
2.88406796e-04f, 1.89536836e-04f, 8.98491837e-05f, -9.79888746e-06f, -1.08531507e-04f, -2.05575498e-04f,
|
||||
-3.00092231e-04f, -3.91327952e-04f, -4.78537671e-04f, -5.61003964e-04f, -6.38090388e-04f, -7.09209697e-04f,
|
||||
-7.73747838e-04f, -8.31297964e-04f, -8.81364804e-04f, -9.23641236e-04f, -9.57793553e-04f, -9.83624619e-04f,
|
||||
-1.00098424e-03f, -1.00979404e-03f, -1.01003977e-03f, -1.00180772e-03f, -9.85219816e-04f, -9.60506778e-04f,
|
||||
-9.27905874e-04f, -8.87790902e-04f, -8.40553609e-04f, -7.86632276e-04f, -7.26559669e-04f, -6.60872173e-04f,
|
||||
-5.90177860e-04f, -5.15099219e-04f, -4.36341554e-04f, -3.54526447e-04f, -2.70436804e-04f, -1.84757234e-04f,
|
||||
-9.82406108e-05f, -1.16228429e-05f, 7.44116225e-05f, 1.59099493e-04f, 2.41739119e-04f, 3.21707034e-04f,
|
||||
3.98276352e-04f, 4.70887555e-04f, 5.38973046e-04f, 6.01940918e-04f, 6.59368174e-04f, 7.10783030e-04f,
|
||||
7.55802336e-04f, 7.94127086e-04f, 8.25478803e-04f, 8.49639386e-04f, 8.66487952e-04f, 8.75935969e-04f,
|
||||
8.77948893e-04f, 8.72611584e-04f, 8.59994515e-04f, 8.40271458e-04f, 8.13696181e-04f, 7.80491851e-04f,
|
||||
7.41053306e-04f, 6.95727202e-04f, 6.44936090e-04f, 5.89181503e-04f, 5.28946796e-04f, 4.64790448e-04f,
|
||||
3.97272420e-04f, 3.27000597e-04f, 2.54559578e-04f, 1.80597276e-04f, 1.05760446e-04f, 3.06209047e-05f,
|
||||
-4.41172003e-05f, -1.17884760e-04f, -1.90032814e-04f, -2.60000039e-04f, -3.27213235e-04f, -3.91110007e-04f,
|
||||
-4.51226928e-04f, -5.07042112e-04f, -5.58194586e-04f, -6.04189222e-04f, -6.44816381e-04f, -6.79653847e-04f,
|
||||
-7.08557315e-04f, -7.31282579e-04f, -7.47702169e-04f, -7.57731688e-04f, -7.61359812e-04f, -7.58589885e-04f,
|
||||
-7.49503361e-04f, -7.34226582e-04f, -7.12935677e-04f, -6.85882645e-04f, -6.53307567e-04f, -6.15569562e-04f,
|
||||
-5.72978650e-04f, -5.25977418e-04f, -4.74963705e-04f, -4.20426590e-04f, -3.62819514e-04f, -3.02647353e-04f,
|
||||
-2.40497241e-04f, -1.76810216e-04f, -1.12210871e-04f, -4.71976690e-05f, 1.76624641e-05f, 8.18440593e-05f,
|
||||
1.44804207e-04f, 2.06021410e-04f, 2.65025446e-04f, 3.21327783e-04f, 3.74487008e-04f, 4.24062432e-04f,
|
||||
4.69715655e-04f, 5.11042943e-04f, 5.47794530e-04f, 5.79655168e-04f, 6.06446384e-04f, 6.27934546e-04f,
|
||||
6.44010762e-04f, 6.54614698e-04f, 6.59636425e-04f, 6.59157826e-04f, 6.53158826e-04f, 6.41794049e-04f,
|
||||
6.25154916e-04f, 6.03470855e-04f, 5.76917242e-04f, 5.45789736e-04f, 5.10368292e-04f, 4.70998661e-04f,
|
||||
4.28021656e-04f, 3.81834126e-04f, 3.32863326e-04f, 2.81489629e-04f, 2.28231239e-04f, 1.73484261e-04f,
|
||||
1.17756607e-04f, 6.14881351e-05f, 5.17778269e-06f, -5.07352374e-05f, -1.05745987e-04f, -1.59454662e-04f,
|
||||
-2.11394268e-04f, -2.61151905e-04f, -3.08351703e-04f, -3.52598590e-04f, -3.93545002e-04f, -4.30916147e-04f,
|
||||
-4.64387406e-04f, -4.93756593e-04f, -5.18755281e-04f, -5.39265493e-04f, -5.55137934e-04f, -5.66259303e-04f,
|
||||
-5.72606783e-04f, -5.74140344e-04f, -5.70903292e-04f, -5.62934741e-04f, -5.50388898e-04f, -5.33351962e-04f,
|
||||
-5.12028510e-04f, -4.86612455e-04f, -4.57392981e-04f, -4.24578939e-04f, -3.88503808e-04f, -3.49487518e-04f,
|
||||
-3.07895836e-04f, -2.64036522e-04f, -2.18356445e-04f, -1.71198300e-04f, -1.22998901e-04f, -7.41392080e-05f,
|
||||
-2.50280393e-05f, 2.38852047e-05f, 7.22663332e-05f, 1.19659647e-04f, 1.65718806e-04f, 2.10055385e-04f,
|
||||
2.52324173e-04f, 2.92190427e-04f, 3.29337577e-04f, 3.63510150e-04f, 3.94385715e-04f, 4.21803288e-04f,
|
||||
4.45519433e-04f, 4.65391876e-04f, 4.81270460e-04f, 4.93057625e-04f, 5.00688030e-04f, 5.04121708e-04f,
|
||||
5.03379627e-04f, 4.98485604e-04f, 4.89499566e-04f, 4.76539317e-04f, 4.59760023e-04f, 4.39274612e-04f,
|
||||
4.15334876e-04f, 3.88103885e-04f, 3.57902146e-04f, 3.24908089e-04f, 2.89490480e-04f, 2.51922687e-04f,
|
||||
2.12512220e-04f, 1.71637404e-04f, 1.29609890e-04f, 8.67866183e-05f, 4.35312276e-05f, 1.98808307e-07f,
|
||||
-4.28589070e-05f, -8.52865394e-05f, -1.26765698e-04f, -1.66922292e-04f, -2.05456466e-04f, -2.42095652e-04f,
|
||||
-2.76487494e-04f, -3.08425602e-04f, -3.37638832e-04f, -3.63923042e-04f, -3.87022898e-04f, -4.06875144e-04f,
|
||||
-4.23245129e-04f, -4.36071615e-04f, -4.45236993e-04f, -4.50724682e-04f, -4.52491230e-04f, -4.50548104e-04f,
|
||||
-4.44936790e-04f, -4.35725612e-04f, -4.22987381e-04f, -4.06882738e-04f, -3.87548587e-04f, -3.65123104e-04f,
|
||||
-3.39860288e-04f, -3.11947486e-04f, -2.81618569e-04f, -2.49166817e-04f, -2.14824344e-04f, -1.78876370e-04f,
|
||||
-1.41684861e-04f, -1.03466427e-04f, -6.45996088e-05f, -2.53738050e-05f, 1.39035721e-05f, 5.28977578e-05f,
|
||||
9.13010773e-05f, 1.28809554e-04f, 1.65139924e-04f, 2.00005346e-04f, 2.33095696e-04f, 2.64232233e-04f,
|
||||
2.93070034e-04f, 3.19508024e-04f, 3.43252648e-04f, 3.64165224e-04f, 3.82074036e-04f, 3.96868082e-04f,
|
||||
4.08408250e-04f, 4.16671952e-04f, 4.21556517e-04f, 4.23035822e-04f, 4.21172111e-04f, 4.15928838e-04f,
|
||||
4.07377025e-04f, 3.95568598e-04f, 3.80628038e-04f, 3.62729177e-04f, 3.41921136e-04f, 3.18489958e-04f,
|
||||
2.92497406e-04f, 2.64266550e-04f, 2.33955571e-04f, 2.01809261e-04f, 1.68092145e-04f, 1.33141461e-04f,
|
||||
9.71043460e-05f, 6.03452880e-05f, 2.31264055e-05f, -1.43105089e-05f, -5.15607083e-05f, -8.84833364e-05f,
|
||||
-1.24679461e-04f, -1.59910519e-04f, -1.93952723e-04f, -2.26496145e-04f, -2.57307566e-04f, -2.86175538e-04f,
|
||||
-3.12853472e-04f, -3.37140613e-04f, -3.58914997e-04f, -3.77932329e-04f, -3.94117065e-04f, -4.07317063e-04f,
|
||||
-4.17422308e-04f, -4.24419479e-04f, -4.28161231e-04f, -4.28700484e-04f, -4.26016659e-04f, -4.20088126e-04f,
|
||||
-4.11009185e-04f, -3.98835037e-04f, -3.83585114e-04f, -3.65493072e-04f, -3.44616197e-04f, -3.21064387e-04f,
|
||||
-2.95119418e-04f, -2.66863117e-04f, -2.36549174e-04f, -2.04391686e-04f, -1.70585806e-04f, -1.35432614e-04f,
|
||||
-9.91006984e-05f, -6.19152828e-05f, -2.41012311e-05f, 1.40621144e-05f, 5.22867497e-05f, 9.03199843e-05f,
|
||||
1.27917614e-04f, 1.64740292e-04f, 2.00634478e-04f, 2.35261402e-04f, 2.68377430e-04f, 2.99818019e-04f,
|
||||
3.29273634e-04f, 3.56562766e-04f, 3.81532332e-04f, 4.03948113e-04f, 4.23655375e-04f, 4.40488930e-04f,
|
||||
4.54376777e-04f, 4.65137195e-04f, 4.72679704e-04f, 4.77014073e-04f, 4.77982201e-04f, 4.75625277e-04f,
|
||||
4.69878507e-04f, 4.60802987e-04f, 4.48367418e-04f, 4.32641679e-04f, 4.13709630e-04f, 3.91634147e-04f,
|
||||
3.66512902e-04f, 3.38481392e-04f, 3.07634938e-04f, 2.74189182e-04f, 2.38229594e-04f, 1.99985879e-04f,
|
||||
1.59632210e-04f, 1.17351364e-04f, 7.33404728e-05f, 2.78844831e-05f, -1.89099461e-05f, -6.67343638e-05f,
|
||||
-1.15367449e-04f, -1.64649983e-04f, -2.14224348e-04f, -2.64019844e-04f, -3.13654244e-04f, -3.62990333e-04f,
|
||||
-4.11800705e-04f, -4.59821928e-04f, -5.06946486e-04f, -5.52847863e-04f, -5.97397068e-04f, -6.40454770e-04f,
|
||||
-6.81765968e-04f, -7.21210131e-04f, -7.58634477e-04f, -7.93939572e-04f, -8.26964876e-04f, -8.57585335e-04f,
|
||||
-8.85733438e-04f, -9.11351007e-04f, -9.34300512e-04f, -9.54617442e-04f, -9.72159416e-04f, -9.87012089e-04f,
|
||||
-9.99095133e-04f, -1.00846242e-03f, -1.01506022e-03f, -1.01897105e-03f, -1.02021427e-03f, -1.01887259e-03f,
|
||||
-1.01497557e-03f, -1.00861358e-03f, -9.99877741e-04f, -9.88823136e-04f, -9.75617693e-04f, -9.60303769e-04f,
|
||||
-9.43035535e-04f, -9.23922797e-04f, -9.03105429e-04f, -8.80708716e-04f, -8.56853281e-04f, -8.31685264e-04f,
|
||||
-8.05348207e-04f, -7.77961627e-04f, -7.49713086e-04f, -7.20674604e-04f, -6.91032783e-04f, -6.60888020e-04f,
|
||||
-6.30372917e-04f, -5.99673349e-04f, -5.68830563e-04f, -5.38013304e-04f, -5.07353303e-04f, -4.76915043e-04f,
|
||||
-4.46832926e-04f, -4.17179291e-04f, -3.88083307e-04f, -3.59575024e-04f, -3.31820735e-04f, -3.04804303e-04f,
|
||||
-2.78616041e-04f, -2.53335964e-04f, -2.28986996e-04f, -2.05619529e-04f, -1.83318449e-04f, -1.61979425e-04f,
|
||||
-1.41791423e-04f, -1.22648816e-04f, -1.04625498e-04f, -8.77122910e-05f, -7.18653457e-05f, -5.71787106e-05f,
|
||||
-4.34807639e-05f, -3.09618857e-05f, -1.94074401e-05f, -8.88017971e-06f, 6.09625220e-07f, 9.14020334e-06f,
|
||||
1.67805558e-05f, 2.35369965e-05f, 2.94278194e-05f, 3.45049751e-05f, 3.88373828e-05f, 4.24291966e-05f,
|
||||
4.53445665e-05f, 4.76965834e-05f, 4.93395567e-05f, 5.05392111e-05f, 5.12257065e-05f, 5.14579340e-05f,
|
||||
5.12651750e-05f, 5.07312551e-05f, 4.98486765e-05f, 4.87082573e-05f, 4.73439631e-05f, 4.56740817e-05f,
|
||||
4.38653618e-05f, 4.19399075e-05f, 3.99125668e-05f, 3.77616021e-05f, 3.56135997e-05f, 3.33554815e-05f,
|
||||
3.11656899e-05f, 2.89038150e-05f, 2.67281634e-05f, 2.46192762e-05f, 2.24899205e-05f, 2.04698700e-05f,
|
||||
1.84927655e-05f, 1.66762886e-05f, 1.49393771e-05f, 1.32258081e-05f, 1.16985586e-05f, 1.01874391e-05f,
|
||||
8.99882100e-06f, 7.61267073e-06f, 6.57702907e-06f, 5.59829210e-06f, 4.27698546e-06f, 1.03248674e-05f,
|
||||
};
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "AudioRingBuffer.h"
|
||||
#include "AudioLogging.h"
|
||||
#include "AudioSRC.h"
|
||||
|
||||
#include "Sound.h"
|
||||
|
||||
QScriptValue soundSharedPointerToScriptValue(QScriptEngine* engine, const SharedSoundPointer& in) {
|
||||
|
@ -89,49 +91,22 @@ void Sound::downSample(const QByteArray& rawAudioByteArray) {
|
|||
// we want to convert it to the format that the audio-mixer wants
|
||||
// which is signed, 16-bit, 24Khz
|
||||
|
||||
int numSourceSamples = rawAudioByteArray.size() / sizeof(AudioConstants::AudioSample);
|
||||
int numChannels = _isStereo ? 2 : 1;
|
||||
AudioSRC resampler(48000, AudioConstants::SAMPLE_RATE, numChannels);
|
||||
|
||||
if (_isStereo && numSourceSamples % 2 != 0){
|
||||
// in the unlikely case that we have stereo audio but we seem to be missing a sample
|
||||
// (the sample for one channel is missing in a set of interleaved samples)
|
||||
// then drop the odd sample
|
||||
--numSourceSamples;
|
||||
}
|
||||
// resize to max possible output
|
||||
int numSourceFrames = rawAudioByteArray.size() / (numChannels * sizeof(AudioConstants::AudioSample));
|
||||
int maxDestinationFrames = resampler.getMaxOutput(numSourceFrames);
|
||||
int maxDestinationBytes = maxDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample);
|
||||
_byteArray.resize(maxDestinationBytes);
|
||||
|
||||
int numDestinationSamples = numSourceSamples / 2.0f;
|
||||
|
||||
if (_isStereo && numDestinationSamples % 2 != 0) {
|
||||
// if this is stereo we need to make sure we produce stereo output
|
||||
// which means we should have an even number of output samples
|
||||
numDestinationSamples += 1;
|
||||
}
|
||||
|
||||
int numDestinationBytes = numDestinationSamples * sizeof(AudioConstants::AudioSample);
|
||||
int numDestinationFrames = resampler.render((int16_t*)rawAudioByteArray.data(),
|
||||
(int16_t*)_byteArray.data(),
|
||||
numSourceFrames);
|
||||
|
||||
// truncate to actual output
|
||||
int numDestinationBytes = numDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample);
|
||||
_byteArray.resize(numDestinationBytes);
|
||||
|
||||
int16_t* sourceSamples = (int16_t*) rawAudioByteArray.data();
|
||||
int16_t* destinationSamples = (int16_t*) _byteArray.data();
|
||||
|
||||
if (_isStereo) {
|
||||
for (int i = 0; i < numSourceSamples; i += 4) {
|
||||
if (i + 2 >= numSourceSamples) {
|
||||
destinationSamples[i / 2] = sourceSamples[i];
|
||||
destinationSamples[(i / 2) + 1] = sourceSamples[i + 1];
|
||||
} else {
|
||||
destinationSamples[i / 2] = (sourceSamples[i] + sourceSamples[i + 2]) / 2;
|
||||
destinationSamples[(i / 2) + 1] = (sourceSamples[i + 1] + sourceSamples[i + 3]) / 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < numSourceSamples; i += 2) {
|
||||
if (i + 1 >= numSourceSamples) {
|
||||
destinationSamples[(i - 1) / 2] = (sourceSamples[i - 1] + sourceSamples[i]) / 2;
|
||||
} else {
|
||||
destinationSamples[(i - 1) / 2] = ((sourceSamples[i - 1] + sourceSamples[i + 1]) / 4) + (sourceSamples[i] / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
201
libraries/audio/src/avx2/AudioSRC_avx2.cpp
Normal file
201
libraries/audio/src/avx2/AudioSRC_avx2.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
//
|
||||
// AudioSRC_avx2.cpp
|
||||
// libraries/audio/src
|
||||
//
|
||||
// Created by Ken Cooke on 6/5/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
#include <assert.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "../AudioSRC.h"
|
||||
|
||||
#ifndef __AVX2__
|
||||
#error Must be compiled with /arch:AVX2 or -mavx2 -mfma.
|
||||
#endif
|
||||
|
||||
// high/low part of int64_t
|
||||
#define LO32(a) ((uint32_t)(a))
|
||||
#define HI32(a) ((int32_t)((a) >> 32))
|
||||
|
||||
int AudioSRC::multirateFilter1_AVX2(const float* input0, float* output0, int inputFrames) {
|
||||
int outputFrames = 0;
|
||||
|
||||
assert(_numTaps % 8 == 0); // SIMD8
|
||||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
const float* c0 = &_polyphaseFilter[_numTaps * _phase];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
|
||||
//float coef = c0[j];
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
}
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc0);
|
||||
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||
t0 = _mm_add_ps(t0, _mm_movehdup_ps(t0));
|
||||
|
||||
_mm_store_ss(&output0[outputFrames], t0);
|
||||
outputFrames += 1;
|
||||
|
||||
i += _stepTable[_phase];
|
||||
if (++_phase == _upFactor) {
|
||||
_phase = 0;
|
||||
}
|
||||
}
|
||||
_offset = (int64_t)(i - inputFrames) << 32;
|
||||
|
||||
} else { // irrational
|
||||
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
float ftmp = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT;
|
||||
|
||||
const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)];
|
||||
const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
__m256 frac = _mm256_broadcast_ss(&ftmp);
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
|
||||
//float coef = c0[j] + frac * (c1[j] - c0[j]);
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
__m256 coef1 = _mm256_loadu_ps(&c1[j]);
|
||||
coef1 = _mm256_sub_ps(coef1, coef0);
|
||||
coef0 = _mm256_fmadd_ps(coef1, frac, coef0);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
}
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc0);
|
||||
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||
t0 = _mm_add_ps(t0, _mm_movehdup_ps(t0));
|
||||
|
||||
_mm_store_ss(&output0[outputFrames], t0);
|
||||
outputFrames += 1;
|
||||
|
||||
_offset += _step;
|
||||
}
|
||||
_offset -= (int64_t)inputFrames << 32;
|
||||
}
|
||||
_mm256_zeroupper();
|
||||
|
||||
return outputFrames;
|
||||
}
|
||||
|
||||
int AudioSRC::multirateFilter2_AVX2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) {
|
||||
int outputFrames = 0;
|
||||
|
||||
assert(_numTaps % 8 == 0); // SIMD8
|
||||
|
||||
if (_step == 0) { // rational
|
||||
|
||||
int32_t i = HI32(_offset);
|
||||
|
||||
while (i < inputFrames) {
|
||||
|
||||
const float* c0 = &_polyphaseFilter[_numTaps * _phase];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
__m256 acc1 = _mm256_setzero_ps();
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
|
||||
//float coef = c0[j];
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input1[i + j]), coef0, acc1);
|
||||
}
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc1);
|
||||
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||
t0 = _mm_add_ps(t0, _mm_movehdup_ps(t0));
|
||||
|
||||
_mm_store_ss(&output0[outputFrames], t0);
|
||||
_mm_store_ss(&output1[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,2)));
|
||||
outputFrames += 1;
|
||||
|
||||
i += _stepTable[_phase];
|
||||
if (++_phase == _upFactor) {
|
||||
_phase = 0;
|
||||
}
|
||||
}
|
||||
_offset = (int64_t)(i - inputFrames) << 32;
|
||||
|
||||
} else { // irrational
|
||||
|
||||
while (HI32(_offset) < inputFrames) {
|
||||
|
||||
int32_t i = HI32(_offset);
|
||||
uint32_t f = LO32(_offset);
|
||||
|
||||
uint32_t phase = f >> SRC_FRACBITS;
|
||||
float ftmp = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT;
|
||||
|
||||
const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)];
|
||||
const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
__m256 acc1 = _mm256_setzero_ps();
|
||||
__m256 frac = _mm256_broadcast_ss(&ftmp);
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
|
||||
//float coef = c0[j] + frac * (c1[j] - c0[j]);
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
__m256 coef1 = _mm256_loadu_ps(&c1[j]);
|
||||
coef1 = _mm256_sub_ps(coef1, coef0);
|
||||
coef0 = _mm256_fmadd_ps(coef1, frac, coef0);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input1[i + j]), coef0, acc1);
|
||||
}
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc1);
|
||||
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||
t0 = _mm_add_ps(t0, _mm_movehdup_ps(t0));
|
||||
|
||||
_mm_store_ss(&output0[outputFrames], t0);
|
||||
_mm_store_ss(&output1[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,2)));
|
||||
outputFrames += 1;
|
||||
|
||||
_offset += _step;
|
||||
}
|
||||
_offset -= (int64_t)inputFrames << 32;
|
||||
}
|
||||
_mm256_zeroupper();
|
||||
|
||||
return outputFrames;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -632,13 +632,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
#endif
|
||||
|
||||
int numBytesRead = sourceBuffer - startPosition;
|
||||
|
||||
if (numBytesRead != buffer.size()) {
|
||||
if (shouldLogError(now)) {
|
||||
qCWarning(avatars) << "AvatarData packet size mismatch: expected " << numBytesRead << " received " << buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
_averageBytesReceived.updateAverage(numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
|
@ -1270,6 +1263,10 @@ static const QString JSON_AVATAR_DISPLAY_NAME = QStringLiteral("displayName");
|
|||
static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments");
|
||||
static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities");
|
||||
static const QString JSON_AVATAR_SCALE = QStringLiteral("scale");
|
||||
static const QString JSON_AVATAR_VERSION = QStringLiteral("version");
|
||||
|
||||
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION = 0;
|
||||
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION = 1;
|
||||
|
||||
QJsonValue toJsonValue(const JointData& joint) {
|
||||
QJsonArray result;
|
||||
|
@ -1293,6 +1290,8 @@ JointData jointDataFromJsonValue(const QJsonValue& json) {
|
|||
QJsonObject AvatarData::toJson() const {
|
||||
QJsonObject root;
|
||||
|
||||
root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION;
|
||||
|
||||
if (!getSkeletonModelURL().isEmpty()) {
|
||||
root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString();
|
||||
}
|
||||
|
@ -1359,6 +1358,15 @@ QJsonObject AvatarData::toJson() const {
|
|||
}
|
||||
|
||||
void AvatarData::fromJson(const QJsonObject& json) {
|
||||
|
||||
int version;
|
||||
if (json.contains(JSON_AVATAR_VERSION)) {
|
||||
version = json[JSON_AVATAR_VERSION].toInt();
|
||||
} else {
|
||||
// initial data did not have a version field.
|
||||
version = JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION;
|
||||
}
|
||||
|
||||
// The head setOrientation likes to overwrite the avatar orientation,
|
||||
// so lets do the head first
|
||||
// Most head data is relative to the avatar, and needs no basis correction,
|
||||
|
@ -1424,20 +1432,28 @@ void AvatarData::fromJson(const QJsonObject& json) {
|
|||
// }
|
||||
// }
|
||||
|
||||
// Joint rotations are relative to the avatar, so they require no basis correction
|
||||
if (json.contains(JSON_AVATAR_JOINT_ARRAY)) {
|
||||
QVector<JointData> jointArray;
|
||||
QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray();
|
||||
jointArray.reserve(jointArrayJson.size());
|
||||
int i = 0;
|
||||
for (const auto& jointJson : jointArrayJson) {
|
||||
auto joint = jointDataFromJsonValue(jointJson);
|
||||
jointArray.push_back(joint);
|
||||
setJointData(i, joint.rotation, joint.translation);
|
||||
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
|
||||
i++;
|
||||
if (version == JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION) {
|
||||
// because we don't have the full joint hierarchy skeleton of the model,
|
||||
// we can't properly convert from relative rotations into absolute rotations.
|
||||
quint64 now = usecTimestampNow();
|
||||
if (shouldLogError(now)) {
|
||||
qCWarning(avatars) << "Version 0 avatar recordings not supported. using default rotations";
|
||||
}
|
||||
} else {
|
||||
QVector<JointData> jointArray;
|
||||
QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray();
|
||||
jointArray.reserve(jointArrayJson.size());
|
||||
int i = 0;
|
||||
for (const auto& jointJson : jointArrayJson) {
|
||||
auto joint = jointDataFromJsonValue(jointJson);
|
||||
jointArray.push_back(joint);
|
||||
setJointData(i, joint.rotation, joint.translation);
|
||||
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
|
||||
i++;
|
||||
}
|
||||
setRawJointData(jointArray);
|
||||
}
|
||||
setRawJointData(jointArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,6 @@ HeadData::HeadData(AvatarData* owningAvatar) :
|
|||
_baseYaw(0.0f),
|
||||
_basePitch(0.0f),
|
||||
_baseRoll(0.0f),
|
||||
_leanSideways(0.0f),
|
||||
_leanForward(0.0f),
|
||||
_torsoTwist(0.0f),
|
||||
_lookAtPosition(0.0f, 0.0f, 0.0f),
|
||||
_audioLoudness(0.0f),
|
||||
_isFaceTrackerConnected(false),
|
||||
|
@ -132,12 +129,6 @@ QJsonObject HeadData::toJson() const {
|
|||
if (getRawOrientation() != quat()) {
|
||||
headJson[JSON_AVATAR_HEAD_ROTATION] = toJsonValue(getRawOrientation());
|
||||
}
|
||||
if (getLeanForward() != 0.0f) {
|
||||
headJson[JSON_AVATAR_HEAD_LEAN_FORWARD] = getLeanForward();
|
||||
}
|
||||
if (getLeanSideways() != 0.0f) {
|
||||
headJson[JSON_AVATAR_HEAD_LEAN_SIDEWAYS] = getLeanSideways();
|
||||
}
|
||||
auto lookat = getLookAtPosition();
|
||||
if (lookat != vec3()) {
|
||||
vec3 relativeLookAt = glm::inverse(_owningAvatar->getOrientation()) *
|
||||
|
@ -171,12 +162,6 @@ void HeadData::fromJson(const QJsonObject& json) {
|
|||
if (json.contains(JSON_AVATAR_HEAD_ROTATION)) {
|
||||
setOrientation(quatFromJsonValue(json[JSON_AVATAR_HEAD_ROTATION]));
|
||||
}
|
||||
if (json.contains(JSON_AVATAR_HEAD_LEAN_FORWARD)) {
|
||||
setLeanForward((float)json[JSON_AVATAR_HEAD_LEAN_FORWARD].toDouble());
|
||||
}
|
||||
if (json.contains(JSON_AVATAR_HEAD_LEAN_SIDEWAYS)) {
|
||||
setLeanSideways((float)json[JSON_AVATAR_HEAD_LEAN_SIDEWAYS].toDouble());
|
||||
}
|
||||
|
||||
if (json.contains(JSON_AVATAR_HEAD_LOOKAT)) {
|
||||
auto relativeLookAt = vec3FromJsonValue(json[JSON_AVATAR_HEAD_LOOKAT]);
|
||||
|
|
|
@ -68,17 +68,6 @@ public:
|
|||
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
|
||||
void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; }
|
||||
|
||||
|
||||
float getLeanSideways() const { return _leanSideways; }
|
||||
float getLeanForward() const { return _leanForward; }
|
||||
float getTorsoTwist() const { return _torsoTwist; }
|
||||
virtual float getFinalLeanSideways() const { return _leanSideways; }
|
||||
virtual float getFinalLeanForward() const { return _leanForward; }
|
||||
|
||||
void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; }
|
||||
void setLeanForward(float leanForward) { _leanForward = leanForward; }
|
||||
void setTorsoTwist(float torsoTwist) { _torsoTwist = torsoTwist; }
|
||||
|
||||
friend class AvatarData;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
|
@ -89,9 +78,6 @@ protected:
|
|||
float _baseYaw;
|
||||
float _basePitch;
|
||||
float _baseRoll;
|
||||
float _leanSideways;
|
||||
float _leanForward;
|
||||
float _torsoTwist;
|
||||
|
||||
glm::vec3 _lookAtPosition;
|
||||
float _audioLoudness;
|
||||
|
|
|
@ -31,6 +31,12 @@ namespace controller {
|
|||
class Endpoint;
|
||||
using EndpointPointer = std::shared_ptr<Endpoint>;
|
||||
|
||||
enum Hand {
|
||||
LEFT = 0,
|
||||
RIGHT,
|
||||
BOTH
|
||||
};
|
||||
|
||||
// NOTE: If something inherits from both InputDevice and InputPlugin, InputPlugin must go first.
|
||||
// e.g. class Example : public InputPlugin, public InputDevice
|
||||
// instead of class Example : public InputDevice, public InputPlugin
|
||||
|
@ -55,6 +61,9 @@ public:
|
|||
|
||||
const QString& getName() const { return _name; }
|
||||
|
||||
// By default, Input Devices do not support haptics
|
||||
virtual bool triggerHapticPulse(float strength, float duration, controller::Hand hand) { return false; }
|
||||
|
||||
// Update call MUST be called once per simulation loop
|
||||
// It takes care of updating the action states and deltas
|
||||
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData) {};
|
||||
|
|
|
@ -140,6 +140,24 @@ namespace controller {
|
|||
return DependencyManager::get<UserInputMapper>()->getActionNames();
|
||||
}
|
||||
|
||||
bool ScriptingInterface::triggerHapticPulse(float strength, float duration, controller::Hand hand) const {
|
||||
return DependencyManager::get<UserInputMapper>()->triggerHapticPulse(strength, duration, hand);
|
||||
}
|
||||
|
||||
bool ScriptingInterface::triggerShortHapticPulse(float strength, controller::Hand hand) const {
|
||||
const float SHORT_HAPTIC_DURATION_MS = 250.0f;
|
||||
return DependencyManager::get<UserInputMapper>()->triggerHapticPulse(strength, SHORT_HAPTIC_DURATION_MS, hand);
|
||||
}
|
||||
|
||||
bool ScriptingInterface::triggerHapticPulseOnDevice(unsigned int device, float strength, float duration, controller::Hand hand) const {
|
||||
return DependencyManager::get<UserInputMapper>()->triggerHapticPulseOnDevice(device, strength, duration, hand);
|
||||
}
|
||||
|
||||
bool ScriptingInterface::triggerShortHapticPulseOnDevice(unsigned int device, float strength, controller::Hand hand) const {
|
||||
const float SHORT_HAPTIC_DURATION_MS = 250.0f;
|
||||
return DependencyManager::get<UserInputMapper>()->triggerHapticPulseOnDevice(device, strength, SHORT_HAPTIC_DURATION_MS, hand);
|
||||
}
|
||||
|
||||
void ScriptingInterface::updateMaps() {
|
||||
QVariantMap newHardware;
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
|
|
|
@ -84,6 +84,11 @@ namespace controller {
|
|||
Q_INVOKABLE Pose getPoseValue(const int& source) const;
|
||||
Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const;
|
||||
|
||||
Q_INVOKABLE bool triggerHapticPulse(float strength, float duration, controller::Hand hand = BOTH) const;
|
||||
Q_INVOKABLE bool triggerShortHapticPulse(float strength, controller::Hand hand = BOTH) const;
|
||||
Q_INVOKABLE bool triggerHapticPulseOnDevice(unsigned int device, float strength, float duration, controller::Hand hand = BOTH) const;
|
||||
Q_INVOKABLE bool triggerShortHapticPulseOnDevice(unsigned int device, float strength, controller::Hand hand = BOTH) const;
|
||||
|
||||
Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString());
|
||||
Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true);
|
||||
Q_INVOKABLE void disableMapping(const QString& mappingName) { enableMapping(mappingName, false); }
|
||||
|
|
|
@ -66,9 +66,7 @@ namespace controller {
|
|||
RIGHT_SECONDARY_INDEX_TOUCH,
|
||||
RIGHT_INDEX_POINT,
|
||||
|
||||
LEFT_GRIP,
|
||||
LEFT_GRIP_TOUCH,
|
||||
RIGHT_GRIP,
|
||||
RIGHT_GRIP_TOUCH,
|
||||
|
||||
NUM_STANDARD_BUTTONS
|
||||
|
@ -85,9 +83,9 @@ namespace controller {
|
|||
// Triggers
|
||||
LT,
|
||||
RT,
|
||||
// Grips (Oculus touch squeeze)
|
||||
LG,
|
||||
RG,
|
||||
// Grips
|
||||
LEFT_GRIP,
|
||||
RIGHT_GRIP,
|
||||
NUM_STANDARD_AXES,
|
||||
LZ = LT,
|
||||
RZ = RT
|
||||
|
|
|
@ -62,14 +62,6 @@ namespace controller {
|
|||
UserInputMapper::~UserInputMapper() {
|
||||
}
|
||||
|
||||
int UserInputMapper::recordDeviceOfType(const QString& deviceName) {
|
||||
if (!_deviceCounts.contains(deviceName)) {
|
||||
_deviceCounts[deviceName] = 0;
|
||||
}
|
||||
_deviceCounts[deviceName] += 1;
|
||||
return _deviceCounts[deviceName];
|
||||
}
|
||||
|
||||
void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||
Locker locker(_lock);
|
||||
if (device->_deviceID == Input::INVALID_DEVICE) {
|
||||
|
@ -77,8 +69,6 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
|||
}
|
||||
const auto& deviceID = device->_deviceID;
|
||||
|
||||
recordDeviceOfType(device->getName());
|
||||
|
||||
qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID;
|
||||
|
||||
for (const auto& inputMapping : device->getAvailableInputs()) {
|
||||
|
@ -134,6 +124,15 @@ void UserInputMapper::removeDevice(int deviceID) {
|
|||
_mappingsByDevice.erase(mappingsEntry);
|
||||
}
|
||||
|
||||
for (const auto& inputMapping : device->getAvailableInputs()) {
|
||||
const auto& input = inputMapping.first;
|
||||
auto endpoint = _endpointsByInput.find(input);
|
||||
if (endpoint != _endpointsByInput.end()) {
|
||||
_inputsByEndpoint.erase((*endpoint).second);
|
||||
_endpointsByInput.erase(input);
|
||||
}
|
||||
}
|
||||
|
||||
_registeredDevices.erase(proxyEntry);
|
||||
|
||||
emit hardwareChanged();
|
||||
|
@ -336,10 +335,28 @@ QVector<QString> UserInputMapper::getActionNames() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool UserInputMapper::triggerHapticPulse(float strength, float duration, controller::Hand hand) {
|
||||
Locker locker(_lock);
|
||||
bool toReturn = false;
|
||||
for (auto device : _registeredDevices) {
|
||||
toReturn = toReturn || device.second->triggerHapticPulse(strength, duration, hand);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
bool UserInputMapper::triggerHapticPulseOnDevice(uint16 deviceID, float strength, float duration, controller::Hand hand) {
|
||||
Locker locker(_lock);
|
||||
if (_registeredDevices.find(deviceID) != _registeredDevices.end()) {
|
||||
return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, hand);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int actionMetaTypeId = qRegisterMetaType<Action>();
|
||||
int inputMetaTypeId = qRegisterMetaType<Input>();
|
||||
int inputPairMetaTypeId = qRegisterMetaType<Input::NamedPair>();
|
||||
int poseMetaTypeId = qRegisterMetaType<controller::Pose>("Pose");
|
||||
int handMetaTypeId = qRegisterMetaType<controller::Hand>();
|
||||
|
||||
QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input);
|
||||
void inputFromScriptValue(const QScriptValue& object, Input& input);
|
||||
|
@ -347,6 +364,8 @@ QScriptValue actionToScriptValue(QScriptEngine* engine, const Action& action);
|
|||
void actionFromScriptValue(const QScriptValue& object, Action& action);
|
||||
QScriptValue inputPairToScriptValue(QScriptEngine* engine, const Input::NamedPair& inputPair);
|
||||
void inputPairFromScriptValue(const QScriptValue& object, Input::NamedPair& inputPair);
|
||||
QScriptValue handToScriptValue(QScriptEngine* engine, const controller::Hand& hand);
|
||||
void handFromScriptValue(const QScriptValue& object, controller::Hand& hand);
|
||||
|
||||
QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
|
@ -385,12 +404,21 @@ void inputPairFromScriptValue(const QScriptValue& object, Input::NamedPair& inpu
|
|||
inputPair.second = QString(object.property("inputName").toVariant().toString());
|
||||
}
|
||||
|
||||
QScriptValue handToScriptValue(QScriptEngine* engine, const controller::Hand& hand) {
|
||||
return engine->newVariant((int)hand);
|
||||
}
|
||||
|
||||
void handFromScriptValue(const QScriptValue& object, controller::Hand& hand) {
|
||||
hand = Hand(object.toVariant().toInt());
|
||||
}
|
||||
|
||||
void UserInputMapper::registerControllerTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterSequenceMetaType<QVector<Action> >(engine);
|
||||
qScriptRegisterSequenceMetaType<Input::NamedVector>(engine);
|
||||
qScriptRegisterMetaType(engine, actionToScriptValue, actionFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, inputToScriptValue, inputFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, inputPairToScriptValue, inputPairFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, handToScriptValue, handFromScriptValue);
|
||||
|
||||
qScriptRegisterMetaType(engine, Pose::toScriptValue, Pose::fromScriptValue);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,8 @@ namespace controller {
|
|||
void setActionState(Action action, float value) { _actionStates[toInt(action)] = value; }
|
||||
void deltaActionState(Action action, float delta) { _actionStates[toInt(action)] += delta; }
|
||||
void setActionState(Action action, const Pose& value) { _poseStates[toInt(action)] = value; }
|
||||
bool triggerHapticPulse(float strength, float duration, controller::Hand hand);
|
||||
bool triggerHapticPulseOnDevice(uint16 deviceID, float strength, float duration, controller::Hand hand);
|
||||
|
||||
static Input makeStandardInput(controller::StandardButtonChannel button);
|
||||
static Input makeStandardInput(controller::StandardAxisChannel axis);
|
||||
|
@ -141,9 +143,6 @@ namespace controller {
|
|||
std::vector<Pose> _poseStates = std::vector<Pose>(toInt(Action::NUM_ACTIONS));
|
||||
std::vector<float> _lastStandardStates = std::vector<float>();
|
||||
|
||||
int recordDeviceOfType(const QString& deviceName);
|
||||
QHash<const QString&, int> _deviceCounts;
|
||||
|
||||
static float getValue(const EndpointPointer& endpoint, bool peek = false);
|
||||
static Pose getPose(const EndpointPointer& endpoint, bool peek = false);
|
||||
|
||||
|
@ -199,6 +198,7 @@ Q_DECLARE_METATYPE(QVector<controller::Input::NamedPair>)
|
|||
Q_DECLARE_METATYPE(controller::Input)
|
||||
Q_DECLARE_METATYPE(controller::Action)
|
||||
Q_DECLARE_METATYPE(QVector<controller::Action>)
|
||||
Q_DECLARE_METATYPE(controller::Hand)
|
||||
|
||||
// Cheating.
|
||||
using UserInputMapper = controller::UserInputMapper;
|
||||
|
|
|
@ -599,11 +599,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
|||
|
||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
ShapeType type = getShapeType();
|
||||
if (type != SHAPE_TYPE_COMPOUND) {
|
||||
ModelEntityItem::computeShapeInfo(info);
|
||||
info.setParams(type, 0.5f * getDimensions());
|
||||
adjustShapeInfoByRegistration(info);
|
||||
} else {
|
||||
if (type == SHAPE_TYPE_COMPOUND) {
|
||||
updateModelBounds();
|
||||
|
||||
// should never fall in here when collision model not fully loaded
|
||||
|
@ -612,25 +608,27 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
const FBXGeometry& renderGeometry = _model->getFBXGeometry();
|
||||
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
|
||||
|
||||
_points.clear();
|
||||
unsigned int i = 0;
|
||||
QVector<QVector<glm::vec3>>& points = info.getPoints();
|
||||
points.clear();
|
||||
uint32_t i = 0;
|
||||
|
||||
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
|
||||
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
||||
const uint32_t TRIANGLE_STRIDE = 3;
|
||||
const uint32_t QUAD_STRIDE = 4;
|
||||
foreach (const FBXMesh& mesh, collisionGeometry.meshes) {
|
||||
// each meshPart is a convex hull
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
QVector<glm::vec3> pointsInPart;
|
||||
points.push_back(QVector<glm::vec3>());
|
||||
QVector<glm::vec3>& pointsInPart = points[i];
|
||||
|
||||
// run through all the triangles and (uniquely) add each point to the hull
|
||||
unsigned int triangleCount = meshPart.triangleIndices.size() / 3;
|
||||
for (unsigned int j = 0; j < triangleCount; j++) {
|
||||
unsigned int p0Index = meshPart.triangleIndices[j*3];
|
||||
unsigned int p1Index = meshPart.triangleIndices[j*3+1];
|
||||
unsigned int p2Index = meshPart.triangleIndices[j*3+2];
|
||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
||||
uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size();
|
||||
assert(numIndices % TRIANGLE_STRIDE == 0);
|
||||
for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) {
|
||||
glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]];
|
||||
glm::vec3 p1 = mesh.vertices[meshPart.triangleIndices[j + 1]];
|
||||
glm::vec3 p2 = mesh.vertices[meshPart.triangleIndices[j + 2]];
|
||||
if (!pointsInPart.contains(p0)) {
|
||||
pointsInPart << p0;
|
||||
}
|
||||
|
@ -643,17 +641,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
}
|
||||
|
||||
// run through all the quads and (uniquely) add each point to the hull
|
||||
unsigned int quadCount = meshPart.quadIndices.size() / 4;
|
||||
assert((unsigned int)meshPart.quadIndices.size() == quadCount*4);
|
||||
for (unsigned int j = 0; j < quadCount; j++) {
|
||||
unsigned int p0Index = meshPart.quadIndices[j*4];
|
||||
unsigned int p1Index = meshPart.quadIndices[j*4+1];
|
||||
unsigned int p2Index = meshPart.quadIndices[j*4+2];
|
||||
unsigned int p3Index = meshPart.quadIndices[j*4+3];
|
||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
||||
glm::vec3 p3 = mesh.vertices[p3Index];
|
||||
numIndices = (uint32_t)meshPart.quadIndices.size();
|
||||
assert(numIndices % QUAD_STRIDE == 0);
|
||||
for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) {
|
||||
glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]];
|
||||
glm::vec3 p1 = mesh.vertices[meshPart.quadIndices[j + 1]];
|
||||
glm::vec3 p2 = mesh.vertices[meshPart.quadIndices[j + 2]];
|
||||
glm::vec3 p3 = mesh.vertices[meshPart.quadIndices[j + 3]];
|
||||
if (!pointsInPart.contains(p0)) {
|
||||
pointsInPart << p0;
|
||||
}
|
||||
|
@ -670,14 +664,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
|
||||
if (pointsInPart.size() == 0) {
|
||||
qCDebug(entitiesrenderer) << "Warning -- meshPart has no faces";
|
||||
points.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
// add next convex hull
|
||||
QVector<glm::vec3> newMeshPoints;
|
||||
_points << newMeshPoints;
|
||||
// add points to the new convex hull
|
||||
_points[i++] << pointsInPart;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,23 +681,26 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
// multiply each point by scale before handing the point-set off to the physics engine.
|
||||
// also determine the extents of the collision model.
|
||||
AABox box;
|
||||
for (int i = 0; i < _points.size(); i++) {
|
||||
for (int j = 0; j < _points[i].size(); j++) {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
for (int j = 0; j < points[i].size(); j++) {
|
||||
// compensate for registration
|
||||
_points[i][j] += _model->getOffset();
|
||||
points[i][j] += _model->getOffset();
|
||||
// scale so the collision points match the model points
|
||||
_points[i][j] *= scale;
|
||||
points[i][j] *= scale;
|
||||
// this next subtraction is done so we can give info the offset, which will cause
|
||||
// the shape-key to change.
|
||||
_points[i][j] -= _model->getOffset();
|
||||
box += _points[i][j];
|
||||
points[i][j] -= _model->getOffset();
|
||||
box += points[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 collisionModelDimensions = box.getDimensions();
|
||||
info.setParams(type, collisionModelDimensions, _compoundShapeURL);
|
||||
info.setConvexHulls(_points);
|
||||
info.setOffset(_model->getOffset());
|
||||
} else {
|
||||
ModelEntityItem::computeShapeInfo(info);
|
||||
info.setParams(type, 0.5f * getDimensions());
|
||||
adjustShapeInfoByRegistration(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,6 @@ private:
|
|||
QVariantMap _currentTextures;
|
||||
QVariantMap _originalTextures;
|
||||
bool _originalTexturesRead = false;
|
||||
QVector<QVector<glm::vec3>> _points;
|
||||
bool _dimensionsInitialized = true;
|
||||
|
||||
AnimationPropertyGroup _renderAnimationProperties;
|
||||
|
|
|
@ -226,10 +226,15 @@ void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
|||
}
|
||||
|
||||
void RenderableWebEntityItem::setProxyWindow(QWindow* proxyWindow) {
|
||||
_webSurface->setProxyWindow(proxyWindow);
|
||||
if (_webSurface) {
|
||||
_webSurface->setProxyWindow(proxyWindow);
|
||||
}
|
||||
}
|
||||
|
||||
QObject* RenderableWebEntityItem::getEventHandler() {
|
||||
if (!_webSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
return _webSurface->getEventHandler();
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ void EntityItemProperties::setLastEdited(quint64 usecTime) {
|
|||
_lastEdited = usecTime > _created ? usecTime : _created;
|
||||
}
|
||||
|
||||
const char* shapeTypeNames[] = {"none", "box", "sphere", "ellipsoid", "plane", "compound", "capsule-x",
|
||||
const char* shapeTypeNames[] = {"none", "box", "sphere", "plane", "compound", "capsule-x",
|
||||
"capsule-y", "capsule-z", "cylinder-x", "cylinder-y", "cylinder-z"};
|
||||
|
||||
QHash<QString, ShapeType> stringToShapeTypeLookup;
|
||||
|
@ -101,7 +101,6 @@ void buildStringToShapeTypeLookup() {
|
|||
addShapeType(SHAPE_TYPE_NONE);
|
||||
addShapeType(SHAPE_TYPE_BOX);
|
||||
addShapeType(SHAPE_TYPE_SPHERE);
|
||||
addShapeType(SHAPE_TYPE_ELLIPSOID);
|
||||
addShapeType(SHAPE_TYPE_PLANE);
|
||||
addShapeType(SHAPE_TYPE_COMPOUND);
|
||||
addShapeType(SHAPE_TYPE_CAPSULE_X);
|
||||
|
|
|
@ -1121,6 +1121,27 @@ QStringList EntityScriptingInterface::getJointNames(const QUuid& entityID) {
|
|||
return result;
|
||||
}
|
||||
|
||||
QVector<QUuid> EntityScriptingInterface::getChildrenIDs(const QUuid& parentID) {
|
||||
QVector<QUuid> result;
|
||||
if (!_entityTree) {
|
||||
return result;
|
||||
}
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(parentID);
|
||||
if (!entity) {
|
||||
qDebug() << "EntityScriptingInterface::getChildrenIDs - no entity with ID" << parentID;
|
||||
return result;
|
||||
}
|
||||
|
||||
_entityTree->withReadLock([&] {
|
||||
entity->forEachChild([&](SpatiallyNestablePointer child) {
|
||||
result.push_back(child->getID());
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<QUuid> EntityScriptingInterface::getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex) {
|
||||
QVector<QUuid> result;
|
||||
if (!_entityTree) {
|
||||
|
|
|
@ -171,6 +171,7 @@ public slots:
|
|||
|
||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name);
|
||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID);
|
||||
Q_INVOKABLE QVector<QUuid> getChildrenIDs(const QUuid& parentID);
|
||||
Q_INVOKABLE QVector<QUuid> getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -1284,6 +1284,7 @@ class ContentsDimensionOperator : public RecurseOctreeOperator {
|
|||
public:
|
||||
virtual bool preRecursion(OctreeElementPointer element);
|
||||
virtual bool postRecursion(OctreeElementPointer element) { return true; }
|
||||
glm::vec3 getDimensions() const { return _contentExtents.size(); }
|
||||
float getLargestDimension() const { return _contentExtents.largestDimension(); }
|
||||
private:
|
||||
Extents _contentExtents;
|
||||
|
@ -1295,6 +1296,12 @@ bool ContentsDimensionOperator::preRecursion(OctreeElementPointer element) {
|
|||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 EntityTree::getContentsDimensions() {
|
||||
ContentsDimensionOperator theOperator;
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
return theOperator.getDimensions();
|
||||
}
|
||||
|
||||
float EntityTree::getContentsLargestDimension() {
|
||||
ContentsDimensionOperator theOperator;
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
|
|
|
@ -207,6 +207,7 @@ public:
|
|||
bool skipThoseWithBadParents) override;
|
||||
virtual bool readFromMap(QVariantMap& entityDescription) override;
|
||||
|
||||
glm::vec3 getContentsDimensions();
|
||||
float getContentsLargestDimension();
|
||||
|
||||
virtual void resetEditStats() override {
|
||||
|
|
|
@ -55,7 +55,7 @@ void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) cons
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
qCDebug(entities) << " encode data:" << entityTreeElementExtraEncodeData;
|
||||
} else {
|
||||
qCDebug(entities) << " encode data: MISSING!!";
|
||||
|
@ -97,7 +97,7 @@ bool EntityTreeElement::shouldIncludeChildData(int childIndex, EncodeBitstreamPa
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
bool childCompleted = entityTreeElementExtraEncodeData->childCompleted[childIndex];
|
||||
|
||||
|
@ -126,7 +126,7 @@ bool EntityTreeElement::alreadyFullyEncoded(EncodeBitstreamParams& params) const
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
// If we know that ALL subtrees below us have already been recursed, then we don't
|
||||
// need to recurse this child.
|
||||
|
@ -140,7 +140,7 @@ void EntityTreeElement::updateEncodedData(int childIndex, AppendState childAppen
|
|||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
if (childAppendState == OctreeElement::COMPLETED) {
|
||||
entityTreeElementExtraEncodeData->childCompleted[childIndex] = true;
|
||||
|
@ -165,7 +165,7 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params) con
|
|||
assert(extraEncodeData->contains(this));
|
||||
|
||||
EntityTreeElementExtraEncodeData* thisExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
// Note: this will be called when OUR element has finished running through encodeTreeBitstreamRecursion()
|
||||
// which means, it's possible that our parent element hasn't finished encoding OUR data... so
|
||||
|
@ -241,7 +241,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
bool hadElementExtraData = false;
|
||||
if (extraEncodeData && extraEncodeData->contains(this)) {
|
||||
entityTreeElementExtraEncodeData =
|
||||
static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
hadElementExtraData = true;
|
||||
} else {
|
||||
// if there wasn't one already, then create one
|
||||
|
@ -268,7 +268,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
|
||||
//assert(extraEncodeData);
|
||||
//assert(extraEncodeData->contains(this));
|
||||
//entityTreeElementExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
//entityTreeElementExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
LevelDetails elementLevel = packetData->startLevel();
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class LineEntityItem : public EntityItem {
|
|||
|
||||
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
|
||||
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||
|
||||
// never have a ray intersection pick a LineEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
|
|
|
@ -78,7 +78,7 @@ class PolyLineEntityItem : public EntityItem {
|
|||
|
||||
virtual bool needsToCallUpdate() const { return true; }
|
||||
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||
|
||||
// never have a ray intersection pick a PolyLineEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
|
|
|
@ -759,7 +759,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
|
||||
model.preRotation = glm::quat(glm::radians(preRotation));
|
||||
model.rotation = glm::quat(glm::radians(rotation));
|
||||
model.postRotation = glm::quat(glm::radians(postRotation));
|
||||
model.postRotation = glm::inverse(glm::quat(glm::radians(postRotation)));
|
||||
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scaleOffset) *
|
||||
glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot);
|
||||
// NOTE: angles from the FBX file are in degrees
|
||||
|
@ -927,6 +927,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
// material.emissiveColor = getVec3(property.properties, index);
|
||||
// material.emissiveFactor = 1.0;
|
||||
|
||||
} else if (property.properties.at(0) == "AmbientFactor") {
|
||||
material.ambientFactor = property.properties.at(index).value<double>();
|
||||
// Detected just for BLender AO vs lightmap
|
||||
} else if (property.properties.at(0) == "Shininess") {
|
||||
material.shininess = property.properties.at(index).value<double>();
|
||||
|
||||
|
@ -1128,8 +1131,10 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_emissive_map")) {
|
||||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("ambient")) {
|
||||
} else if (type.contains("ambientcolor")) {
|
||||
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("ambientfactor")) {
|
||||
ambientFactorTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type.contains("tex_ao_map")) {
|
||||
occlusionTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else if (type == "lcl rotation") {
|
||||
|
|
|
@ -151,6 +151,7 @@ public:
|
|||
float metallic{ 0.0f };
|
||||
float roughness{ 1.0f };
|
||||
float emissiveIntensity{ 1.0f };
|
||||
float ambientFactor{ 1.0f };
|
||||
|
||||
QString materialID;
|
||||
QString name;
|
||||
|
@ -437,6 +438,7 @@ public:
|
|||
QHash<QString, QString> shininessTextures;
|
||||
QHash<QString, QString> emissiveTextures;
|
||||
QHash<QString, QString> ambientTextures;
|
||||
QHash<QString, QString> ambientFactorTextures;
|
||||
QHash<QString, QString> occlusionTextures;
|
||||
|
||||
QHash<QString, FBXMaterial> _fbxMaterials;
|
||||
|
|
|
@ -186,6 +186,14 @@ void FBXReader::consolidateFBXMaterials() {
|
|||
|
||||
FBXTexture occlusionTexture;
|
||||
QString occlusionTextureID = occlusionTextures.value(material.materialID);
|
||||
if (occlusionTextureID.isNull()) {
|
||||
// 2nd chance
|
||||
// For blender we use the ambient factor texture as AOMap ONLY if the ambientFactor value is > 0.0
|
||||
if (material.ambientFactor > 0.0f) {
|
||||
occlusionTextureID = ambientFactorTextures.value(material.materialID);
|
||||
}
|
||||
}
|
||||
|
||||
if (!occlusionTextureID.isNull()) {
|
||||
occlusionTexture = getTexture(occlusionTextureID);
|
||||
detectDifferentUVs |= (occlusionTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||
|
@ -198,6 +206,14 @@ void FBXReader::consolidateFBXMaterials() {
|
|||
|
||||
FBXTexture ambientTexture;
|
||||
QString ambientTextureID = ambientTextures.value(material.materialID);
|
||||
if (ambientTextureID.isNull()) {
|
||||
// 2nd chance
|
||||
// For blender we use the ambient factor texture as Lightmap ONLY if the ambientFactor value is set to 0
|
||||
if (material.ambientFactor == 0.0f) {
|
||||
ambientTextureID = ambientFactorTextures.value(material.materialID);
|
||||
}
|
||||
}
|
||||
|
||||
if (_loadLightmaps && !ambientTextureID.isNull()) {
|
||||
ambientTexture = getTexture(ambientTextureID);
|
||||
detectDifferentUVs |= (ambientTexture.texcoordSet != 0) || (!ambientTexture.transform.isIdentity());
|
||||
|
|
|
@ -25,7 +25,6 @@ InputPluginList getInputPlugins() {
|
|||
for (int i = 0; PLUGIN_POOL[i]; ++i) {
|
||||
InputPlugin* plugin = PLUGIN_POOL[i];
|
||||
if (plugin->isSupported()) {
|
||||
plugin->init();
|
||||
result.push_back(InputPluginPointer(plugin));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -418,6 +418,8 @@ model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, c
|
|||
|
||||
auto map = std::make_shared<model::TextureMap>();
|
||||
map->setTextureSource(texture->_textureSource);
|
||||
map->setTextureTransform(fbxTexture.transform);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -427,6 +429,7 @@ model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, Textu
|
|||
|
||||
auto map = std::make_shared<model::TextureMap>();
|
||||
map->setTextureSource(texture->_textureSource);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -475,6 +478,7 @@ NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textur
|
|||
|
||||
if (!material.occlusionTexture.filename.isEmpty()) {
|
||||
auto map = fetchTextureMap(textureBaseUrl, material.occlusionTexture, NetworkTexture::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||
map->setTextureTransform(material.occlusionTexture.transform);
|
||||
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,10 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
|
|||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[0] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
}
|
||||
|
||||
if (channel == MaterialKey::OCCLUSION_MAP) {
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
}
|
||||
|
||||
if (channel == MaterialKey::LIGHTMAP_MAP) {
|
||||
// update the texcoord1 with lightmap
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <atomic>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletDynamics/Character/btCharacterControllerInterface.h>
|
||||
|
||||
|
@ -105,8 +106,9 @@ public:
|
|||
|
||||
void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale);
|
||||
|
||||
bool isEnabled() const { return _enabled; } // thread-safe
|
||||
void setEnabled(bool enabled);
|
||||
bool isEnabled() const { return _enabled && _dynamicsWorld; }
|
||||
bool isEnabledAndReady() const { return _enabled && _dynamicsWorld; }
|
||||
|
||||
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||
|
||||
|
@ -167,7 +169,7 @@ protected:
|
|||
btQuaternion _followAngularDisplacement;
|
||||
btVector3 _linearAcceleration;
|
||||
|
||||
bool _enabled;
|
||||
std::atomic_bool _enabled;
|
||||
State _state;
|
||||
bool _isPushingUp;
|
||||
|
||||
|
|
|
@ -17,6 +17,54 @@
|
|||
#include "ShapeFactory.h"
|
||||
#include "BulletUtil.h"
|
||||
|
||||
// These are the same normalized directions used by the btShapeHull class.
|
||||
// 12 points for the face centers of a duodecohedron plus another 30 points
|
||||
// for the midpoints the edges, for a total of 42.
|
||||
const uint32_t NUM_UNIT_SPHERE_DIRECTIONS = 42;
|
||||
static const btVector3 _unitSphereDirections[NUM_UNIT_SPHERE_DIRECTIONS] = {
|
||||
btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
|
||||
btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
|
||||
btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
|
||||
btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
|
||||
btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
|
||||
btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
|
||||
btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
|
||||
btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
|
||||
btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
|
||||
btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
|
||||
btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
|
||||
btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
|
||||
btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
|
||||
btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
|
||||
btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
|
||||
btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
|
||||
btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
|
||||
btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
|
||||
btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
|
||||
btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
|
||||
btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
|
||||
btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
|
||||
btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
|
||||
btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
|
||||
btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
|
||||
btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
|
||||
btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
|
||||
btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
|
||||
btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
|
||||
btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
|
||||
btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
|
||||
btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
|
||||
btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
|
||||
btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
|
||||
btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
|
||||
btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
|
||||
btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
|
||||
btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
|
||||
btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
|
||||
btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
|
||||
btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
|
||||
btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
|
||||
};
|
||||
|
||||
|
||||
btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& points) {
|
||||
|
@ -66,15 +114,40 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& poin
|
|||
hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false);
|
||||
}
|
||||
|
||||
if (points.size() > MAX_HULL_POINTS) {
|
||||
// create hull approximation
|
||||
btShapeHull shapeHull(hull);
|
||||
shapeHull.buildHull(margin);
|
||||
uint32_t numPoints = (uint32_t)hull->getNumPoints();
|
||||
if (numPoints > MAX_HULL_POINTS) {
|
||||
// we have too many points, so we compute point projections along canonical unit vectors
|
||||
// and keep the those that project the farthest
|
||||
btVector3 btCenter = glmToBullet(center);
|
||||
btVector3* shapePoints = hull->getUnscaledPoints();
|
||||
std::vector<uint32_t> finalIndices;
|
||||
finalIndices.reserve(NUM_UNIT_SPHERE_DIRECTIONS);
|
||||
for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) {
|
||||
uint32_t bestIndex = 0;
|
||||
btScalar maxDistance = _unitSphereDirections[i].dot(shapePoints[0] - btCenter);
|
||||
for (uint32_t j = 1; j < numPoints; ++j) {
|
||||
btScalar distance = _unitSphereDirections[i].dot(shapePoints[j] - btCenter);
|
||||
if (distance > maxDistance) {
|
||||
maxDistance = distance;
|
||||
bestIndex = j;
|
||||
}
|
||||
}
|
||||
bool keep = true;
|
||||
for (uint32_t j = 0; j < finalIndices.size(); ++j) {
|
||||
if (finalIndices[j] == bestIndex) {
|
||||
keep = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keep) {
|
||||
finalIndices.push_back(bestIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// we cannot copy Bullet shapes so we must create a new one...
|
||||
btConvexHullShape* newHull = new btConvexHullShape();
|
||||
const btVector3* newPoints = shapeHull.getVertexPointer();
|
||||
for (int i = 0; i < shapeHull.numVertices(); ++i) {
|
||||
newHull->addPoint(newPoints[i], false);
|
||||
for (uint32_t i = 0; i < finalIndices.size(); ++i) {
|
||||
newHull->addPoint(shapePoints[finalIndices[i]], false);
|
||||
}
|
||||
// ...and delete the old one
|
||||
delete hull;
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
}
|
||||
|
||||
// will query the underlying hmd api to compute the most recent head pose
|
||||
virtual void beginFrameRender(uint32_t frameIndex) {}
|
||||
virtual bool beginFrameRender(uint32_t frameIndex) { return true; }
|
||||
|
||||
// returns a copy of the most recent head pose, computed via updateHeadPose
|
||||
virtual glm::mat4 getHeadPose() const {
|
||||
|
@ -170,6 +170,10 @@ public:
|
|||
|
||||
signals:
|
||||
void recommendedFramebufferSizeChanged(const QSize & size);
|
||||
// Indicates that this display plugin is no longer valid for use.
|
||||
// For instance if a user exits Oculus Home or Steam VR while
|
||||
// using the corresponding plugin, that plugin should be disabled.
|
||||
void outputDeviceLost();
|
||||
|
||||
protected:
|
||||
void incrementPresentCount();
|
||||
|
|
|
@ -25,6 +25,50 @@ PluginManager* PluginManager::getInstance() {
|
|||
return &_manager;
|
||||
}
|
||||
|
||||
QString getPluginNameFromMetaData(QJsonObject object) {
|
||||
static const char* METADATA_KEY = "MetaData";
|
||||
static const char* NAME_KEY = "name";
|
||||
|
||||
if (!object.contains(METADATA_KEY) || !object[METADATA_KEY].isObject()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
auto metaDataObject = object[METADATA_KEY].toObject();
|
||||
|
||||
if (!metaDataObject.contains(NAME_KEY) || !metaDataObject[NAME_KEY].isString()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return metaDataObject[NAME_KEY].toString();
|
||||
}
|
||||
|
||||
QString getPluginIIDFromMetaData(QJsonObject object) {
|
||||
static const char* IID_KEY = "IID";
|
||||
|
||||
if (!object.contains(IID_KEY) || !object[IID_KEY].isString()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return object[IID_KEY].toString();
|
||||
}
|
||||
|
||||
QStringList preferredDisplayPlugins;
|
||||
QStringList disabledDisplays;
|
||||
QStringList disabledInputs;
|
||||
|
||||
bool isDisabled(QJsonObject metaData) {
|
||||
auto name = getPluginNameFromMetaData(metaData);
|
||||
auto iid = getPluginIIDFromMetaData(metaData);
|
||||
|
||||
if (iid == DisplayProvider_iid) {
|
||||
return disabledDisplays.contains(name);
|
||||
} else if (iid == InputProvider_iid) {
|
||||
return disabledInputs.contains(name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
using Loader = QSharedPointer<QPluginLoader>;
|
||||
using LoaderList = QList<Loader>;
|
||||
|
||||
|
@ -43,11 +87,21 @@ const LoaderList& getLoadedPlugins() {
|
|||
qDebug() << "Loading runtime plugins from " << pluginPath;
|
||||
auto candidates = pluginDir.entryList();
|
||||
for (auto plugin : candidates) {
|
||||
qDebug() << "Attempting plugins " << plugin;
|
||||
qDebug() << "Attempting plugin" << qPrintable(plugin);
|
||||
QSharedPointer<QPluginLoader> loader(new QPluginLoader(pluginPath + plugin));
|
||||
|
||||
if (isDisabled(loader->metaData())) {
|
||||
qWarning() << "Plugin" << qPrintable(plugin) << "is disabled";
|
||||
// Skip this one, it's disabled
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loader->load()) {
|
||||
qDebug() << "Plugins " << plugin << " success";
|
||||
qDebug() << "Plugin" << qPrintable(plugin) << "loaded successfully";
|
||||
loadedPlugins.push_back(loader);
|
||||
} else {
|
||||
qDebug() << "Plugin" << qPrintable(plugin) << "failed to load:";
|
||||
qDebug() << " " << qPrintable(loader->errorString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,11 +116,10 @@ PluginManager::PluginManager() {
|
|||
extern DisplayPluginList getDisplayPlugins();
|
||||
extern InputPluginList getInputPlugins();
|
||||
extern void saveInputPluginSettings(const InputPluginList& plugins);
|
||||
static DisplayPluginList displayPlugins;
|
||||
|
||||
const DisplayPluginList& PluginManager::getDisplayPlugins() {
|
||||
static DisplayPluginList displayPlugins;
|
||||
static std::once_flag once;
|
||||
|
||||
std::call_once(once, [&] {
|
||||
// Grab the built in plugins
|
||||
displayPlugins = ::getDisplayPlugins();
|
||||
|
@ -90,6 +143,16 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() {
|
|||
return displayPlugins;
|
||||
}
|
||||
|
||||
void PluginManager::disableDisplayPlugin(const QString& name) {
|
||||
for (size_t i = 0; i < displayPlugins.size(); ++i) {
|
||||
if (displayPlugins[i]->getName() == name) {
|
||||
displayPlugins.erase(displayPlugins.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const InputPluginList& PluginManager::getInputPlugins() {
|
||||
static InputPluginList inputPlugins;
|
||||
static std::once_flag once;
|
||||
|
@ -101,7 +164,9 @@ const InputPluginList& PluginManager::getInputPlugins() {
|
|||
InputProvider* inputProvider = qobject_cast<InputProvider*>(loader->instance());
|
||||
if (inputProvider) {
|
||||
for (auto inputPlugin : inputProvider->getInputPlugins()) {
|
||||
inputPlugins.push_back(inputPlugin);
|
||||
if (inputPlugin->isSupported()) {
|
||||
inputPlugins.push_back(inputPlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +180,40 @@ const InputPluginList& PluginManager::getInputPlugins() {
|
|||
return inputPlugins;
|
||||
}
|
||||
|
||||
void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) {
|
||||
preferredDisplayPlugins = displays;
|
||||
}
|
||||
|
||||
DisplayPluginList PluginManager::getPreferredDisplayPlugins() {
|
||||
static DisplayPluginList displayPlugins;
|
||||
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
// Grab the built in plugins
|
||||
auto plugins = getDisplayPlugins();
|
||||
|
||||
for (auto pluginName : preferredDisplayPlugins) {
|
||||
auto it = std::find_if(plugins.begin(), plugins.end(), [&](DisplayPluginPointer plugin) {
|
||||
return plugin->getName() == pluginName;
|
||||
});
|
||||
if (it != plugins.end()) {
|
||||
displayPlugins.push_back(*it);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return displayPlugins;
|
||||
}
|
||||
|
||||
|
||||
void PluginManager::disableDisplays(const QStringList& displays) {
|
||||
disabledDisplays << displays;
|
||||
}
|
||||
|
||||
void PluginManager::disableInputs(const QStringList& inputs) {
|
||||
disabledInputs << inputs;
|
||||
}
|
||||
|
||||
void PluginManager::saveSettings() {
|
||||
saveInputPluginSettings(getInputPlugins());
|
||||
}
|
||||
|
|
|
@ -13,10 +13,17 @@
|
|||
|
||||
class PluginManager : public QObject {
|
||||
public:
|
||||
static PluginManager* getInstance();
|
||||
PluginManager();
|
||||
static PluginManager* getInstance();
|
||||
PluginManager();
|
||||
|
||||
const DisplayPluginList& getDisplayPlugins();
|
||||
const InputPluginList& getInputPlugins();
|
||||
void saveSettings();
|
||||
const DisplayPluginList& getDisplayPlugins();
|
||||
const InputPluginList& getInputPlugins();
|
||||
|
||||
DisplayPluginList getPreferredDisplayPlugins();
|
||||
void setPreferredDisplayPlugins(const QStringList& displays);
|
||||
|
||||
void disableDisplayPlugin(const QString& name);
|
||||
void disableDisplays(const QStringList& displays);
|
||||
void disableInputs(const QStringList& inputs);
|
||||
void saveSettings();
|
||||
};
|
||||
|
|
|
@ -84,7 +84,7 @@ static const std::string DEFAULT_NORMAL_SHADER {
|
|||
static const std::string DEFAULT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||
" return vec4(vec3(frag.obscurance), 1.0);"
|
||||
" return vec4(vec3(pow(frag.obscurance, 1.0 / 2.2)), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ float fetchOcclusionMap(vec2 uv) {
|
|||
<@endfunc@>
|
||||
|
||||
|
||||
<@func fetchMaterialTextures(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, occlusion)@>
|
||||
<@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive)@>
|
||||
<@if albedo@>
|
||||
vec4 <$albedo$> = (((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0));
|
||||
<@endif@>
|
||||
|
@ -106,12 +106,19 @@ float fetchOcclusionMap(vec2 uv) {
|
|||
<@if emissive@>
|
||||
vec3 <$emissive$> = (((<$matKey$> & EMISSIVE_MAP_BIT) != 0) ? fetchEmissiveMap(<$texcoord0$>) : vec3(0.0));
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func fetchMaterialTexturesCoord1(matKey, texcoord1, occlusion, lightmapVal)@>
|
||||
<@if occlusion@>
|
||||
float <$occlusion$> = (((<$matKey$> & OCCLUSION_MAP_BIT) != 0) ? fetchOcclusionMap(<$texcoord0$>) : 1.0);
|
||||
float <$occlusion$> = (((<$matKey$> & OCCLUSION_MAP_BIT) != 0) ? fetchOcclusionMap(<$texcoord1$>) : 1.0);
|
||||
<@endif@>
|
||||
<@if lightmapVal@>
|
||||
vec3 <$lightmapVal$> = fetchLightmapMap(<$texcoord1$>);
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
|
||||
<@func declareMaterialLightmap()@>
|
||||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
@ -123,11 +130,6 @@ vec3 fetchLightmapMap(vec2 uv) {
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func fetchMaterialLightmap(texcoord1, lightmapVal)@>
|
||||
vec3 <$lightmapVal$> = fetchLightmapMap(<$texcoord1$>);
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@func tangentToViewSpace(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
{
|
||||
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
|
||||
|
|
|
@ -35,7 +35,46 @@ int vec3VectorTypeId = qRegisterMetaType<QVector<glm::vec3> >();
|
|||
float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f;
|
||||
#define HTTP_INVALID_COM "http://invalid.com"
|
||||
|
||||
model::MaterialPointer Model::_collisionHullMaterial;
|
||||
const int NUM_COLLISION_HULL_COLORS = 24;
|
||||
std::vector<model::MaterialPointer> _collisionHullMaterials;
|
||||
|
||||
void initCollisionHullMaterials() {
|
||||
// generates bright colors in red, green, blue, yellow, magenta, and cyan spectrums
|
||||
// (no browns, greys, or dark shades)
|
||||
float component[NUM_COLLISION_HULL_COLORS] = {
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.2f, 0.4f, 0.6f, 0.8f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.8f, 0.6f, 0.4f, 0.2f
|
||||
};
|
||||
_collisionHullMaterials.reserve(NUM_COLLISION_HULL_COLORS);
|
||||
|
||||
// each component gets the same cuve
|
||||
// but offset by a multiple of one third the full width
|
||||
int numComponents = 3;
|
||||
int sectionWidth = NUM_COLLISION_HULL_COLORS / numComponents;
|
||||
int greenPhase = sectionWidth;
|
||||
int bluePhase = 2 * sectionWidth;
|
||||
|
||||
// we stride through the colors to scatter adjacent shades
|
||||
// so they don't tend to group together for large models
|
||||
for (int i = 0; i < sectionWidth; ++i) {
|
||||
for (int j = 0; j < numComponents; ++j) {
|
||||
model::MaterialPointer material;
|
||||
material = std::make_shared<model::Material>();
|
||||
int index = j * sectionWidth + i;
|
||||
float red = component[index];
|
||||
float green = component[(index + greenPhase) % NUM_COLLISION_HULL_COLORS];
|
||||
float blue = component[(index + bluePhase) % NUM_COLLISION_HULL_COLORS];
|
||||
material->setAlbedo(glm::vec3(red, green, blue));
|
||||
material->setMetallic(0.02f);
|
||||
material->setRoughness(0.5f);
|
||||
_collisionHullMaterials.push_back(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Model::Model(RigPointer rig, QObject* parent) :
|
||||
QObject(parent),
|
||||
|
@ -1217,13 +1256,10 @@ void Model::segregateMeshGroups() {
|
|||
int totalParts = mesh.parts.size();
|
||||
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
||||
if (showingCollisionHull) {
|
||||
if (!_collisionHullMaterial) {
|
||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
||||
_collisionHullMaterial->setAlbedo(glm::vec3(1.0f, 0.5f, 0.0f));
|
||||
_collisionHullMaterial->setMetallic(0.02f);
|
||||
_collisionHullMaterial->setRoughness(0.5f);
|
||||
if (_collisionHullMaterials.empty()) {
|
||||
initCollisionHullMaterials();
|
||||
}
|
||||
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(networkMesh, partIndex, _collisionHullMaterial, transform, offset);
|
||||
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(networkMesh, partIndex, _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS], transform, offset);
|
||||
} else {
|
||||
_modelMeshRenderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset);
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@ in vec4 _position;
|
|||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
|
||||
|
||||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec3 _normal;
|
||||
|
||||
|
@ -31,6 +32,7 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
|
@ -29,8 +29,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
|
|
|
@ -30,8 +30,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, normalTexel)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
|
|
@ -30,8 +30,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
vec3 viewNormal;
|
||||
<$tangentToViewSpace(normalTexel, _normal, _tangent, viewNormal)$>
|
||||
|
|
|
@ -29,8 +29,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness, _SCRIBE_NULL, metallicTex)$>
|
||||
<$fetchMaterialLightmap(_texCoord1, lightmapVal)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, _SCRIBE_NULL, metallicTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$>
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
|
@ -28,7 +29,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _color;
|
||||
|
@ -34,6 +35,7 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _color;
|
||||
|
@ -28,7 +29,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, occlusionTex)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
|
||||
|
@ -28,7 +29,8 @@ in vec3 _color;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, occlusionTex)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
|
@ -35,7 +36,8 @@ out vec4 _fragColor;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex)$>
|
||||
<$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$>
|
||||
|
||||
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
@ -61,7 +63,7 @@ void main(void) {
|
|||
_fragColor = vec4(evalGlobalLightingAlphaBlended(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
albedo,
|
||||
|
|
|
@ -26,7 +26,7 @@ out vec4 _fragColor;
|
|||
void main(void) {
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
|
||||
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<@include model/Material.slh@>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||
<$declareMaterialTextures(ALBEDO)$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _normal;
|
||||
|
@ -27,7 +27,7 @@ void main(void) {
|
|||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
|
||||
|
||||
float opacity = 1.0;
|
||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
|
@ -40,6 +41,7 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
out vec4 _position;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _color;
|
||||
|
@ -42,6 +43,7 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
||||
|
|
181
libraries/shared/src/CPUDetect.h
Normal file
181
libraries/shared/src/CPUDetect.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
//
|
||||
// CPUDetect.h
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Ken Cooke on 6/6/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_CPUDetect_h
|
||||
#define hifi_CPUDetect_h
|
||||
|
||||
//
|
||||
// Lightweight functions to detect SSE/AVX/AVX2 support
|
||||
//
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
|
||||
#define ARCH_X86
|
||||
#endif
|
||||
|
||||
#define MASK_SSE3 (1 << 0) // SSE3
|
||||
#define MASK_SSSE3 (1 << 9) // SSSE3
|
||||
#define MASK_SSE41 (1 << 19) // SSE4.1
|
||||
#define MASK_SSE42 ((1 << 20) | (1 << 23)) // SSE4.2 and POPCNT
|
||||
#define MASK_AVX ((1 << 27) | (1 << 28)) // OSXSAVE and AVX
|
||||
#define MASK_AVX2 (1 << 5) // AVX2
|
||||
|
||||
#if defined(ARCH_X86) && defined(_MSC_VER)
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
static inline bool cpuSupportsSSE3() {
|
||||
int info[4];
|
||||
|
||||
__cpuidex(info, 0x1, 0);
|
||||
|
||||
return ((info[2] & MASK_SSE3) == MASK_SSE3);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSSE3() {
|
||||
int info[4];
|
||||
|
||||
__cpuidex(info, 0x1, 0);
|
||||
|
||||
return ((info[2] & MASK_SSSE3) == MASK_SSSE3);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE41() {
|
||||
int info[4];
|
||||
|
||||
__cpuidex(info, 0x1, 0);
|
||||
|
||||
return ((info[2] & MASK_SSE41) == MASK_SSE41);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE42() {
|
||||
int info[4];
|
||||
|
||||
__cpuidex(info, 0x1, 0);
|
||||
|
||||
return ((info[2] & MASK_SSE42) == MASK_SSE42);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX() {
|
||||
int info[4];
|
||||
|
||||
__cpuidex(info, 0x1, 0);
|
||||
|
||||
bool result = false;
|
||||
if ((info[2] & MASK_AVX) == MASK_AVX) {
|
||||
|
||||
// verify OS support for YMM state
|
||||
if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX2() {
|
||||
int info[4];
|
||||
|
||||
bool result = false;
|
||||
if (cpuSupportsAVX()) {
|
||||
|
||||
__cpuidex(info, 0x7, 0);
|
||||
|
||||
if ((info[1] & MASK_AVX2) == MASK_AVX2) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif defined(ARCH_X86) && defined(__GNUC__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
static inline bool cpuSupportsSSE3() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
return __get_cpuid(0x1, &eax, &ebx, &ecx, &edx) && ((ecx & MASK_SSE3) == MASK_SSE3);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSSE3() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
return __get_cpuid(0x1, &eax, &ebx, &ecx, &edx) && ((ecx & MASK_SSSE3) == MASK_SSSE3);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE41() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
return __get_cpuid(0x1, &eax, &ebx, &ecx, &edx) && ((ecx & MASK_SSE41) == MASK_SSE41);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE42() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
return __get_cpuid(0x1, &eax, &ebx, &ecx, &edx) && ((ecx & MASK_SSE42) == MASK_SSE42);
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
bool result = false;
|
||||
if (__get_cpuid(0x1, &eax, &ebx, &ecx, &edx) && ((ecx & MASK_AVX) == MASK_AVX)) {
|
||||
|
||||
// verify OS support for YMM state
|
||||
__asm__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
|
||||
if ((eax & 0x6) == 0x6) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX2() {
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
bool result = false;
|
||||
if (cpuSupportsAVX()) {
|
||||
|
||||
if (__get_cpuid(0x7, &eax, &ebx, &ecx, &edx) && ((ebx & MASK_AVX2) == MASK_AVX2)) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline bool cpuSupportsSSE3() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSSE3() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE41() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsSSE42() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool cpuSupportsAVX2() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // hifi_CPUDetect_h
|
|
@ -10,11 +10,80 @@
|
|||
//
|
||||
|
||||
#include "SettingHandle.h"
|
||||
#include "SettingManager.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
const QString Settings::firstRun { "firstRun" };
|
||||
|
||||
Settings::Settings() :
|
||||
_manager(DependencyManager::get<Setting::Manager>()),
|
||||
_locker(&(_manager->getLock()))
|
||||
{
|
||||
}
|
||||
|
||||
Settings::~Settings() {
|
||||
}
|
||||
|
||||
void Settings::remove(const QString& key) {
|
||||
if (key == "" || _manager->contains(key)) {
|
||||
_manager->remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Settings::childGroups() const {
|
||||
return _manager->childGroups();
|
||||
}
|
||||
|
||||
QStringList Settings::childKeys() const {
|
||||
return _manager->childKeys();
|
||||
}
|
||||
|
||||
QStringList Settings::allKeys() const {
|
||||
return _manager->allKeys();
|
||||
}
|
||||
|
||||
bool Settings::contains(const QString& key) const {
|
||||
return _manager->contains(key);
|
||||
}
|
||||
|
||||
int Settings::beginReadArray(const QString & prefix) {
|
||||
return _manager->beginReadArray(prefix);
|
||||
}
|
||||
|
||||
void Settings::beginWriteArray(const QString& prefix, int size) {
|
||||
_manager->beginWriteArray(prefix, size);
|
||||
}
|
||||
|
||||
void Settings::endArray() {
|
||||
_manager->endArray();
|
||||
}
|
||||
|
||||
void Settings::setArrayIndex(int i) {
|
||||
_manager->setArrayIndex(i);
|
||||
}
|
||||
|
||||
void Settings::beginGroup(const QString& prefix) {
|
||||
_manager->beginGroup(prefix);
|
||||
}
|
||||
|
||||
void Settings::endGroup() {
|
||||
_manager->endGroup();
|
||||
}
|
||||
|
||||
void Settings::setValue(const QString& name, const QVariant& value) {
|
||||
if (_manager->value(name) != value) {
|
||||
_manager->setValue(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant Settings::value(const QString& name, const QVariant& defaultValue) const {
|
||||
return _manager->value(name, defaultValue);
|
||||
}
|
||||
|
||||
|
||||
void Settings::getFloatValueIfValid(const QString& name, float& floatValue) {
|
||||
const QVariant badDefaultValue = NAN;
|
||||
bool ok = true;
|
||||
|
|
|
@ -14,19 +14,40 @@
|
|||
|
||||
#include <type_traits>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QStack>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include "SettingInterface.h"
|
||||
|
||||
|
||||
// TODO: remove
|
||||
class Settings : public QSettings {
|
||||
class Settings {
|
||||
public:
|
||||
static const QString firstRun;
|
||||
Settings();
|
||||
~Settings();
|
||||
|
||||
void remove(const QString& key);
|
||||
QStringList childGroups() const;
|
||||
QStringList childKeys() const;
|
||||
QStringList allKeys() const;
|
||||
bool contains(const QString& key) const;
|
||||
int beginReadArray(const QString & prefix);
|
||||
void beginWriteArray(const QString& prefix, int size = -1);
|
||||
void endArray();
|
||||
void setArrayIndex(int i);
|
||||
|
||||
void beginGroup(const QString& prefix);
|
||||
void endGroup();
|
||||
|
||||
void setValue(const QString& name, const QVariant& value);
|
||||
QVariant value(const QString& name, const QVariant& defaultValue = QVariant()) const;
|
||||
|
||||
void getFloatValueIfValid(const QString& name, float& floatValue);
|
||||
void getBoolValue(const QString& name, bool& boolValue);
|
||||
|
@ -36,6 +57,9 @@ public:
|
|||
|
||||
void setQuatValue(const QString& name, const glm::quat& quatValue);
|
||||
void getQuatValueIfValid(const QString& name, glm::quat& quatValue);
|
||||
|
||||
QSharedPointer<Setting::Manager> _manager;
|
||||
QWriteLocker _locker;
|
||||
};
|
||||
|
||||
namespace Setting {
|
||||
|
|
|
@ -9,27 +9,33 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "SettingInterface.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QThread>
|
||||
|
||||
#include "PathUtils.h"
|
||||
#include "SettingInterface.h"
|
||||
#include "SettingManager.h"
|
||||
#include "SharedLogging.h"
|
||||
|
||||
namespace Setting {
|
||||
static Manager* privateInstance = nullptr;
|
||||
static QSharedPointer<Manager> globalManager;
|
||||
|
||||
const QString Interface::FIRST_RUN { "firstRun" };
|
||||
|
||||
// cleans up the settings private instance. Should only be run once at closing down.
|
||||
void cleanupPrivateInstance() {
|
||||
// grab the thread before we nuke the instance
|
||||
QThread* settingsManagerThread = privateInstance->thread();
|
||||
|
||||
QThread* settingsManagerThread = DependencyManager::get<Manager>()->thread();
|
||||
|
||||
// tell the private instance to clean itself up on its thread
|
||||
privateInstance->deleteLater();
|
||||
privateInstance = NULL;
|
||||
DependencyManager::destroy<Manager>();
|
||||
|
||||
//
|
||||
globalManager->deleteLater();
|
||||
globalManager.reset();
|
||||
|
||||
// quit the settings manager thread and wait on it to make sure it's gone
|
||||
settingsManagerThread->quit();
|
||||
|
@ -63,14 +69,13 @@ namespace Setting {
|
|||
QThread* thread = new QThread();
|
||||
Q_CHECK_PTR(thread);
|
||||
thread->setObjectName("Settings Thread");
|
||||
|
||||
privateInstance = new Manager();
|
||||
Q_CHECK_PTR(privateInstance);
|
||||
|
||||
QObject::connect(privateInstance, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||
QObject::connect(thread, SIGNAL(started()), privateInstance, SLOT(startTimer()));
|
||||
globalManager = DependencyManager::set<Manager>();
|
||||
|
||||
QObject::connect(globalManager.data(), SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||
QObject::connect(thread, SIGNAL(started()), globalManager.data(), SLOT(startTimer()));
|
||||
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
privateInstance->moveToThread(thread);
|
||||
globalManager->moveToThread(thread);
|
||||
thread->start();
|
||||
qCDebug(shared) << "Settings thread started.";
|
||||
|
||||
|
@ -79,7 +84,7 @@ namespace Setting {
|
|||
}
|
||||
|
||||
void Interface::init() {
|
||||
if (!privateInstance) {
|
||||
if (!DependencyManager::isSet<Manager>()) {
|
||||
// WARNING: As long as we are using QSettings this should always be triggered for each Setting::Handle
|
||||
// in an assignment-client - the QSettings backing we use for this means persistence of these
|
||||
// settings from an AC (when there can be multiple terminating at same time on one machine)
|
||||
|
@ -87,9 +92,13 @@ namespace Setting {
|
|||
qWarning() << "Setting::Interface::init() for key" << _key << "- Manager not yet created." <<
|
||||
"Settings persistence disabled.";
|
||||
} else {
|
||||
// Register Handle
|
||||
privateInstance->registerHandle(this);
|
||||
_isInitialized = true;
|
||||
_manager = DependencyManager::get<Manager>();
|
||||
auto manager = _manager.lock();
|
||||
if (manager) {
|
||||
// Register Handle
|
||||
manager->registerHandle(this);
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
// Load value from disk
|
||||
load();
|
||||
|
@ -97,11 +106,13 @@ namespace Setting {
|
|||
}
|
||||
|
||||
void Interface::deinit() {
|
||||
if (_isInitialized && privateInstance) {
|
||||
// Save value to disk
|
||||
save();
|
||||
|
||||
privateInstance->removeHandle(_key);
|
||||
if (_isInitialized && _manager) {
|
||||
auto manager = _manager.lock();
|
||||
if (manager) {
|
||||
// Save value to disk
|
||||
save();
|
||||
manager->removeHandle(_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,14 +124,16 @@ namespace Setting {
|
|||
}
|
||||
|
||||
void Interface::save() {
|
||||
if (privateInstance) {
|
||||
privateInstance->saveSetting(this);
|
||||
auto manager = _manager.lock();
|
||||
if (manager) {
|
||||
manager->saveSetting(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::load() {
|
||||
if (privateInstance) {
|
||||
privateInstance->loadSetting(this);
|
||||
auto manager = _manager.lock();
|
||||
if (manager) {
|
||||
manager->loadSetting(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,17 +12,23 @@
|
|||
#ifndef hifi_SettingInterface_h
|
||||
#define hifi_SettingInterface_h
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <memory>
|
||||
#include <QtCore/QWeakPointer>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
namespace Setting {
|
||||
class Manager;
|
||||
|
||||
void preInit();
|
||||
void init();
|
||||
void cleanupSettings();
|
||||
|
||||
class Interface {
|
||||
public:
|
||||
QString getKey() const { return _key; }
|
||||
static const QString FIRST_RUN;
|
||||
|
||||
const QString& getKey() const { return _key; }
|
||||
bool isSet() const { return _isSet; }
|
||||
|
||||
virtual void setVariant(const QVariant& variant) = 0;
|
||||
|
@ -44,6 +50,8 @@ namespace Setting {
|
|||
const QString _key;
|
||||
|
||||
friend class Manager;
|
||||
|
||||
QWeakPointer<Manager> _manager;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "SettingInterface.h"
|
||||
#include "SettingManager.h"
|
||||
|
||||
namespace Setting {
|
||||
|
||||
Manager::~Manager() {
|
||||
// Cleanup timer
|
||||
stopTimer();
|
||||
|
@ -27,6 +29,10 @@ namespace Setting {
|
|||
// sync will be called in the QSettings destructor
|
||||
}
|
||||
|
||||
// Custom deleter does nothing, because we need to shutdown later than the dependency manager
|
||||
void Manager::customDeleter() { }
|
||||
|
||||
|
||||
void Manager::registerHandle(Setting::Interface* handle) {
|
||||
QString key = handle->getKey();
|
||||
withWriteLock([&] {
|
||||
|
@ -44,15 +50,29 @@ namespace Setting {
|
|||
}
|
||||
|
||||
void Manager::loadSetting(Interface* handle) {
|
||||
handle->setVariant(value(handle->getKey()));
|
||||
const auto& key = handle->getKey();
|
||||
withWriteLock([&] {
|
||||
QVariant loadedValue;
|
||||
if (_pendingChanges.contains(key)) {
|
||||
loadedValue = _pendingChanges[key];
|
||||
} else {
|
||||
loadedValue = value(key);
|
||||
}
|
||||
handle->setVariant(loadedValue);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Manager::saveSetting(Interface* handle) {
|
||||
const auto& key = handle->getKey();
|
||||
QVariant handleValue = UNSET_VALUE;
|
||||
if (handle->isSet()) {
|
||||
setValue(handle->getKey(), handle->getVariant());
|
||||
} else {
|
||||
remove(handle->getKey());
|
||||
handleValue = handle->getVariant();
|
||||
}
|
||||
|
||||
withWriteLock([&] {
|
||||
_pendingChanges[key] = handleValue;
|
||||
});
|
||||
}
|
||||
|
||||
static const int SAVE_INTERVAL_MSEC = 5 * 1000; // 5 sec
|
||||
|
@ -74,10 +94,20 @@ namespace Setting {
|
|||
}
|
||||
|
||||
void Manager::saveAll() {
|
||||
withReadLock([&] {
|
||||
for (auto handle : _handles) {
|
||||
saveSetting(handle);
|
||||
withWriteLock([&] {
|
||||
for (auto key : _pendingChanges.keys()) {
|
||||
auto newValue = _pendingChanges[key];
|
||||
auto savedValue = value(key, UNSET_VALUE);
|
||||
if (newValue == savedValue) {
|
||||
continue;
|
||||
}
|
||||
if (newValue == UNSET_VALUE) {
|
||||
remove(key);
|
||||
} else {
|
||||
setValue(key, newValue);
|
||||
}
|
||||
}
|
||||
_pendingChanges.clear();
|
||||
});
|
||||
|
||||
// Restart timer
|
||||
|
|
|
@ -12,17 +12,23 @@
|
|||
#ifndef hifi_SettingManager_h
|
||||
#define hifi_SettingManager_h
|
||||
|
||||
#include <QPointer>
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "DependencyManager.h"
|
||||
#include "shared/ReadWriteLockable.h"
|
||||
|
||||
namespace Setting {
|
||||
class Interface;
|
||||
|
||||
class Manager : public QSettings, public ReadWriteLockable {
|
||||
class Manager : public QSettings, public ReadWriteLockable, public Dependency {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void customDeleter() override;
|
||||
|
||||
protected:
|
||||
~Manager();
|
||||
void registerHandle(Interface* handle);
|
||||
|
@ -40,6 +46,8 @@ namespace Setting {
|
|||
private:
|
||||
QHash<QString, Interface*> _handles;
|
||||
QPointer<QTimer> _saveTimer = nullptr;
|
||||
const QVariant UNSET_VALUE { QUuid::createUuid().variant() };
|
||||
QHash<QString, QVariant> _pendingChanges;
|
||||
|
||||
friend class Interface;
|
||||
friend void cleanupPrivateInstance();
|
||||
|
|
|
@ -23,7 +23,6 @@ void ShapeInfo::clear() {
|
|||
|
||||
void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) {
|
||||
_type = type;
|
||||
_points.clear();
|
||||
switch(type) {
|
||||
case SHAPE_TYPE_NONE:
|
||||
_halfExtents = glm::vec3(0.0f);
|
||||
|
@ -52,7 +51,6 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
|||
_url = "";
|
||||
_type = SHAPE_TYPE_BOX;
|
||||
_halfExtents = halfExtents;
|
||||
_points.clear();
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
|
@ -60,15 +58,6 @@ void ShapeInfo::setSphere(float radius) {
|
|||
_url = "";
|
||||
_type = SHAPE_TYPE_SPHERE;
|
||||
_halfExtents = glm::vec3(radius, radius, radius);
|
||||
_points.clear();
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) {
|
||||
_url = "";
|
||||
_type = SHAPE_TYPE_ELLIPSOID;
|
||||
_halfExtents = halfExtents;
|
||||
_points.clear();
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
|
@ -82,7 +71,6 @@ void ShapeInfo::setCapsuleY(float radius, float halfHeight) {
|
|||
_url = "";
|
||||
_type = SHAPE_TYPE_CAPSULE_Y;
|
||||
_halfExtents = glm::vec3(radius, halfHeight, radius);
|
||||
_points.clear();
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
|
@ -146,10 +134,6 @@ bool ShapeInfo::contains(const glm::vec3& point) const {
|
|||
switch(_type) {
|
||||
case SHAPE_TYPE_SPHERE:
|
||||
return glm::length(point) <= _halfExtents.x;
|
||||
case SHAPE_TYPE_ELLIPSOID: {
|
||||
glm::vec3 scaledPoint = glm::abs(point) / _halfExtents;
|
||||
return glm::length(scaledPoint) <= 1.0f;
|
||||
}
|
||||
case SHAPE_TYPE_CYLINDER_X:
|
||||
return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z;
|
||||
case SHAPE_TYPE_CYLINDER_Y:
|
||||
|
|
|
@ -30,7 +30,6 @@ enum ShapeType {
|
|||
SHAPE_TYPE_NONE,
|
||||
SHAPE_TYPE_BOX,
|
||||
SHAPE_TYPE_SPHERE,
|
||||
SHAPE_TYPE_ELLIPSOID,
|
||||
SHAPE_TYPE_PLANE,
|
||||
SHAPE_TYPE_COMPOUND,
|
||||
SHAPE_TYPE_CAPSULE_X,
|
||||
|
@ -39,7 +38,7 @@ enum ShapeType {
|
|||
SHAPE_TYPE_CYLINDER_X,
|
||||
SHAPE_TYPE_CYLINDER_Y,
|
||||
SHAPE_TYPE_CYLINDER_Z,
|
||||
SHAPE_TYPE_LINE
|
||||
SHAPE_TYPE_STATIC_MESH
|
||||
};
|
||||
|
||||
class ShapeInfo {
|
||||
|
@ -50,7 +49,6 @@ public:
|
|||
void setParams(ShapeType type, const glm::vec3& halfExtents, QString url="");
|
||||
void setBox(const glm::vec3& halfExtents);
|
||||
void setSphere(float radius);
|
||||
void setEllipsoid(const glm::vec3& halfExtents);
|
||||
void setConvexHulls(const QVector<QVector<glm::vec3>>& points);
|
||||
void setCapsuleY(float radius, float halfHeight);
|
||||
void setOffset(const glm::vec3& offset);
|
||||
|
@ -60,10 +58,10 @@ public:
|
|||
const glm::vec3& getHalfExtents() const { return _halfExtents; }
|
||||
const glm::vec3& getOffset() const { return _offset; }
|
||||
|
||||
QVector<QVector<glm::vec3>>& getPoints() { return _points; }
|
||||
const QVector<QVector<glm::vec3>>& getPoints() const { return _points; }
|
||||
uint32_t getNumSubShapes() const;
|
||||
|
||||
void clearPoints () { _points.clear(); }
|
||||
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
|
||||
int getMaxNumPoints() const;
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
template <typename F>
|
||||
bool withTryReadLock(F&& f, int timeout) const;
|
||||
|
||||
QReadWriteLock& getLock() const { return _lock; }
|
||||
|
||||
private:
|
||||
mutable QReadWriteLock _lock { QReadWriteLock::Recursive };
|
||||
};
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Neuron"}
|
||||
|
|
|
@ -21,9 +21,16 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl
|
|||
InputDevice("GamePad"),
|
||||
_sdlGameController(sdlGameController),
|
||||
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
||||
_sdlHaptic(SDL_HapticOpenFromJoystick(_sdlJoystick)),
|
||||
_instanceId(instanceId)
|
||||
{
|
||||
|
||||
if (!_sdlHaptic) {
|
||||
qDebug() << "SDL Haptic Open Failure: " << QString(SDL_GetError());
|
||||
} else {
|
||||
if (SDL_HapticRumbleInit(_sdlHaptic) != 0) {
|
||||
qDebug() << "SDL Haptic Rumble Init Failure: " << QString(SDL_GetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Joystick::~Joystick() {
|
||||
|
@ -31,6 +38,9 @@ Joystick::~Joystick() {
|
|||
}
|
||||
|
||||
void Joystick::closeJoystick() {
|
||||
if (_sdlHaptic) {
|
||||
SDL_HapticClose(_sdlHaptic);
|
||||
}
|
||||
SDL_GameControllerClose(_sdlGameController);
|
||||
}
|
||||
|
||||
|
@ -62,55 +72,64 @@ void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Joystick::triggerHapticPulse(float strength, float duration, controller::Hand hand) {
|
||||
if (SDL_HapticRumblePlay(_sdlHaptic, strength, duration) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
controller::Input::NamedVector Joystick::getAvailableInputs() const {
|
||||
using namespace controller;
|
||||
static const Input::NamedVector availableInputs{
|
||||
makePair(A, "A"),
|
||||
makePair(B, "B"),
|
||||
makePair(X, "X"),
|
||||
makePair(Y, "Y"),
|
||||
// DPad
|
||||
makePair(DU, "DU"),
|
||||
makePair(DD, "DD"),
|
||||
makePair(DL, "DL"),
|
||||
makePair(DR, "DR"),
|
||||
// Bumpers
|
||||
makePair(LB, "LB"),
|
||||
makePair(RB, "RB"),
|
||||
// Stick press
|
||||
makePair(LS, "LS"),
|
||||
makePair(RS, "RS"),
|
||||
// Center buttons
|
||||
makePair(START, "Start"),
|
||||
makePair(BACK, "Back"),
|
||||
// Analog sticks
|
||||
makePair(LX, "LX"),
|
||||
makePair(LY, "LY"),
|
||||
makePair(RX, "RX"),
|
||||
makePair(RY, "RY"),
|
||||
|
||||
// Triggers
|
||||
makePair(LT, "LT"),
|
||||
makePair(RT, "RT"),
|
||||
if (_availableInputs.length() == 0) {
|
||||
_availableInputs = {
|
||||
makePair(A, "A"),
|
||||
makePair(B, "B"),
|
||||
makePair(X, "X"),
|
||||
makePair(Y, "Y"),
|
||||
// DPad
|
||||
makePair(DU, "DU"),
|
||||
makePair(DD, "DD"),
|
||||
makePair(DL, "DL"),
|
||||
makePair(DR, "DR"),
|
||||
// Bumpers
|
||||
makePair(LB, "LB"),
|
||||
makePair(RB, "RB"),
|
||||
// Stick press
|
||||
makePair(LS, "LS"),
|
||||
makePair(RS, "RS"),
|
||||
// Center buttons
|
||||
makePair(START, "Start"),
|
||||
makePair(BACK, "Back"),
|
||||
// Analog sticks
|
||||
makePair(LX, "LX"),
|
||||
makePair(LY, "LY"),
|
||||
makePair(RX, "RX"),
|
||||
makePair(RY, "RY"),
|
||||
|
||||
// Aliases, PlayStation style names
|
||||
makePair(LB, "L1"),
|
||||
makePair(RB, "R1"),
|
||||
makePair(LT, "L2"),
|
||||
makePair(RT, "R2"),
|
||||
makePair(LS, "L3"),
|
||||
makePair(RS, "R3"),
|
||||
makePair(BACK, "Select"),
|
||||
makePair(A, "Cross"),
|
||||
makePair(B, "Circle"),
|
||||
makePair(X, "Square"),
|
||||
makePair(Y, "Triangle"),
|
||||
makePair(DU, "Up"),
|
||||
makePair(DD, "Down"),
|
||||
makePair(DL, "Left"),
|
||||
makePair(DR, "Right"),
|
||||
};
|
||||
return availableInputs;
|
||||
// Triggers
|
||||
makePair(LT, "LT"),
|
||||
makePair(RT, "RT"),
|
||||
|
||||
// Aliases, PlayStation style names
|
||||
makePair(LB, "L1"),
|
||||
makePair(RB, "R1"),
|
||||
makePair(LT, "L2"),
|
||||
makePair(RT, "R2"),
|
||||
makePair(LS, "L3"),
|
||||
makePair(RS, "R3"),
|
||||
makePair(BACK, "Select"),
|
||||
makePair(A, "Cross"),
|
||||
makePair(B, "Circle"),
|
||||
makePair(X, "Square"),
|
||||
makePair(Y, "Triangle"),
|
||||
makePair(DU, "Up"),
|
||||
makePair(DD, "Down"),
|
||||
makePair(DL, "Left"),
|
||||
makePair(DR, "Right"),
|
||||
};
|
||||
}
|
||||
return _availableInputs;
|
||||
}
|
||||
|
||||
QString Joystick::getDefaultMappingConfig() const {
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
virtual QString getDefaultMappingConfig() const override;
|
||||
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
bool triggerHapticPulse(float strength, float duration, controller::Hand hand) override;
|
||||
|
||||
Joystick() : InputDevice("GamePad") {}
|
||||
~Joystick();
|
||||
|
@ -52,7 +54,10 @@ public:
|
|||
private:
|
||||
SDL_GameController* _sdlGameController;
|
||||
SDL_Joystick* _sdlJoystick;
|
||||
SDL_Haptic* _sdlHaptic;
|
||||
SDL_JoystickID _instanceId;
|
||||
|
||||
mutable controller::Input::NamedVector _availableInputs;
|
||||
};
|
||||
|
||||
#endif // hifi_Joystick_h
|
||||
|
|
|
@ -49,7 +49,7 @@ SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
|||
}
|
||||
|
||||
void SDL2Manager::init() {
|
||||
bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0);
|
||||
bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0);
|
||||
|
||||
if (initSuccess) {
|
||||
int joystickCount = SDL_NumJoysticks();
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"SDL2"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Sixense"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Spacemouse"}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue