Format everything.
This commit is contained in:
parent
b89d4cd0e0
commit
1bcdf9271e
|
@ -229,11 +229,11 @@ static void ReadMesh(
|
|||
targetShapes.push_back(&shape);
|
||||
auto& blendChannel = blendShapes.GetBlendChannel(channelIx);
|
||||
|
||||
rawSurface.blendChannels.push_back(
|
||||
RawBlendChannel{static_cast<float>(blendChannel.deformPercent),
|
||||
shape.normals.LayerPresent(),
|
||||
shape.tangents.LayerPresent(),
|
||||
blendChannel.name});
|
||||
rawSurface.blendChannels.push_back(RawBlendChannel{
|
||||
static_cast<float>(blendChannel.deformPercent),
|
||||
shape.normals.LayerPresent(),
|
||||
shape.tangents.LayerPresent(),
|
||||
blendChannel.name});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,14 +59,13 @@ FbxSkinningAccess::FbxSkinningAccess(const FbxMesh* pMesh, FbxScene* pScene, Fbx
|
|||
continue;
|
||||
}
|
||||
|
||||
vertexSkinning[clusterIndices[i]].push_back(FbxVertexSkinningInfo{(int) clusterIndex, (float)clusterWeights[i]});
|
||||
|
||||
vertexSkinning[clusterIndices[i]].push_back(
|
||||
FbxVertexSkinningInfo{(int)clusterIndex, (float)clusterWeights[i]});
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vertexSkinning.size(); i++)
|
||||
maxBoneInfluences = std::max((int) vertexSkinning[i].size(), maxBoneInfluences);
|
||||
|
||||
for (int i = 0; i < vertexSkinning.size(); i++)
|
||||
maxBoneInfluences = std::max((int)vertexSkinning[i].size(), maxBoneInfluences);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,17 +23,14 @@ struct FbxVertexSkinningInfo {
|
|||
float weight;
|
||||
};
|
||||
|
||||
|
||||
class FbxSkinningAccess {
|
||||
public:
|
||||
|
||||
FbxSkinningAccess(const FbxMesh* pMesh, FbxScene* pScene, FbxNode* pNode);
|
||||
|
||||
bool IsSkinned() const {
|
||||
return (vertexSkinning.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
int GetNodeCount() const {
|
||||
return (int)jointNodes.size();
|
||||
}
|
||||
|
@ -62,10 +59,11 @@ class FbxSkinningAccess {
|
|||
const FbxAMatrix& GetInverseBindMatrix(const int jointIndex) const {
|
||||
return inverseBindMatrices[jointIndex];
|
||||
}
|
||||
|
||||
const std::vector<FbxVertexSkinningInfo> GetVertexSkinningInfo(const int controlPointIndex) const {
|
||||
return vertexSkinning[controlPointIndex];
|
||||
}
|
||||
|
||||
const std::vector<FbxVertexSkinningInfo> GetVertexSkinningInfo(
|
||||
const int controlPointIndex) const {
|
||||
return vertexSkinning[controlPointIndex];
|
||||
}
|
||||
|
||||
private:
|
||||
int rootIndex;
|
||||
|
|
|
@ -45,8 +45,7 @@ FbxMaterialsAccess::FbxMaterialsAccess(
|
|||
continue;
|
||||
}
|
||||
|
||||
auto* surfaceMaterial =
|
||||
mesh->GetNode()->GetSrcObject<FbxSurfaceMaterial>(materialNum);
|
||||
auto* surfaceMaterial = mesh->GetNode()->GetSrcObject<FbxSurfaceMaterial>(materialNum);
|
||||
|
||||
if (!surfaceMaterial) {
|
||||
if (++warnMtrCount == 1) {
|
||||
|
@ -67,7 +66,6 @@ FbxMaterialsAccess::FbxMaterialsAccess(
|
|||
userProperties.resize(materialNum + 1);
|
||||
}
|
||||
if (surfaceMaterial && userProperties[materialNum].empty()) {
|
||||
|
||||
FbxProperty objectProperty = surfaceMaterial->GetFirstProperty();
|
||||
while (objectProperty.IsValid()) {
|
||||
if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
|
||||
|
|
|
@ -640,20 +640,21 @@ ModelData* Raw2Gltf(
|
|||
for (int jj = 0; jj < surfaceModel.GetVertexCount(); jj++) {
|
||||
auto blendVertex = surfaceModel.GetVertex(jj).blends[channelIx];
|
||||
shapeBounds.AddPoint(blendVertex.position);
|
||||
bool isSparseVertex = options.disableSparseBlendShapes; // If sparse is off, add all vertices
|
||||
bool isSparseVertex =
|
||||
options.disableSparseBlendShapes; // If sparse is off, add all vertices
|
||||
// Check to see whether position, normal or tangent deviates from base mesh and flag as
|
||||
// sparse.
|
||||
if (blendVertex.position.Length() > 0.00) {
|
||||
isSparseVertex = true;
|
||||
}
|
||||
// if (options.useBlendShapeNormals && channel.hasNormals &&
|
||||
// blendVertex.normal.Length() > 0.00) {
|
||||
// isSparseVertex = true;
|
||||
// }
|
||||
// if (options.useBlendShapeTangents && channel.hasTangents &&
|
||||
// blendVertex.tangent.Length() > 0.00) {
|
||||
// isSparseVertex = true;
|
||||
// }
|
||||
// if (options.useBlendShapeNormals && channel.hasNormals &&
|
||||
// blendVertex.normal.Length() > 0.00) {
|
||||
// isSparseVertex = true;
|
||||
// }
|
||||
// if (options.useBlendShapeTangents && channel.hasTangents &&
|
||||
// blendVertex.tangent.Length() > 0.00) {
|
||||
// isSparseVertex = true;
|
||||
// }
|
||||
if (isSparseVertex == true) {
|
||||
sparseIndices.push_back(jj);
|
||||
positions.push_back(blendVertex.position);
|
||||
|
|
|
@ -213,7 +213,8 @@ std::shared_ptr<TextureData> TextureBuilder::simple(int rawTexIndex, const std::
|
|||
}
|
||||
if (!image) {
|
||||
// fallback is tiny transparent PNG
|
||||
// image = new ImageData(textureName, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==");
|
||||
// image = new ImageData(textureName,
|
||||
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ class TextureBuilder {
|
|||
const std::string& outputFolder,
|
||||
GltfModel& gltf)
|
||||
: raw(raw), options(options), outputFolder(outputFolder), gltf(gltf) {
|
||||
if (!outputFolder.empty()) {
|
||||
if (outputFolder[outputFolder.size() - 1] == '/') {
|
||||
this->outputFolder = outputFolder.substr(0, outputFolder.size() - 1) ;
|
||||
}
|
||||
if (!outputFolder.empty()) {
|
||||
if (outputFolder[outputFolder.size() - 1] == '/') {
|
||||
this->outputFolder = outputFolder.substr(0, outputFolder.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
~TextureBuilder() {}
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ AccessorData::AccessorData(const BufferViewData& bufferView, GLType type, std::s
|
|||
name(name),
|
||||
sparse(false) {}
|
||||
|
||||
AccessorData::AccessorData(const AccessorData& baseAccessor, const BufferViewData& sparseIdxBufferView, const BufferViewData& sparseDataBufferView, GLType type, std::string name)
|
||||
AccessorData::AccessorData(
|
||||
const AccessorData& baseAccessor,
|
||||
const BufferViewData& sparseIdxBufferView,
|
||||
const BufferViewData& sparseDataBufferView,
|
||||
GLType type,
|
||||
std::string name)
|
||||
: Holdable(),
|
||||
bufferView(baseAccessor.bufferView),
|
||||
type(std::move(type)),
|
||||
|
@ -51,12 +56,13 @@ json AccessorData::serialize() const {
|
|||
}
|
||||
if (sparse) {
|
||||
json sparseData = {{"count", sparseIdxCount}};
|
||||
sparseData["indices"] = { {"bufferView", sparseIdxBufferView},
|
||||
{"byteOffset", sparseIdxBufferViewOffset},
|
||||
{"componentType", sparseIdxBufferViewType}};
|
||||
sparseData["indices"] = {
|
||||
{"bufferView", sparseIdxBufferView},
|
||||
{"byteOffset", sparseIdxBufferViewOffset},
|
||||
{"componentType", sparseIdxBufferViewType}};
|
||||
|
||||
sparseData["values"] = { {"bufferView", sparseDataBufferView},
|
||||
{"byteOffset", sparseDataBufferViewOffset}};
|
||||
sparseData["values"] = {
|
||||
{"bufferView", sparseDataBufferView}, {"byteOffset", sparseDataBufferViewOffset}};
|
||||
|
||||
result["sparse"] = sparseData;
|
||||
}
|
||||
|
|
|
@ -11,30 +11,35 @@
|
|||
#include "gltf/Raw2Gltf.hpp"
|
||||
|
||||
struct AccessorData : Holdable {
|
||||
AccessorData(const BufferViewData& bufferView, GLType type, std::string name);
|
||||
explicit AccessorData(GLType type);
|
||||
AccessorData(const AccessorData& baseAccessor, const BufferViewData& sparseIdxBufferView, const BufferViewData& sparseDataBufferView, GLType type, std::string name);
|
||||
AccessorData(const BufferViewData& bufferView, GLType type, std::string name);
|
||||
explicit AccessorData(GLType type);
|
||||
AccessorData(
|
||||
const AccessorData& baseAccessor,
|
||||
const BufferViewData& sparseIdxBufferView,
|
||||
const BufferViewData& sparseDataBufferView,
|
||||
GLType type,
|
||||
std::string name);
|
||||
|
||||
json serialize() const override;
|
||||
json serialize() const override;
|
||||
|
||||
unsigned int byteLength() const {
|
||||
return type.byteStride() * count;
|
||||
}
|
||||
unsigned int byteLength() const {
|
||||
return type.byteStride() * count;
|
||||
}
|
||||
|
||||
const int bufferView;
|
||||
const GLType type;
|
||||
const int bufferView;
|
||||
const GLType type;
|
||||
|
||||
unsigned int byteOffset;
|
||||
unsigned int count;
|
||||
std::vector<float> min;
|
||||
std::vector<float> max;
|
||||
std::string name;
|
||||
unsigned int byteOffset;
|
||||
unsigned int count;
|
||||
std::vector<float> min;
|
||||
std::vector<float> max;
|
||||
std::string name;
|
||||
|
||||
bool sparse;
|
||||
int sparseIdxCount;
|
||||
int sparseIdxBufferView;
|
||||
int sparseIdxBufferViewOffset;
|
||||
int sparseIdxBufferViewType;
|
||||
int sparseDataBufferView;
|
||||
int sparseDataBufferViewOffset;
|
||||
bool sparse;
|
||||
int sparseIdxCount;
|
||||
int sparseIdxBufferView;
|
||||
int sparseIdxBufferViewOffset;
|
||||
int sparseIdxBufferViewType;
|
||||
int sparseDataBufferView;
|
||||
int sparseDataBufferViewOffset;
|
||||
};
|
||||
|
|
|
@ -38,11 +38,12 @@ AnimationData::channel_t::channel_t(uint32_t ix, const NodeData& node, std::stri
|
|||
AnimationData::sampler_t::sampler_t(uint32_t time, uint32_t output) : time(time), output(output) {}
|
||||
|
||||
void to_json(json& j, const AnimationData::channel_t& data) {
|
||||
j = json{{"sampler", data.ix},
|
||||
{
|
||||
"target",
|
||||
{{"node", data.node}, {"path", data.path}},
|
||||
}};
|
||||
j = json{
|
||||
{"sampler", data.ix},
|
||||
{
|
||||
"target",
|
||||
{{"node", data.node}, {"path", data.path}},
|
||||
}};
|
||||
}
|
||||
|
||||
void to_json(json& j, const AnimationData::sampler_t& data) {
|
||||
|
|
|
@ -92,12 +92,13 @@ MaterialData::MaterialData(
|
|||
pbrMetallicRoughness(pbrMetallicRoughness) {}
|
||||
|
||||
json MaterialData::serialize() const {
|
||||
json result = {{"name", name},
|
||||
{"alphaMode", isTransparent ? "BLEND" : "OPAQUE"},
|
||||
{"extras",
|
||||
{{"fromFBX",
|
||||
{{"shadingModel", Describe(shadingModel)},
|
||||
{"isTruePBR", shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH}}}}}};
|
||||
json result = {
|
||||
{"name", name},
|
||||
{"alphaMode", isTransparent ? "BLEND" : "OPAQUE"},
|
||||
{"extras",
|
||||
{{"fromFBX",
|
||||
{{"shadingModel", Describe(shadingModel)},
|
||||
{"isTruePBR", shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH}}}}}};
|
||||
|
||||
if (normalTexture != nullptr) {
|
||||
result["normalTexture"] = *normalTexture;
|
||||
|
|
|
@ -73,7 +73,8 @@ void to_json(json& j, const PrimitiveData& d) {
|
|||
j["targets"] = targets;
|
||||
}
|
||||
if (!d.dracoAttributes.empty()) {
|
||||
j["extensions"] = {{KHR_DRACO_MESH_COMPRESSION,
|
||||
{{"bufferView", d.dracoBufferView}, {"attributes", d.dracoAttributes}}}};
|
||||
j["extensions"] = {
|
||||
{KHR_DRACO_MESH_COMPRESSION,
|
||||
{{"bufferView", d.dracoBufferView}, {"attributes", d.dracoAttributes}}}};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,15 +60,17 @@ struct PrimitiveData {
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void AddDracoArrayAttrib(const AttributeArrayDefinition<T> attribute, const std::vector<T>& attribArr) {
|
||||
void AddDracoArrayAttrib(
|
||||
const AttributeArrayDefinition<T> attribute,
|
||||
const std::vector<T>& attribArr) {
|
||||
draco::PointAttribute att;
|
||||
int8_t componentCount = attribute.glType.count;
|
||||
att.Init(
|
||||
attribute.dracoAttribute,
|
||||
componentCount,
|
||||
attribute.dracoComponentType,
|
||||
false,
|
||||
componentCount * draco::DataTypeLength(attribute.dracoComponentType));
|
||||
attribute.dracoAttribute,
|
||||
componentCount,
|
||||
attribute.dracoComponentType,
|
||||
false,
|
||||
componentCount * draco::DataTypeLength(attribute.dracoComponentType));
|
||||
|
||||
const int dracoAttId = dracoMesh->AddAttribute(att, true, attribArr.size());
|
||||
draco::PointAttribute* attPtr = dracoMesh->attribute(dracoAttId);
|
||||
|
|
|
@ -21,7 +21,8 @@ SkinData::SkinData(
|
|||
skeletonRootNode(skeletonRootNode.ix) {}
|
||||
|
||||
json SkinData::serialize() const {
|
||||
return {{"joints", joints},
|
||||
{"inverseBindMatrices", inverseBindMatrices},
|
||||
{"skeleton", skeletonRootNode}};
|
||||
return {
|
||||
{"joints", joints},
|
||||
{"inverseBindMatrices", inverseBindMatrices},
|
||||
{"skeleton", skeletonRootNode}};
|
||||
}
|
||||
|
|
|
@ -34,9 +34,8 @@ size_t VertexHasher::operator()(const RawVertex& v) const {
|
|||
bool RawVertex::operator==(const RawVertex& other) const {
|
||||
return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) &&
|
||||
(binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) &&
|
||||
(uv1 == other.uv1) &&
|
||||
(jointWeights == other.jointWeights) && (jointIndices == other.jointIndices) &&
|
||||
(polarityUv0 == other.polarityUv0) &&
|
||||
(uv1 == other.uv1) && (jointWeights == other.jointWeights) &&
|
||||
(jointIndices == other.jointIndices) && (polarityUv0 == other.polarityUv0) &&
|
||||
(blendSurfaceIx == other.blendSurfaceIx) && (blends == other.blends);
|
||||
}
|
||||
|
||||
|
@ -64,13 +63,13 @@ size_t RawVertex::Difference(const RawVertex& other) const {
|
|||
attributes |= RAW_VERTEX_ATTRIBUTE_UV1;
|
||||
}
|
||||
// Always need both or neither.
|
||||
if (jointIndices != other.jointIndices || jointWeights != other.jointWeights) {
|
||||
attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS;
|
||||
if (jointIndices != other.jointIndices || jointWeights != other.jointWeights) {
|
||||
attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS;
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
RawModel::RawModel() : vertexAttributes(0){}
|
||||
RawModel::RawModel() : vertexAttributes(0) {}
|
||||
|
||||
void RawModel::AddVertexAttribute(const RawVertexAttribute attrib) {
|
||||
vertexAttributes |= attrib;
|
||||
|
@ -406,15 +405,17 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
|
|||
|
||||
{
|
||||
globalMaxWeights = 0;
|
||||
for (auto& vertex: vertices) {
|
||||
|
||||
for (auto& vertex : vertices) {
|
||||
// Sort from largest to smallest weight.
|
||||
std::sort(vertex.skinningInfo.begin(), vertex.skinningInfo.end(), std::greater<RawVertexSkinningInfo>());
|
||||
|
||||
std::sort(
|
||||
vertex.skinningInfo.begin(),
|
||||
vertex.skinningInfo.end(),
|
||||
std::greater<RawVertexSkinningInfo>());
|
||||
|
||||
// Reduce to fit the requirements.
|
||||
if (maxSkinningWeights < vertex.skinningInfo.size())
|
||||
vertex.skinningInfo.resize(maxSkinningWeights);
|
||||
globalMaxWeights = std::max(globalMaxWeights, (int) vertex.skinningInfo.size());
|
||||
globalMaxWeights = std::max(globalMaxWeights, (int)vertex.skinningInfo.size());
|
||||
|
||||
// Normalize weights if requested.
|
||||
if (normalizeWeights) {
|
||||
|
@ -432,15 +433,15 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
|
|||
AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS);
|
||||
}
|
||||
|
||||
|
||||
assert(globalMaxWeights >= 0);
|
||||
// Copy to gltf friendly structure
|
||||
for (auto& vertex : vertices) {
|
||||
vertex.jointIndices.reserve(globalMaxWeights);
|
||||
vertex.jointWeights.reserve(globalMaxWeights);
|
||||
for (int i = 0; i < globalMaxWeights; i += 4) { // ensure every vertex has the same amount of weights
|
||||
for (int i = 0; i < globalMaxWeights;
|
||||
i += 4) { // ensure every vertex has the same amount of weights
|
||||
Vec4f weights{0.0};
|
||||
Vec4i jointIds{0,0,0,0};
|
||||
Vec4i jointIds{0, 0, 0, 0};
|
||||
for (int j = i; j < i + 4 && j < vertex.skinningInfo.size(); j++) {
|
||||
weights[j - i] = vertex.skinningInfo[j].jointWeight;
|
||||
jointIds[j - i] = vertex.skinningInfo[j].jointIndex;
|
||||
|
@ -668,11 +669,11 @@ void RawModel::CreateMaterialModels(
|
|||
if ((keep & RAW_VERTEX_ATTRIBUTE_UV1) == 0) {
|
||||
vertex.uv1 = defaultVertex.uv1;
|
||||
}
|
||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) {
|
||||
vertex.jointIndices = defaultVertex.jointIndices;
|
||||
}
|
||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) {
|
||||
vertex.jointWeights = defaultVertex.jointWeights;
|
||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) {
|
||||
vertex.jointIndices = defaultVertex.jointIndices;
|
||||
}
|
||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) {
|
||||
vertex.jointWeights = defaultVertex.jointWeights;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ enum RawVertexAttribute {
|
|||
RAW_VERTEX_ATTRIBUTE_COLOR = 1 << 4,
|
||||
RAW_VERTEX_ATTRIBUTE_UV0 = 1 << 5,
|
||||
RAW_VERTEX_ATTRIBUTE_UV1 = 1 << 6,
|
||||
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES = 1 << 7,
|
||||
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES = 1 << 7,
|
||||
RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS = 1 << 8,
|
||||
|
||||
RAW_VERTEX_ATTRIBUTE_AUTO = 1 << 31
|
||||
|
@ -38,8 +38,7 @@ struct RawBlendVertex {
|
|||
}
|
||||
};
|
||||
|
||||
struct RawVertexSkinningInfo
|
||||
{
|
||||
struct RawVertexSkinningInfo {
|
||||
int jointIndex;
|
||||
float jointWeight;
|
||||
|
||||
|
@ -58,7 +57,7 @@ struct RawVertex {
|
|||
Vec2f uv1{0.0f};
|
||||
std::vector<Vec4i> jointIndices;
|
||||
std::vector<Vec4f> jointWeights;
|
||||
|
||||
|
||||
std::vector<RawVertexSkinningInfo> skinningInfo;
|
||||
// end of members that directly correspond to vertex attributes
|
||||
|
||||
|
@ -359,7 +358,6 @@ struct RawNode {
|
|||
|
||||
class RawModel {
|
||||
public:
|
||||
|
||||
RawModel();
|
||||
|
||||
// Add geometry.
|
||||
|
@ -437,8 +435,8 @@ class RawModel {
|
|||
int GetVertexCount() const {
|
||||
return (int)vertices.size();
|
||||
}
|
||||
|
||||
int GetGlobalWeightCount() const{
|
||||
|
||||
int GetGlobalWeightCount() const {
|
||||
return globalMaxWeights;
|
||||
}
|
||||
|
||||
|
@ -527,10 +525,10 @@ class RawModel {
|
|||
// Create individual attribute arrays, with the source as an array.
|
||||
// Returns true if the vertices store the particular attribute.
|
||||
template <typename _attrib_type_>
|
||||
void GetArrayAttributeArray(std::vector<_attrib_type_>& out,
|
||||
const std::vector<_attrib_type_> RawVertex::*ptr,
|
||||
const int arrayOffset)
|
||||
const;
|
||||
void GetArrayAttributeArray(
|
||||
std::vector<_attrib_type_>& out,
|
||||
const std::vector<_attrib_type_> RawVertex::*ptr,
|
||||
const int arrayOffset) const;
|
||||
|
||||
// Create an array with a raw model for each material.
|
||||
// Multiple surfaces with the same material will turn into a single model.
|
||||
|
@ -571,9 +569,9 @@ void RawModel::GetAttributeArray(
|
|||
|
||||
template <typename _attrib_type_>
|
||||
void RawModel::GetArrayAttributeArray(
|
||||
std::vector<_attrib_type_>& out,
|
||||
const std::vector<_attrib_type_> RawVertex::*ptr,
|
||||
const int arrayOffset) const {
|
||||
std::vector<_attrib_type_>& out,
|
||||
const std::vector<_attrib_type_> RawVertex::*ptr,
|
||||
const int arrayOffset) const {
|
||||
out.resize(vertices.size());
|
||||
for (size_t i = 0; i < vertices.size(); i++) {
|
||||
out[i] = (vertices[i].*ptr)[arrayOffset];
|
||||
|
|
Loading…
Reference in New Issue