mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 09:24:00 +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 <OctalCode.h>
|
||||
#include <Shape.h>
|
||||
#include <gpu/Format.h>
|
||||
|
||||
|
||||
#include "FBXReader.h"
|
||||
#include "ModelFormatLogging.h"
|
||||
|
@ -1276,6 +1278,151 @@ FBXLight extractLight(const FBXNode& object) {
|
|||
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) {
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
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);
|
||||
|
||||
# if USE_MODEL_MESH
|
||||
buildModelMesh(extracted);
|
||||
# endif
|
||||
|
||||
geometry.meshes.append(extracted.mesh);
|
||||
int meshIndex = geometry.meshes.size() - 1;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_FBXReader_h
|
||||
#define hifi_FBXReader_h
|
||||
|
||||
#define USE_MODEL_MESH 1
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QUrl>
|
||||
#include <QVarLengthArray>
|
||||
|
@ -154,6 +156,9 @@ public:
|
|||
bool hasEmissiveTexture() const;
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue