mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 21:18:54 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into dk/3995
This commit is contained in:
commit
cb092d67dd
15 changed files with 100 additions and 58 deletions
|
@ -17,6 +17,8 @@ Documentation
|
||||||
=========
|
=========
|
||||||
Documentation is available at [docs.highfidelity.com](https://docs.highfidelity.com), if something is missing, please suggest it via a new job on Worklist (add to the hifi-docs project).
|
Documentation is available at [docs.highfidelity.com](https://docs.highfidelity.com), if something is missing, please suggest it via a new job on Worklist (add to the hifi-docs project).
|
||||||
|
|
||||||
|
There is also detailed [documentation on our coding standards](https://wiki.highfidelity.com/wiki/Coding_Standards).
|
||||||
|
|
||||||
Build Instructions
|
Build Instructions
|
||||||
=========
|
=========
|
||||||
All information required to build is found in the [build guide](BUILD.md).
|
All information required to build is found in the [build guide](BUILD.md).
|
||||||
|
|
4
cmake/externals/openvr/CMakeLists.txt
vendored
4
cmake/externals/openvr/CMakeLists.txt
vendored
|
@ -7,8 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL https://github.com/ValveSoftware/openvr/archive/v1.0.3.zip
|
URL https://github.com/ValveSoftware/openvr/archive/v1.0.6.zip
|
||||||
URL_MD5 b484b12901917cc739e40389583c8b0d
|
URL_MD5 f6892cd3a3078f505d03b4297f5a1951
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
|
|
@ -443,7 +443,7 @@ Rectangle {
|
||||||
rowDelegate: Rectangle { // The only way I know to specify a row height.
|
rowDelegate: Rectangle { // The only way I know to specify a row height.
|
||||||
// Size
|
// Size
|
||||||
height: rowHeight + (styleData.selected ? 15 : 0);
|
height: rowHeight + (styleData.selected ? 15 : 0);
|
||||||
color: rowColor(styleData.selected, styleData.alternate);
|
color: nearbyRowColor(styleData.selected, styleData.alternate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This Item refers to the contents of each Cell
|
// This Item refers to the contents of each Cell
|
||||||
|
@ -756,7 +756,7 @@ Rectangle {
|
||||||
resizable: false;
|
resizable: false;
|
||||||
}
|
}
|
||||||
TableViewColumn {
|
TableViewColumn {
|
||||||
role: "friends";
|
role: "connection";
|
||||||
title: "FRIEND";
|
title: "FRIEND";
|
||||||
width: actionButtonWidth;
|
width: actionButtonWidth;
|
||||||
movable: false;
|
movable: false;
|
||||||
|
@ -771,7 +771,7 @@ Rectangle {
|
||||||
rowDelegate: Rectangle {
|
rowDelegate: Rectangle {
|
||||||
// Size
|
// Size
|
||||||
height: rowHeight + (styleData.selected ? 15 : 0);
|
height: rowHeight + (styleData.selected ? 15 : 0);
|
||||||
color: rowColor(styleData.selected, styleData.alternate);
|
color: connectionsRowColor(styleData.selected, styleData.alternate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This Item refers to the contents of each Cell
|
// This Item refers to the contents of each Cell
|
||||||
|
@ -834,16 +834,16 @@ Rectangle {
|
||||||
// "Friends" checkbox
|
// "Friends" checkbox
|
||||||
HifiControlsUit.CheckBox {
|
HifiControlsUit.CheckBox {
|
||||||
id: friendsCheckBox;
|
id: friendsCheckBox;
|
||||||
visible: styleData.role === "friends" && model && model.userName !== myData.userName;
|
visible: styleData.role === "connection" && model && model.userName !== myData.userName;
|
||||||
// you would think that this would work:
|
// you would think that this would work:
|
||||||
// anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
|
// anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
|
||||||
// but no! you cannot anchor to a non-sibling or parent. So:
|
// but no! you cannot anchor to a non-sibling or parent. So:
|
||||||
x: parent.width/2 - boxSize/2
|
x: parent.width/2 - boxSize/2;
|
||||||
y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2
|
y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2;
|
||||||
checked: model ? (model["connection"] === "friend" ? true : false) : false;
|
checked: model && (model.connection === "friend");
|
||||||
boxSize: 24;
|
boxSize: 24;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var newValue = !(model["connection"] === "friend");
|
var newValue = model.connection !== "friend";
|
||||||
connectionsUserModel.setProperty(model.userIndex, styleData.role, newValue);
|
connectionsUserModel.setProperty(model.userIndex, styleData.role, newValue);
|
||||||
connectionsUserModelData[model.userIndex][styleData.role] = newValue; // Defensive programming
|
connectionsUserModelData[model.userIndex][styleData.role] = newValue; // Defensive programming
|
||||||
pal.sendToScript({method: newValue ? 'addFriend' : 'removeFriend', params: model.userName});
|
pal.sendToScript({method: newValue ? 'addFriend' : 'removeFriend', params: model.userName});
|
||||||
|
@ -1210,9 +1210,12 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function rowColor(selected, alternate) {
|
function nearbyRowColor(selected, alternate) {
|
||||||
return selected ? hifi.colors.orangeHighlight : alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd;
|
return selected ? hifi.colors.orangeHighlight : alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd;
|
||||||
}
|
}
|
||||||
|
function connectionsRowColor(selected, alternate) {
|
||||||
|
return selected ? hifi.colors.lightBlueHighlight : alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd;
|
||||||
|
}
|
||||||
function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml
|
function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml
|
||||||
var data = optionalData || nearbyUserModelData, length = data.length;
|
var data = optionalData || nearbyUserModelData, length = data.length;
|
||||||
for (var i = 0; i < length; i++) {
|
for (var i = 0; i < length; i++) {
|
||||||
|
@ -1283,6 +1286,8 @@ Rectangle {
|
||||||
selectionTimer.userIndex = userIndex;
|
selectionTimer.userIndex = userIndex;
|
||||||
selectionTimer.start();
|
selectionTimer.start();
|
||||||
}
|
}
|
||||||
|
// in any case make sure we are in the nearby tab
|
||||||
|
activeTab="nearbyTab";
|
||||||
break;
|
break;
|
||||||
// Received an "updateUsername()" request from the JS
|
// Received an "updateUsername()" request from the JS
|
||||||
case 'updateUsername':
|
case 'updateUsername':
|
||||||
|
|
|
@ -72,6 +72,7 @@ Item {
|
||||||
readonly property color magentaAccent: "#A2277C"
|
readonly property color magentaAccent: "#A2277C"
|
||||||
readonly property color checkboxCheckedRed: "#FF0000"
|
readonly property color checkboxCheckedRed: "#FF0000"
|
||||||
readonly property color checkboxCheckedBorderRed: "#D00000"
|
readonly property color checkboxCheckedBorderRed: "#D00000"
|
||||||
|
readonly property color lightBlueHighlight: "#d6f6ff"
|
||||||
|
|
||||||
// Semitransparent
|
// Semitransparent
|
||||||
readonly property color darkGray30: "#4d121212"
|
readonly property color darkGray30: "#4d121212"
|
||||||
|
|
|
@ -74,7 +74,7 @@ void AnimationReader::run() {
|
||||||
// Parse the FBX directly from the QNetworkReply
|
// Parse the FBX directly from the QNetworkReply
|
||||||
FBXGeometry::Pointer fbxgeo;
|
FBXGeometry::Pointer fbxgeo;
|
||||||
if (_url.path().toLower().endsWith(".fbx")) {
|
if (_url.path().toLower().endsWith(".fbx")) {
|
||||||
fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path()));
|
fbxgeo.reset(readFBX(_data, QVariantHash(), _url));
|
||||||
} else {
|
} else {
|
||||||
QString errorStr("usupported format");
|
QString errorStr("usupported format");
|
||||||
emit onError(299, errorStr);
|
emit onError(299, errorStr);
|
||||||
|
|
|
@ -182,6 +182,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
||||||
if (!wantsLocked) {
|
if (!wantsLocked) {
|
||||||
EntityItemProperties tempProperties;
|
EntityItemProperties tempProperties;
|
||||||
tempProperties.setLocked(wantsLocked);
|
tempProperties.setLocked(wantsLocked);
|
||||||
|
tempProperties.setLastEdited(properties.getLastEdited());
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
AACube queryCube = entity->getQueryAACube(success);
|
AACube queryCube = entity->getQueryAACube(success);
|
||||||
|
|
|
@ -376,10 +376,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool checkMaterialsHaveTextures(const QHash<QString, FBXMaterial>& materials,
|
bool checkMaterialsHaveTextures(const QHash<QString, FBXMaterial>& materials,
|
||||||
const QHash<QString, QByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) {
|
const QHash<QString, QByteArray>& textureFilepaths, const QMultiMap<QString, QString>& _connectionChildMap) {
|
||||||
foreach (const QString& materialID, materials.keys()) {
|
foreach (const QString& materialID, materials.keys()) {
|
||||||
foreach (const QString& childID, _connectionChildMap.values(materialID)) {
|
foreach (const QString& childID, _connectionChildMap.values(materialID)) {
|
||||||
if (textureFilenames.contains(childID)) {
|
if (textureFilepaths.contains(childID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,21 +443,48 @@ FBXLight extractLight(const FBXNode& object) {
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
QByteArray fixedTextureFilepath(QByteArray fbxRelativeFilepath, QUrl url) {
|
||||||
QString path = QFileInfo(url).path();
|
// first setup a QFileInfo for the passed relative filepath, with backslashes replaced by forward slashes
|
||||||
QByteArray filename = filepath;
|
auto fileInfo = QFileInfo { fbxRelativeFilepath.replace("\\", "/") };
|
||||||
QFileInfo checkFile(path + "/" + filepath);
|
|
||||||
|
|
||||||
// check if the file exists at the RelativeFilename
|
#ifndef Q_OS_WIN
|
||||||
if (!(checkFile.exists() && checkFile.isFile())) {
|
// it turns out that absolute windows paths starting with drive letters look like relative paths to QFileInfo on UNIX
|
||||||
// if not, assume it is in the fbx directory
|
// so we add a check for that here to work around it
|
||||||
filename = filename.mid(filename.lastIndexOf('/') + 1);
|
bool isRelative = fbxRelativeFilepath[1] != ':' && fileInfo.isRelative();
|
||||||
|
#else
|
||||||
|
bool isRelative = fileInfo.isRelative();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (isRelative) {
|
||||||
|
// the RelativeFilename pulled from the FBX is already correctly relative
|
||||||
|
// so simply return this as the filepath to use
|
||||||
|
return fbxRelativeFilepath;
|
||||||
|
} else {
|
||||||
|
// the RelativeFilename pulled from the FBX is an absolute path
|
||||||
|
|
||||||
|
// use the URL to figure out where the FBX is being loaded from
|
||||||
|
auto filename = fileInfo.fileName();
|
||||||
|
|
||||||
|
if (url.isLocalFile()) {
|
||||||
|
// the FBX is being loaded from the local filesystem
|
||||||
|
|
||||||
|
if (fileInfo.exists() && fileInfo.isFile()) {
|
||||||
|
// found a file at the absolute path in the FBX, return that path
|
||||||
|
return fbxRelativeFilepath;
|
||||||
|
} else {
|
||||||
|
// didn't find a file at the absolute path, assume it is right beside the FBX
|
||||||
|
// return just the filename as the relative path
|
||||||
|
return filename.toUtf8();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is a remote file, meaning we can't really do anything with the absolute path to the texture
|
||||||
|
// so assume it will be right beside the fbx
|
||||||
|
return filename.toUtf8();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) {
|
FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QUrl& url) {
|
||||||
const FBXNode& node = _fbxNode;
|
const FBXNode& node = _fbxNode;
|
||||||
QMap<QString, ExtractedMesh> meshes;
|
QMap<QString, ExtractedMesh> meshes;
|
||||||
QHash<QString, QString> modelIDsToNames;
|
QHash<QString, QString> modelIDsToNames;
|
||||||
|
@ -833,11 +860,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
const int MODEL_UV_SCALING_MIN_SIZE = 2;
|
const int MODEL_UV_SCALING_MIN_SIZE = 2;
|
||||||
const int CROPPING_MIN_SIZE = 4;
|
const int CROPPING_MIN_SIZE = 4;
|
||||||
if (subobject.name == "RelativeFilename" && subobject.properties.length() >= RELATIVE_FILENAME_MIN_SIZE) {
|
if (subobject.name == "RelativeFilename" && subobject.properties.length() >= RELATIVE_FILENAME_MIN_SIZE) {
|
||||||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
auto filepath = fixedTextureFilepath(subobject.properties.at(0).toByteArray(), url);
|
||||||
QByteArray filepath = filename.replace('\\', '/');
|
|
||||||
filename = fileOnUrl(filepath, url);
|
|
||||||
_textureFilepaths.insert(getID(object.properties), filepath);
|
_textureFilepaths.insert(getID(object.properties), filepath);
|
||||||
_textureFilenames.insert(getID(object.properties), filename);
|
|
||||||
} else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) {
|
} else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) {
|
||||||
// trim the name from the timestamp
|
// trim the name from the timestamp
|
||||||
QString name = QString(subobject.properties.at(0).toByteArray());
|
QString name = QString(subobject.properties.at(0).toByteArray());
|
||||||
|
@ -930,7 +955,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
if (subobject.name == "RelativeFilename") {
|
if (subobject.name == "RelativeFilename") {
|
||||||
filepath= subobject.properties.at(0).toByteArray();
|
filepath = subobject.properties.at(0).toByteArray();
|
||||||
filepath = filepath.replace('\\', '/');
|
filepath = filepath.replace('\\', '/');
|
||||||
|
|
||||||
} else if (subobject.name == "Content" && !subobject.properties.isEmpty()) {
|
} else if (subobject.name == "Content" && !subobject.properties.isEmpty()) {
|
||||||
|
@ -1502,7 +1527,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
geometry.materials = _fbxMaterials;
|
geometry.materials = _fbxMaterials;
|
||||||
|
|
||||||
// see if any materials have texture children
|
// see if any materials have texture children
|
||||||
bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilenames, _connectionChildMap);
|
bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilepaths, _connectionChildMap);
|
||||||
|
|
||||||
for (QMap<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
for (QMap<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
||||||
ExtractedMesh& extracted = it.value();
|
ExtractedMesh& extracted = it.value();
|
||||||
|
@ -1547,7 +1572,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
|
|
||||||
materialIndex++;
|
materialIndex++;
|
||||||
|
|
||||||
} else if (_textureFilenames.contains(childID)) {
|
} else if (_textureFilepaths.contains(childID)) {
|
||||||
FBXTexture texture = getTexture(childID);
|
FBXTexture texture = getTexture(childID);
|
||||||
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
||||||
int partTexture = extracted.partMaterialTextures.at(j).second;
|
int partTexture = extracted.partMaterialTextures.at(j).second;
|
||||||
|
@ -1818,13 +1843,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
return geometryPtr;
|
return geometryPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
|
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps, float lightmapLevel) {
|
||||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||||
buffer.open(QIODevice::ReadOnly);
|
buffer.open(QIODevice::ReadOnly);
|
||||||
return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel);
|
return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
|
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps, float lightmapLevel) {
|
||||||
FBXReader reader;
|
FBXReader reader;
|
||||||
reader._fbxNode = FBXReader::parseFBX(device);
|
reader._fbxNode = FBXReader::parseFBX(device);
|
||||||
reader._loadLightmaps = loadLightmaps;
|
reader._loadLightmaps = loadLightmaps;
|
||||||
|
|
|
@ -268,7 +268,7 @@ class FBXGeometry {
|
||||||
public:
|
public:
|
||||||
using Pointer = std::shared_ptr<FBXGeometry>;
|
using Pointer = std::shared_ptr<FBXGeometry>;
|
||||||
|
|
||||||
QString originalURL;
|
QUrl originalURL;
|
||||||
QString author;
|
QString author;
|
||||||
QString applicationName; ///< the name of the application that generated the model
|
QString applicationName; ///< the name of the application that generated the model
|
||||||
|
|
||||||
|
@ -330,11 +330,11 @@ Q_DECLARE_METATYPE(FBXGeometry::Pointer)
|
||||||
|
|
||||||
/// Reads FBX geometry from the supplied model and mapping data.
|
/// Reads FBX geometry from the supplied model and mapping data.
|
||||||
/// \exception QString if an error occurs in parsing
|
/// \exception QString if an error occurs in parsing
|
||||||
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QUrl& url = QUrl(), bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||||
|
|
||||||
/// Reads FBX geometry from the supplied model and mapping data.
|
/// Reads FBX geometry from the supplied model and mapping data.
|
||||||
/// \exception QString if an error occurs in parsing
|
/// \exception QString if an error occurs in parsing
|
||||||
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl(), bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||||
|
|
||||||
class TextureParam {
|
class TextureParam {
|
||||||
public:
|
public:
|
||||||
|
@ -402,19 +402,17 @@ public:
|
||||||
FBXNode _fbxNode;
|
FBXNode _fbxNode;
|
||||||
static FBXNode parseFBX(QIODevice* device);
|
static FBXNode parseFBX(QIODevice* device);
|
||||||
|
|
||||||
FBXGeometry* extractFBXGeometry(const QVariantHash& mapping, const QString& url);
|
FBXGeometry* extractFBXGeometry(const QVariantHash& mapping, const QUrl& url);
|
||||||
|
|
||||||
ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex);
|
ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex);
|
||||||
QHash<QString, ExtractedMesh> meshes;
|
QHash<QString, ExtractedMesh> meshes;
|
||||||
static void buildModelMesh(FBXMesh& extractedMesh, const QString& url);
|
static void buildModelMesh(FBXMesh& extractedMesh, const QUrl& url);
|
||||||
|
|
||||||
FBXTexture getTexture(const QString& textureID);
|
FBXTexture getTexture(const QString& textureID);
|
||||||
|
|
||||||
QHash<QString, QString> _textureNames;
|
QHash<QString, QString> _textureNames;
|
||||||
// Hashes the original RelativeFilename of textures
|
// Hashes the original RelativeFilename of textures
|
||||||
QHash<QString, QByteArray> _textureFilepaths;
|
QHash<QString, QByteArray> _textureFilepaths;
|
||||||
// Hashes the place to look for textures, in case they are not inlined
|
|
||||||
QHash<QString, QByteArray> _textureFilenames;
|
|
||||||
// Hashes texture content by filepath, in case they are inlined
|
// Hashes texture content by filepath, in case they are inlined
|
||||||
QHash<QByteArray, QByteArray> _textureContent;
|
QHash<QByteArray, QByteArray> _textureContent;
|
||||||
QHash<QString, TextureParam> _textureParams;
|
QHash<QString, TextureParam> _textureParams;
|
||||||
|
|
|
@ -85,12 +85,7 @@ FBXTexture FBXReader::getTexture(const QString& textureID) {
|
||||||
FBXTexture texture;
|
FBXTexture texture;
|
||||||
const QByteArray& filepath = _textureFilepaths.value(textureID);
|
const QByteArray& filepath = _textureFilepaths.value(textureID);
|
||||||
texture.content = _textureContent.value(filepath);
|
texture.content = _textureContent.value(filepath);
|
||||||
|
texture.filename = filepath;
|
||||||
if (texture.content.isEmpty()) { // the content is not inlined
|
|
||||||
texture.filename = _textureFilenames.value(textureID);
|
|
||||||
} else { // use supplied filepath for inlined content
|
|
||||||
texture.filename = filepath;
|
|
||||||
}
|
|
||||||
|
|
||||||
texture.name = _textureNames.value(textureID);
|
texture.name = _textureNames.value(textureID);
|
||||||
texture.transform.setIdentity();
|
texture.transform.setIdentity();
|
||||||
|
@ -155,7 +150,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
||||||
|
|
||||||
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
|
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
|
||||||
foreach(const QString& childTextureID, _connectionChildMap.values(diffuseTextureID)) {
|
foreach(const QString& childTextureID, _connectionChildMap.values(diffuseTextureID)) {
|
||||||
if (_textureFilenames.contains(childTextureID)) {
|
if (_textureFilepaths.contains(childTextureID)) {
|
||||||
diffuseTexture = getTexture(diffuseTextureID);
|
diffuseTexture = getTexture(diffuseTextureID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
return data.extracted;
|
return data.extracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QUrl& url) {
|
||||||
static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*");
|
static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*");
|
||||||
|
|
||||||
unsigned int totalSourceIndices = 0;
|
unsigned int totalSourceIndices = 0;
|
||||||
|
|
|
@ -72,6 +72,15 @@ Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setKtxBacking(const std::string& filename) {
|
void Texture::setKtxBacking(const std::string& filename) {
|
||||||
|
// Check the KTX file for validity before using it as backing storage
|
||||||
|
{
|
||||||
|
ktx::StoragePointer storage { new storage::FileStorage(filename.c_str()) };
|
||||||
|
auto ktxPointer = ktx::KTX::create(storage);
|
||||||
|
if (!ktxPointer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto newBacking = std::unique_ptr<Storage>(new KtxStorage(filename));
|
auto newBacking = std::unique_ptr<Storage>(new KtxStorage(filename));
|
||||||
setStorage(newBacking);
|
setStorage(newBacking);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +194,12 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) {
|
Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) {
|
||||||
ktx::KTXDescriptor descriptor { ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) })->toDescriptor() };
|
std::unique_ptr<ktx::KTX> ktxPointer = ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) });
|
||||||
|
if (!ktxPointer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ktx::KTXDescriptor descriptor { ktxPointer->toDescriptor() };
|
||||||
const auto& header = descriptor.header;
|
const auto& header = descriptor.header;
|
||||||
|
|
||||||
Format mipFormat = Format::COLOR_BGRA_32;
|
Format mipFormat = Format::COLOR_BGRA_32;
|
||||||
|
|
|
@ -173,7 +173,7 @@ void GeometryReader::run() {
|
||||||
FBXGeometry::Pointer fbxGeometry;
|
FBXGeometry::Pointer fbxGeometry;
|
||||||
|
|
||||||
if (_url.path().toLower().endsWith(".fbx")) {
|
if (_url.path().toLower().endsWith(".fbx")) {
|
||||||
fbxGeometry.reset(readFBX(_data, _mapping, _url.path()));
|
fbxGeometry.reset(readFBX(_data, _mapping, _url));
|
||||||
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
||||||
throw QString("empty geometry, possibly due to an unsupported FBX version");
|
throw QString("empty geometry, possibly due to an unsupported FBX version");
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,8 +277,8 @@ public:
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
static const vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
static const vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
||||||
static const vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
|
static const vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
|
||||||
|
|
||||||
vr::Texture_t texture{ (void*)_colors[currentColorBuffer], vr::API_OpenGL, vr::ColorSpace_Auto };
|
vr::Texture_t texture{ (void*)_colors[currentColorBuffer], vr::TextureType_OpenGL, vr::ColorSpace_Auto };
|
||||||
vr::VRCompositor()->Submit(vr::Eye_Left, &texture, &leftBounds);
|
vr::VRCompositor()->Submit(vr::Eye_Left, &texture, &leftBounds);
|
||||||
vr::VRCompositor()->Submit(vr::Eye_Right, &texture, &rightBounds);
|
vr::VRCompositor()->Submit(vr::Eye_Right, &texture, &rightBounds);
|
||||||
_plugin._presentRate.increment();
|
_plugin._presentRate.increment();
|
||||||
|
@ -422,7 +422,7 @@ bool OpenVrDisplayPlugin::internalActivate() {
|
||||||
withNonPresentThreadLock([&] {
|
withNonPresentThreadLock([&] {
|
||||||
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
||||||
_eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye));
|
_eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye));
|
||||||
_eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
|
_eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||||
});
|
});
|
||||||
// FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
|
// FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
|
||||||
_cullingProjection = _eyeProjections[0];
|
_cullingProjection = _eyeProjections[0];
|
||||||
|
@ -639,7 +639,7 @@ void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
_submitThread->waitForPresent();
|
_submitThread->waitForPresent();
|
||||||
} else {
|
} else {
|
||||||
GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0));
|
GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0));
|
||||||
vr::Texture_t vrTexture { (void*)glTexId, vr::API_OpenGL, vr::ColorSpace_Auto };
|
vr::Texture_t vrTexture { (void*)glTexId, vr::TextureType_OpenGL, vr::ColorSpace_Auto };
|
||||||
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
|
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
|
||||||
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);
|
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);
|
||||||
vr::VRCompositor()->PostPresentHandoff();
|
vr::VRCompositor()->PostPresentHandoff();
|
||||||
|
|
|
@ -114,7 +114,7 @@ void releaseOpenVrSystem() {
|
||||||
|
|
||||||
// HACK: workaround openvr crash, call submit with an invalid texture, right before VR_Shutdown.
|
// HACK: workaround openvr crash, call submit with an invalid texture, right before VR_Shutdown.
|
||||||
const GLuint INVALID_GL_TEXTURE_HANDLE = -1;
|
const GLuint INVALID_GL_TEXTURE_HANDLE = -1;
|
||||||
vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto };
|
vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::TextureType_OpenGL, vr::ColorSpace_Auto };
|
||||||
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 };
|
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 };
|
||||||
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 };
|
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 };
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
||||||
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
|
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
|
||||||
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
||||||
|
|
||||||
// collect raw poses
|
// collect poses for all generic trackers
|
||||||
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||||
handleTrackedObject(i, inputCalibrationData);
|
handleTrackedObject(i, inputCalibrationData);
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,7 @@ void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceInde
|
||||||
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
||||||
|
|
||||||
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
||||||
|
_system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_GenericTracker &&
|
||||||
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid &&
|
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid &&
|
||||||
poseIndex <= controller::TRACKED_OBJECT_15) {
|
poseIndex <= controller::TRACKED_OBJECT_15) {
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@ void ViveControllerManager::InputDevice::handleHandController(float deltaTime, u
|
||||||
handlePoseEvent(deltaTime, inputCalibrationData, mat, linearVelocity, angularVelocity, isLeftHand);
|
handlePoseEvent(deltaTime, inputCalibrationData, mat, linearVelocity, angularVelocity, isLeftHand);
|
||||||
|
|
||||||
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
||||||
if (_system->GetControllerState(deviceIndex, &controllerState)) {
|
if (_system->GetControllerState(deviceIndex, &controllerState, sizeof(vr::VRControllerState_t))) {
|
||||||
// process each button
|
// process each button
|
||||||
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
||||||
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
||||||
|
|
Loading…
Reference in a new issue