PeriDyno 1.0.0
Loading...
Searching...
No Matches
HierarchicalModel.h
Go to the documentation of this file.
1#pragma once
3
4#include "AnimationCurve.h"
5#include <iterator>
6#include <random>
7#include "TextureMesh.h"
8#include "Quat.h"
9
10#define ERRORTIME -2321.51
11
12namespace dyno
13{
14 class ModelObject;
15 class Bone;
16
17 class ModelObject : public Object
18 {
19 public:
22 {
23 child.clear();
24 parent.clear();
25
26
27 };
28
29 bool operator==(const ModelObject& model)
30 {
31 return name == model.name;
32 }
33
34 std::string name;
35 Mat4f localTransform = Mat4f::identityMatrix();
41
42 std::vector<std::shared_ptr<ModelObject>> child;
43 std::vector<std::shared_ptr<ModelObject>> parent;// bone - parent - root
44
45 int id = -1;
46
47 std::vector<Real> m_Translation_Times[3];
48 std::vector<Real> m_Translation_Values[3];
49
50 std::vector<Real> m_Rotation_Times[3];
51 std::vector<Real> m_Rotation_Values[3];
52
53 std::vector<Real> m_Scale_Times[3];
54 std::vector<Real> m_Scale_Values[3];
55
59
60
61 };
62
63
64 class Bone : public ModelObject
65 {
66 public:
67 Bone() {};
68
69 };
70
71 class MeshInfo : public ModelObject
72 {
73 public:
75
76 std::vector<Vec3f> vertices;
77 std::vector<int> verticeId_pointId;
78 std::map<int,std::vector<int>> pointId_verticeId;
79 std::vector<Vec3f> normals;
80 std::vector<Vec2f> texcoords;
81 std::vector<Vec3f> verticesColor;
82 std::vector<std::vector<TopologyModule::Triangle>> facegroup_triangles;
83 std::vector<CArrayList<uint>> facegroup_polygons;
84
85 std::vector<std::shared_ptr<Material>> materials;
86
87 std::vector<TAlignedBox3D<Real>> boundingBox;
88 std::vector<Transform3f> boundingTransform;
89
90 std::vector<Vec4f> boneIndices0;
91 std::vector<Vec4f> boneWeights0;
92 std::vector<Vec4f> boneIndices1;
93 std::vector<Vec4f> boneWeights1;
94 std::vector<Vec4f> boneIndices2;
95 std::vector<Vec4f> boneWeights2;
96
97 };
98
99
101 {
102 public:
104 {
105 mTimeStart = -1;
106 mTimeEnd = -1;
107 }
109
110 void clear()
111 {
112 mModelObjects.clear();
113 }
114
115 int findMeshIndexByName(std::string name)
116 {
117 int id = 0;
118 for (auto it : mMeshs) {
119 if (it->name == name)
120 return id;
121
122 id++;
123 }
124 return -1;
125 }
126
127 std::shared_ptr<ModelObject> getObjectByName(std::string name)
128 {
129 for (auto it : mModelObjects) {
130 if (it->name == name)
131 {
132 return it;
133 }
134 }
135
136 return nullptr;
137 }
138
139 int getObjIndexByName(std::string name)
140 {
141 int id = 0;
142 for (auto it : mModelObjects) {
143 if (it->name == name)
144 return id;
145
146 id++;
147 }
148 return -1;
149 }
150
151 int getBoneIndexByName(std::string name)
152 {
153 int id = 0;
154 for (auto it : mBones) {
155 if (it->name == name)
156 return id;
157
158 id++;
159 }
160 return -1;
161 }
162
163
165 {
166 for (auto it : mBones)
167 {
168 //build inverseBindMatrix
169 std::cout << "********************" << it->name << "\n";
170 int select = getBoneIndexByName(it->name);
171 if (select == -1)continue;
172
173 Mat4f inverseMatrix = it->localTransform.inverse();
174 for (size_t i = 0; i < it->parent.size(); i++)
175 {
176 auto parent = it->parent[i];
177 inverseMatrix *= parent->localTransform.inverse();
178 std::cout << parent->name << "\n";
179 };
180
181 mBoneInverseBindMatrix[select] = inverseMatrix;
182 }
183 }
184
185 void updateFrameWorldTransform(Real time) //ʱ¼ä²åÖµ
186 {
187
188 //update Animation to mBoneRotations/mBoneTranslations/mBoneScales
189 for (size_t i = 0; i < mBones.size(); i++)
190 {
191 int select = getBoneIndexByName(mBones[i]->name);
192 if (select == -1)continue;
193
194 auto iterR = mBones[select];
195
196 //Rotation
197 mBoneRotations[select].x = getVectorDataByTime(mBones[select]->m_Rotation_Values[0], mBones[select]->m_Rotation_Times[0], time);
198 mBoneRotations[select].y = getVectorDataByTime(mBones[select]->m_Rotation_Values[1], mBones[select]->m_Rotation_Times[1], time);
199 mBoneRotations[select].z = getVectorDataByTime(mBones[select]->m_Rotation_Values[2], mBones[select]->m_Rotation_Times[2], time);
200 //Translation
201 mBoneTranslations[select].x = getVectorDataByTime(mBones[select]->m_Translation_Values[0], mBones[select]->m_Translation_Times[0], time);
202 mBoneTranslations[select].y = getVectorDataByTime(mBones[select]->m_Translation_Values[1], mBones[select]->m_Translation_Times[1], time);
203 mBoneTranslations[select].z = getVectorDataByTime(mBones[select]->m_Translation_Values[2], mBones[select]->m_Translation_Times[2], time);
204 //Scale
205 mBoneScales[select].x = getVectorDataByTime(mBones[select]->m_Scale_Values[0], mBones[select]->m_Scale_Times[0], time);
206 mBoneScales[select].y = getVectorDataByTime(mBones[select]->m_Scale_Values[1], mBones[select]->m_Scale_Times[1], time);
207 mBoneScales[select].z = getVectorDataByTime(mBones[select]->m_Scale_Values[2], mBones[select]->m_Scale_Times[2], time);
208 }
209
210 for (auto it : mBones)
211 {
212 int select = getBoneIndexByName(it->name);
213 if (select == -1)continue;
214
215 Mat4f worldMatrix = it->localTransform;
216 for (size_t i = 0; i < it->parent.size(); i++){
217 auto parent = it->parent[i];
218 worldMatrix *= parent->localTransform;
219 };
220
221 mBoneWorldMatrix[select] = worldMatrix;
222 }
223 currentTime = time;
224
225 };
226
227 Real getVectorDataByTime(std::vector<Real> data,std::vector<Real> timeCode,Real time)
228 {
229 if (!bool(data.size()))
230 return 0;
231
232 int idx = findMaxSmallerIndex(timeCode, time);
233 if (idx >= data.size() - 1) { // [size-1]<=[tId]
234 return data[data.size() - 1];
235 }
236 else if(idx >= 0) {
237 if (data[idx] != data[idx + 1]) {
238 float weight = (time - timeCode[idx]) / (timeCode[idx + 1] - timeCode[idx]);
239 return lerp(data[idx], data[idx + 1], weight);
240 }
241 else
242 return data[idx];
243 }
244 else {
245 return data[0];
246 }
247 }
248
249 int findMaxSmallerIndex(const std::vector<float>& arr, float v) {
250 int left = 0;
251 int right = arr.size() - 1;
252 int maxIndex = -1;
253
254 if (arr.size() >= 1)
255 {
256 if (arr[0] > v)
257 return 0;
258
259 if (arr[arr.size() - 1] < v)
260 return arr.size() - 1;
261 }
262
263 while (left <= right) {
264 int mid = left + (right - left) / 2;
265
266 if (arr[mid] <= v) {
267 maxIndex = mid;
268 left = mid + 1;
269 }
270 else {
271 right = mid - 1;
272 }
273 }
274
275 return maxIndex;
276 }
277
278 public:
279
280 std::vector<std::shared_ptr<ModelObject>> mModelObjects;
281 std::vector<std::shared_ptr<MeshInfo>> mMeshs;
282 std::vector<std::shared_ptr<Bone>> mBones;;
283 std::vector<Vec3f> mBoneRotations;
284 std::vector<Vec3f> mBoneTranslations;
285 std::vector<Vec3f> mBoneScales;
286 std::vector<Mat4f> mBoneWorldMatrix;
287 std::vector<Mat4f> mBoneInverseBindMatrix;
288
289 float mTimeStart = -1;
290 float mTimeEnd = -1;
291
292
293 private:
294 Real lerp(Real v0, Real v1, float weight)
295 {
296 return v0 + (v1 - v0) * weight;
297 }
299 };
300
301
302}
#define ERRORTIME
Implementation of quaternion.
double Real
Definition Typedef.inl:23
Real lerp(Real v0, Real v1, float weight)
std::vector< std::shared_ptr< MeshInfo > > mMeshs
int findMeshIndexByName(std::string name)
std::vector< Mat4f > mBoneWorldMatrix
std::shared_ptr< ModelObject > getObjectByName(std::string name)
std::vector< Mat4f > mBoneInverseBindMatrix
std::vector< std::shared_ptr< Bone > > mBones
int getObjIndexByName(std::string name)
void updateFrameWorldTransform(Real time)
std::vector< Vec3f > mBoneScales
std::vector< Vec3f > mBoneRotations
int findMaxSmallerIndex(const std::vector< float > &arr, float v)
Real getVectorDataByTime(std::vector< Real > data, std::vector< Real > timeCode, Real time)
std::vector< std::shared_ptr< ModelObject > > mModelObjects
int getBoneIndexByName(std::string name)
std::vector< Vec3f > mBoneTranslations
std::vector< Vec3f > normals
std::vector< Vec4f > boneIndices0
std::vector< Vec3f > vertices
std::vector< CArrayList< uint > > facegroup_polygons
std::map< int, std::vector< int > > pointId_verticeId
std::vector< Vec4f > boneIndices2
std::vector< Vec2f > texcoords
std::vector< Vec4f > boneWeights2
std::vector< std::vector< TopologyModule::Triangle > > facegroup_triangles
std::vector< Vec4f > boneWeights0
std::vector< Vec4f > boneWeights1
std::vector< std::shared_ptr< Material > > materials
std::vector< int > verticeId_pointId
std::vector< Vec4f > boneIndices1
std::vector< Vec3f > verticesColor
std::vector< Transform3f > boundingTransform
std::vector< TAlignedBox3D< Real > > boundingBox
bool operator==(const ModelObject &model)
std::vector< std::shared_ptr< ModelObject > > parent
std::vector< Real > m_Rotation_Times[3]
std::vector< std::shared_ptr< ModelObject > > child
std::vector< Real > m_Translation_Values[3]
std::vector< Real > m_Rotation_Values[3]
std::vector< Real > m_Translation_Times[3]
Vec3f getFrameRotation(Real time)
Vec3f getFrameScale(Real time)
std::vector< Real > m_Scale_Times[3]
Vec3f getFrameTranslation(Real time)
std::vector< Real > m_Scale_Values[3]
ObjectId id
Definition Object.h:131
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
SquareMatrix< float, 4 > Mat4f
Definition Matrix4x4.h:85