core: Remove __uuidof() emulation.
[vkmodelviewer.git] / Model / Model.cpp
blob4079b6546e7597472f0aac00ee66967994dfcdbc
1 //
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.
8 //
9 // Developed by Minigraph
11 // Author: Alex Nankervis
14 #include "pch.h"
15 #include "Model.h"
16 #include <string.h>
17 #include <float.h>
20 namespace Graphics
23 // must match the format enum in model.h
24 const char* Model::s_FormatString[] =
26 "none",
27 "h3d",
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, '.');
34 if (!p || *p == 0)
35 return format_none;
37 for (int n = 1; n < formats; n++)
39 if (_stricmp(p + 1, s_FormatString[n]) == 0)
40 return n;
43 return format_none;
47 Model::Model()
48 : m_pMesh(nullptr)
49 , m_pMaterial(nullptr)
50 , m_pVertexData(nullptr)
51 , m_pIndexData(nullptr)
52 , m_pVertexDataDepth(nullptr)
53 , m_pIndexDataDepth(nullptr)
54 , m_SRVs(nullptr)
56 Clear();
59 Model::~Model()
61 Clear();
64 void Model::Clear()
66 m_VertexBuffer.Destroy();
67 m_IndexBuffer.Destroy();
68 m_VertexBufferDepth.Destroy();
69 m_IndexBufferDepth.Destroy();
71 delete [] m_pMesh;
72 m_pMesh = nullptr;
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;
92 ReleaseTextures();
94 m_Header.boundingBox.min = Vector3(0.0f);
95 m_Header.boundingBox.max = Vector3(0.0f);
98 bool Model::Load(const char *filename)
100 Clear();
102 int format = FormatFromFilename(filename);
104 bool rval = false;
105 bool needToOptimize = true;
106 switch (format)
108 case format_none:
109 #ifdef MODEL_ENABLE_ASSIMP
110 rval = LoadAssimp(filename);
111 #endif
112 break;
114 case format_h3d:
115 rval = LoadH3D(filename);
116 needToOptimize = false;
117 break;
120 if (!rval)
121 return false;
123 LoadPostProcess(needToOptimize);
125 return true;
128 bool Model::Save(const char *filename) const
130 int format = FormatFromFilename(filename);
132 bool rval = false;
133 switch (format)
135 case format_none:
136 break;
138 case format_h3d:
139 rval = SaveH3D(filename);
140 break;
143 return rval;
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);
160 while (p < pEnd)
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;
170 else
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);
191 else
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)
210 if (needToOptimize)
212 #ifdef MODEL_ENABLE_OPTIMIZER
213 Optimize();
214 #else
215 assert(0);
216 #endif
220 } // namespace Graphics