2 // Copyright (c) Microsoft. All rights reserved.
3 // This code is licensed under the MIT License (MIT).
4 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 // Developed by Minigraph
11 // Author: Alex Nankervis
23 // must match the format enum in model.h
24 const char* Model::s_FormatString
[] =
29 static_assert(sizeof(Model::s_FormatString
) / sizeof(const char*) == Model::formats
, "s_FormatString doesn't match format enum");
31 int Model::FormatFromFilename(const char *filename
)
33 const char *p
= strrchr(filename
, '.');
37 for (int n
= 1; n
< formats
; n
++)
39 if (_stricmp(p
+ 1, s_FormatString
[n
]) == 0)
49 , m_pMaterial(nullptr)
50 , m_pVertexData(nullptr)
51 , m_pIndexData(nullptr)
52 , m_pVertexDataDepth(nullptr)
53 , m_pIndexDataDepth(nullptr)
66 m_VertexBuffer
.Destroy();
67 m_IndexBuffer
.Destroy();
68 m_VertexBufferDepth
.Destroy();
69 m_IndexBufferDepth
.Destroy();
73 m_Header
.meshCount
= 0;
75 delete [] m_pMaterial
;
76 m_pMaterial
= nullptr;
77 m_Header
.materialCount
= 0;
79 delete [] m_pVertexData
;
80 delete [] m_pIndexData
;
81 delete [] m_pVertexDataDepth
;
82 delete [] m_pIndexDataDepth
;
84 m_pVertexData
= nullptr;
85 m_Header
.vertexDataByteSize
= 0;
86 m_pIndexData
= nullptr;
87 m_Header
.indexDataByteSize
= 0;
88 m_pVertexDataDepth
= nullptr;
89 m_Header
.vertexDataByteSizeDepth
= 0;
90 m_pIndexDataDepth
= nullptr;
94 m_Header
.boundingBox
.min
= Vector3(0.0f
);
95 m_Header
.boundingBox
.max
= Vector3(0.0f
);
98 bool Model::Load(const char *filename
)
102 int format
= FormatFromFilename(filename
);
105 bool needToOptimize
= true;
109 #ifdef MODEL_ENABLE_ASSIMP
110 rval
= LoadAssimp(filename
);
115 rval
= LoadH3D(filename
);
116 needToOptimize
= false;
123 LoadPostProcess(needToOptimize
);
128 bool Model::Save(const char *filename
) const
130 int format
= FormatFromFilename(filename
);
139 rval
= SaveH3D(filename
);
146 // assuming at least 3 floats for position
147 void Model::ComputeMeshBoundingBox(unsigned int meshIndex
, BoundingBox
&bbox
) const
149 const Mesh
*mesh
= m_pMesh
+ meshIndex
;
151 if (mesh
->vertexCount
> 0)
153 unsigned int vertexStride
= mesh
->vertexStride
;
155 const float *p
= (float*)(m_pVertexData
+ mesh
->vertexDataByteOffset
+ mesh
->attrib
[attrib_position
].offset
);
156 const float *pEnd
= (float*)(m_pVertexData
+ mesh
->vertexDataByteOffset
+ mesh
->vertexCount
* mesh
->vertexStride
+ mesh
->attrib
[attrib_position
].offset
);
157 bbox
.min
= Scalar(FLT_MAX
);
158 bbox
.max
= Scalar(-FLT_MAX
);
162 Vector3
pos(*(p
+ 0), *(p
+ 1), *(p
+ 2));
164 bbox
.min
= Min(bbox
.min
, pos
);
165 bbox
.max
= Max(bbox
.max
, pos
);
167 (*(uint8_t**)&p
) += vertexStride
;
172 bbox
.min
= Scalar(0.0f
);
173 bbox
.max
= Scalar(0.0f
);
177 void Model::ComputeGlobalBoundingBox(BoundingBox
&bbox
) const
179 if (m_Header
.meshCount
> 0)
181 bbox
.min
= Scalar(FLT_MAX
);
182 bbox
.max
= Scalar(-FLT_MAX
);
183 for (unsigned int meshIndex
= 0; meshIndex
< m_Header
.meshCount
; meshIndex
++)
185 const Mesh
*mesh
= m_pMesh
+ meshIndex
;
187 bbox
.min
= Min(bbox
.min
, mesh
->boundingBox
.min
);
188 bbox
.max
= Max(bbox
.max
, mesh
->boundingBox
.max
);
193 bbox
.min
= Scalar(0.0f
);
194 bbox
.max
= Scalar(0.0f
);
198 void Model::ComputeAllBoundingBoxes()
200 for (unsigned int meshIndex
= 0; meshIndex
< m_Header
.meshCount
; meshIndex
++)
202 Mesh
*mesh
= m_pMesh
+ meshIndex
;
203 ComputeMeshBoundingBox(meshIndex
, mesh
->boundingBox
);
205 ComputeGlobalBoundingBox(m_Header
.boundingBox
);
208 void Model::LoadPostProcess(bool needToOptimize
)
212 #ifdef MODEL_ENABLE_OPTIMIZER
220 } // namespace Graphics