PeriDyno 1.0.0
Loading...
Searching...
No Matches
Vessel.cpp
Go to the documentation of this file.
1#include "Vessel.h"
2
3#include "Quat.h"
4
7
8#include "GltfFunc.h"
9
10namespace dyno
11{
12 template<typename TDataType>
14 : RigidBody<TDataType>()
15 {
16 this->varDensity()->setRange(1.0f, 10000.0f);
17
18 auto callback = std::make_shared<FCallBackFunc>(std::bind(&Vessel<TDataType>::transform, this));
19 this->varLocation()->attach(callback);
20 this->varScale()->attach(callback);
21 this->varRotation()->attach(callback);
22
23 auto EnvelopeRender = std::make_shared<GLSurfaceVisualModule>();
24 EnvelopeRender->setColor(Color(0.8f, 0.8f, 0.8f));
25 this->stateEnvelope()->promoteOuput()->connect(EnvelopeRender->inTriangleSet());
26 this->graphicsPipeline()->pushModule(EnvelopeRender);
27 EnvelopeRender->setVisible(false);
28
29
30 auto texMeshRender = std::make_shared<GLPhotorealisticInstanceRender>();
31 this->stateTextureMesh()->connect(texMeshRender->inTextureMesh());
32 this->stateInstanceTransform()->connect(texMeshRender->inTransform());
33 this->graphicsPipeline()->pushModule(texMeshRender);
34
35
36 auto evenlopeLoader = std::make_shared<FCallBackFunc>(
37 [=]() {
38 std::string name = this->varEnvelopeName()->getValue().string();
39 bool succeed = mInitialEnvelope.loadObjFile(name);
40
41 if (succeed)
42 {
43 auto envelope = this->stateEnvelope()->getDataPtr();
44
45 envelope->copyFrom(mInitialEnvelope);
46
47 envelope->scale(this->varScale()->getValue());
48 envelope->rotate(this->varRotation()->getValue() * M_PI / 180);
49 envelope->translate(this->varLocation()->getValue());
50 }
51
52
53 }
54 );
55 evenlopeLoader->update();
56
57 this->varEnvelopeName()->attach(evenlopeLoader);
58
59 auto textureMeshLoader = std::make_shared<FCallBackFunc>(
60 [=]() {
61 std::string filepath = this->varTextureMeshName()->getValue().string();
62 std::shared_ptr<TextureMesh> texMesh = this->stateTextureMesh()->getDataPtr();
63 loadGLTFTextureMesh(texMesh, filepath);
64 }
65 );
66
67 this->varTextureMeshName()->attach(textureMeshLoader);
68
69 this->varDensity()->setValue(150.0f);
70 this->varBarycenterOffset()->setValue(Vec3f(0.0f, 0.0f, -0.5f));
71 }
72
73 template<typename TDataType>
78
79 template<typename TDataType>
81 {
82 NBoundingBox box;
83
84 mInitialEnvelope.requestBoundingBox(box.lower, box.upper);
85
86 return box;
87 }
88
89 template<typename TDataType>
91 {
92 if (this->stateEnvelope()->isEmpty()) this->stateEnvelope()->allocate();
93 if (this->stateTextureMesh()->isEmpty()) this->stateTextureMesh()->allocate();
94
95 std::string envFileName = getAssetPath() + "obj/boat_boundary.obj";
96 if (this->varEnvelopeName()->getValue() != envFileName) {
97 this->varEnvelopeName()->setValue(FilePath(envFileName));
98 }
99
100 std::string texMeshName = getAssetPath() + "gltf/SailBoat/SailBoat.gltf";
101 if (this->varTextureMeshName()->getValue() != texMeshName) {
102 this->varTextureMeshName()->setValue(FilePath(texMeshName));
103 }
104
105 this->transform();
106
107 auto texMesh = this->stateTextureMesh()->constDataPtr();
108
109 //Initialize states for the rigid body
110 {
111 Coord lo;
112 Coord hi;
113
114 if (mInitialEnvelope.isEmpty())
115 return;
116
117 mInitialEnvelope.requestBoundingBox(lo, hi);
118
119 Coord scale = this->varScale()->getValue();
120
121 mShapeCenter = 0.5f * (hi + lo);
122
123
124 Real lx = hi.x - lo.x;
125 Real ly = hi.y - lo.y;
126 Real lz = hi.z - lo.z;
127
128 Real rho = this->varDensity()->getData();
129 Real mass = rho * lx * ly * lz;
130
131 //Calculate mass using the bounding box
132 Matrix inertia = 1.0f / 12.0f * mass
133 * Mat3f(ly * ly + lz * lz, 0, 0,
134 0, lx * lx + lz * lz, 0,
135 0, 0, lx * lx + ly * ly);
136
137
138 Coord location = this->varLocation()->getValue();
139 Coord rot = this->varRotation()->getValue();
140
141 auto quat = this->computeQuaternion();
142 auto offset = this->varBarycenterOffset()->getValue();
143
144 this->stateMass()->setValue(mass);
145 this->stateCenter()->setValue(location + mShapeCenter);
146 this->stateBarycenter()->setValue(location + mShapeCenter + quat.rotate(offset));
147 this->stateVelocity()->setValue(Vec3f(0));
148 this->stateAngularVelocity()->setValue(Vec3f(0));
149 this->stateInertia()->setValue(inertia);
150 this->stateQuaternion()->setValue(quat);
151 this->stateInitialInertia()->setValue(inertia);
152 }
153
155 }
156
157 template<typename TDataType>
159 {
161
162 auto center = this->stateCenter()->getValue();
163 auto quat = this->stateQuaternion()->getValue();
164 auto scale = this->varScale()->getValue();
165
166 auto offset = this->varBarycenterOffset()->getValue();
167
168 this->stateBarycenter()->setValue(center + quat.rotate(offset));
169
170 auto buoy = this->stateEnvelope()->getDataPtr();
171 buoy->copyFrom(mInitialEnvelope);
172 buoy->rotate(quat);
173 buoy->scale(scale);
174 buoy->translate(center - mShapeCenter);
175
176 auto texMesh = this->stateTextureMesh()->getDataPtr();
177 {
178
179 uint N = texMesh->shapes().size();
180
182 tms.assign(this->stateInstanceTransform()->constData());
183
184 for (uint i = 0; i < tms.size(); i++)
185 {
186 auto& list = tms[i];
187 for (uint j = 0; j < list.size(); j++)
188 {
189 list[j].translation() = center + quat.rotate(texMesh->shapes()[i]->boundingTransform.translation() * scale) - mShapeCenter; //
190 list[j].rotation() = quat.toMatrix3x3();
191 list[j].scale() = scale;
192 }
193
194 }
195
196 auto instantanceTransform = this->stateInstanceTransform()->getDataPtr();
197 instantanceTransform->assign(tms);
198
199 tms.clear();
200
201 }
202 }
203
204 template<typename TDataType>
206 {
207
208 Coord location = this->varLocation()->getValue();
209 Coord rot = this->varRotation()->getValue();
210 Coord scale = this->varScale()->getValue();
211
212 auto quat = this->computeQuaternion();
213
214 auto envelope = this->stateEnvelope()->getDataPtr();
215 envelope->copyFrom(mInitialEnvelope);
216 envelope->scale(scale);
217 envelope->rotate(quat);
218 envelope->translate(location);
219
220 if (this->stateTextureMesh()->isEmpty())
221 return;
222
223 auto texMesh = this->stateTextureMesh()->constDataPtr();
224 {
225 uint N = texMesh->shapes().size();
226
228 tms.resize(N, 1);
229
230 for (uint i = 0; i < N; i++)
231 {
232 Transform3f t = texMesh->shapes()[i]->boundingTransform;
233
234 tms[i].insert(Transform3f(t.translation() * scale + location, quat.toMatrix3x3(), t.scale() * scale));
235 }
236
237 if (this->stateInstanceTransform()->isEmpty())
238 {
239 this->stateInstanceTransform()->allocate();
240 }
241
242 auto instantanceTransform = this->stateInstanceTransform()->getDataPtr();
243 instantanceTransform->assign(tms);
244
245 tms.clear();
246 }
247 }
248
250}
#define DEFINE_CLASS(name)
Definition Object.h:140
Implementation of quaternion.
#define M_PI
Definition Typedef.inl:36
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
virtual void resetStates()
Definition Node.cpp:214
Quat< Real > computeQuaternion()
void updateStates() override
Definition RigidBody.cpp:22
TDataType::Matrix Matrix
Definition Vessel.h:33
NBoundingBox boundingBox() override
Definition Vessel.cpp:80
~Vessel() override
Definition Vessel.cpp:74
void resetStates() override
Definition Vessel.cpp:90
void transform()
Definition Vessel.cpp:205
void updateStates() override
Definition Vessel.cpp:158
TDataType::Coord Coord
Definition Vessel.h:32
TriangleSet< TDataType > mInitialEnvelope
Definition Vessel.h:66
TDataType::Real Real
Definition Vessel.h:31
Coord mShapeCenter
Definition Vessel.h:68
#define N(x, y, z)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
SquareMatrix< float, 3 > Mat3f
Definition Matrix3x3.h:92
ArrayList< T, DeviceType::CPU > CArrayList
Definition ArrayList.h:207
void loadGLTFTextureMesh(std::shared_ptr< TextureMesh > texMesh, const std::string &filepath)
Transform< float, 3 > Transform3f
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
unsigned int uint
Definition VkProgram.h:14
vgm::Quat quat
Definition vgMath.h:633