mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 20:48:56 +02:00
port code from samcake's model branch
This commit is contained in:
parent
b658c26799
commit
0db5ddc5b7
2 changed files with 156 additions and 0 deletions
|
@ -28,6 +28,8 @@
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
#include <Shape.h>
|
#include <Shape.h>
|
||||||
|
#include <gpu/Format.h>
|
||||||
|
|
||||||
|
|
||||||
#include "FBXReader.h"
|
#include "FBXReader.h"
|
||||||
#include "ModelFormatLogging.h"
|
#include "ModelFormatLogging.h"
|
||||||
|
@ -1276,6 +1278,151 @@ FBXLight extractLight(const FBXNode& object) {
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if USE_MODEL_MESH
|
||||||
|
void buildModelMesh(ExtractedMesh& extracted) {
|
||||||
|
if (extracted.mesh.vertices.size() == 0) {
|
||||||
|
extracted.mesh._mesh = model::Mesh();
|
||||||
|
qDebug() << "buildModelMesh failed -- no vertices";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FBXMesh& fbxMesh = extracted.mesh;
|
||||||
|
model::Mesh mesh;
|
||||||
|
|
||||||
|
// Grab the vertices in a buffer
|
||||||
|
gpu::BufferPointer vb(new gpu::Buffer());
|
||||||
|
vb->setData(extracted.mesh.vertices.size() * sizeof(glm::vec3),
|
||||||
|
(const gpu::Byte*) extracted.mesh.vertices.data());
|
||||||
|
gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
|
mesh.setVertexBuffer(vbv);
|
||||||
|
|
||||||
|
// evaluate all attribute channels sizes
|
||||||
|
int normalsSize = fbxMesh.normals.size() * sizeof(glm::vec3);
|
||||||
|
int tangentsSize = fbxMesh.tangents.size() * sizeof(glm::vec3);
|
||||||
|
int colorsSize = fbxMesh.colors.size() * sizeof(glm::vec3);
|
||||||
|
int texCoordsSize = fbxMesh.texCoords.size() * sizeof(glm::vec2);
|
||||||
|
int texCoords1Size = fbxMesh.texCoords1.size() * sizeof(glm::vec2);
|
||||||
|
int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(glm::vec4);
|
||||||
|
int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(glm::vec4);
|
||||||
|
|
||||||
|
int normalsOffset = 0;
|
||||||
|
int tangentsOffset = normalsOffset + normalsSize;
|
||||||
|
int colorsOffset = tangentsOffset + tangentsSize;
|
||||||
|
int texCoordsOffset = colorsOffset + colorsSize;
|
||||||
|
int texCoords1Offset = texCoordsOffset + texCoordsSize;
|
||||||
|
int clusterIndicesOffset = texCoords1Offset + texCoords1Size;
|
||||||
|
int clusterWeightsOffset = clusterIndicesOffset + clusterIndicesSize;
|
||||||
|
int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize;
|
||||||
|
|
||||||
|
// Copy all attribute data in a single attribute buffer
|
||||||
|
gpu::BufferPointer attribBuffer(new gpu::Buffer());
|
||||||
|
attribBuffer->resize(totalAttributeSize);
|
||||||
|
attribBuffer->setSubData(normalsOffset, normalsSize, (gpu::Byte*) fbxMesh.normals.constData());
|
||||||
|
attribBuffer->setSubData(tangentsOffset, tangentsSize, (gpu::Byte*) fbxMesh.tangents.constData());
|
||||||
|
attribBuffer->setSubData(colorsOffset, colorsSize, (gpu::Byte*) fbxMesh.colors.constData());
|
||||||
|
attribBuffer->setSubData(texCoordsOffset, texCoordsSize, (gpu::Byte*) fbxMesh.texCoords.constData());
|
||||||
|
attribBuffer->setSubData(texCoords1Offset, texCoords1Size, (gpu::Byte*) fbxMesh.texCoords1.constData());
|
||||||
|
attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) fbxMesh.clusterIndices.constData());
|
||||||
|
attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (gpu::Byte*) fbxMesh.clusterWeights.constData());
|
||||||
|
|
||||||
|
if (normalsSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::NORMAL,
|
||||||
|
model::BufferView(attribBuffer, normalsOffset, normalsSize,
|
||||||
|
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)));
|
||||||
|
}
|
||||||
|
if (tangentsSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::TANGENT,
|
||||||
|
model::BufferView(attribBuffer, tangentsOffset, tangentsSize,
|
||||||
|
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)));
|
||||||
|
}
|
||||||
|
if (colorsSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::COLOR,
|
||||||
|
model::BufferView(attribBuffer, colorsOffset, colorsSize,
|
||||||
|
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB)));
|
||||||
|
}
|
||||||
|
if (texCoordsSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::TEXCOORD,
|
||||||
|
model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize,
|
||||||
|
gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)));
|
||||||
|
}
|
||||||
|
if (texCoords1Size) {
|
||||||
|
mesh.addAttribute(gpu::Stream::TEXCOORD1,
|
||||||
|
model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size,
|
||||||
|
gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)));
|
||||||
|
}
|
||||||
|
if (clusterIndicesSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
|
||||||
|
model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
|
||||||
|
gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW)));
|
||||||
|
}
|
||||||
|
if (clusterWeightsSize) {
|
||||||
|
mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT,
|
||||||
|
model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize,
|
||||||
|
gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int totalIndices = 0;
|
||||||
|
|
||||||
|
foreach(const FBXMeshPart& part, extracted.mesh.parts) {
|
||||||
|
totalIndices += (part.quadIndices.size() + part.triangleIndices.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! totalIndices) {
|
||||||
|
extracted.mesh._mesh = model::Mesh();
|
||||||
|
qDebug() << "buildModelMesh failed -- no indices";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::BufferPointer ib(new gpu::Buffer());
|
||||||
|
ib->resize(totalIndices * sizeof(int));
|
||||||
|
|
||||||
|
int indexNum = 0;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
std::vector< model::Mesh::Part > parts;
|
||||||
|
|
||||||
|
foreach(const FBXMeshPart& part, extracted.mesh.parts) {
|
||||||
|
model::Mesh::Part quadPart(indexNum, part.quadIndices.size(), 0, model::Mesh::QUADS);
|
||||||
|
if (quadPart._numIndices) {
|
||||||
|
parts.push_back(quadPart);
|
||||||
|
ib->setSubData(offset, part.quadIndices.size() * sizeof(int),
|
||||||
|
(gpu::Byte*) part.quadIndices.constData());
|
||||||
|
offset += part.quadIndices.size() * sizeof(int);
|
||||||
|
indexNum += part.quadIndices.size();
|
||||||
|
}
|
||||||
|
model::Mesh::Part triPart(indexNum, part.triangleIndices.size(), 0, model::Mesh::TRIANGLES);
|
||||||
|
if (triPart._numIndices) {
|
||||||
|
ib->setSubData(offset, part.triangleIndices.size() * sizeof(int),
|
||||||
|
(gpu::Byte*) part.triangleIndices.constData());
|
||||||
|
offset += part.triangleIndices.size() * sizeof(int);
|
||||||
|
indexNum += part.triangleIndices.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::BufferView ibv(ib, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ));
|
||||||
|
mesh.setIndexBuffer(ibv);
|
||||||
|
|
||||||
|
if (parts.size()) {
|
||||||
|
gpu::BufferPointer pb(new gpu::Buffer());
|
||||||
|
pb->setData(parts.size() * sizeof(model::Mesh::Part), (const gpu::Byte*) parts.data());
|
||||||
|
gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW));
|
||||||
|
mesh.setPartBuffer(pbv);
|
||||||
|
} else {
|
||||||
|
extracted.mesh._mesh = model::Mesh();
|
||||||
|
qDebug() << "buildModelMesh failed -- no parts";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// model::Box box =
|
||||||
|
mesh.evalPartBound(0);
|
||||||
|
|
||||||
|
extracted.mesh._mesh = mesh;
|
||||||
|
}
|
||||||
|
#endif // USE_MODEL_MESH
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||||
QHash<QString, ExtractedMesh> meshes;
|
QHash<QString, ExtractedMesh> meshes;
|
||||||
QHash<QString, QString> modelIDsToNames;
|
QHash<QString, QString> modelIDsToNames;
|
||||||
|
@ -2431,6 +2578,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
||||||
|
|
||||||
|
# if USE_MODEL_MESH
|
||||||
|
buildModelMesh(extracted);
|
||||||
|
# endif
|
||||||
|
|
||||||
geometry.meshes.append(extracted.mesh);
|
geometry.meshes.append(extracted.mesh);
|
||||||
int meshIndex = geometry.meshes.size() - 1;
|
int meshIndex = geometry.meshes.size() - 1;
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_FBXReader_h
|
#ifndef hifi_FBXReader_h
|
||||||
#define hifi_FBXReader_h
|
#define hifi_FBXReader_h
|
||||||
|
|
||||||
|
#define USE_MODEL_MESH 1
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVarLengthArray>
|
#include <QVarLengthArray>
|
||||||
|
@ -154,6 +156,9 @@ public:
|
||||||
bool hasEmissiveTexture() const;
|
bool hasEmissiveTexture() const;
|
||||||
|
|
||||||
unsigned int meshIndex; // the order the meshes appeared in the object file
|
unsigned int meshIndex; // the order the meshes appeared in the object file
|
||||||
|
# if USE_MODEL_MESH
|
||||||
|
model::Mesh _mesh;
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A single animation frame extracted from an FBX document.
|
/// A single animation frame extracted from an FBX document.
|
||||||
|
|
Loading…
Reference in a new issue