6 #include <unordered_map>
32 using std::make_unique;
35 using std::unordered_map;
63 auto model = make_unique<Model>(
id,
id, UpVector::Y_UP, RotationOrder::XYZ,
nullptr);
65 auto material = make_unique<Material>(
"primitive");
66 auto specularMaterialProperties = make_unique<SpecularMaterialProperties>();
67 specularMaterialProperties->setAmbientColor(
69 245.0f / 255.0f * 0.5f,
70 40.0f / 255.0f * 0.5f,
71 135.0f / 255.0f * 0.5f,
75 specularMaterialProperties->setDiffuseColor(
77 245.0f / 255.0f * 0.5f,
78 40.0f / 255.0f * 0.5f,
79 135.0f / 255.0f * 0.5f,
83 specularMaterialProperties->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
84 material->setSpecularMaterialProperties(specularMaterialProperties.release());
86 auto node = make_unique<Node>(model.get(),
nullptr,
"primitive",
"primitive");
88 auto fvi = BoundingBox::getFacesVerticesIndexes();
90 vector<Vector3> vertices;
91 for (
const auto& vertex : boundingBox->
getVertices()) {
92 vertices.push_back(vertex);
95 vector<Vector3> normals;
96 normals.emplace_back(-1.0f, 0.0f, 0.0f);
97 normals.emplace_back(+1.0f, 0.0f, 0.0f);
98 normals.emplace_back(0.0f, -1.0f, 0.0f);
99 normals.emplace_back(0.0f, +1.0f, 0.0f);
100 normals.emplace_back(0.0f, 0.0f, -1.0f);
101 normals.emplace_back(0.0f, 0.0f, +1.0f);
105 faces.emplace_back(node.get(), (*fvi)[0][0], (*fvi)[0][1], (*fvi)[0][2], 0, 0, 0);
106 faces.emplace_back(node.get(), (*fvi)[1][0], (*fvi)[1][1], (*fvi)[1][2], 0, 0, 0);
108 faces.emplace_back(node.get(), (*fvi)[2][0], (*fvi)[2][1], (*fvi)[2][2], 1, 1, 1);
109 faces.emplace_back(node.get(), (*fvi)[3][0], (*fvi)[3][1], (*fvi)[3][2], 1, 1, 1);
111 faces.emplace_back(node.get(), (*fvi)[4][0], (*fvi)[4][1], (*fvi)[4][2], 2, 2, 2);
112 faces.emplace_back(node.get(), (*fvi)[5][0], (*fvi)[5][1], (*fvi)[5][2], 2, 2, 2);
114 faces.emplace_back(node.get(), (*fvi)[6][0], (*fvi)[6][1], (*fvi)[6][2], 3, 3, 3);
115 faces.emplace_back(node.get(), (*fvi)[7][0], (*fvi)[7][1], (*fvi)[7][2], 3, 3, 3);
117 faces.emplace_back(node.get(), (*fvi)[8][0], (*fvi)[8][1], (*fvi)[8][2], 4, 4, 4);
118 faces.emplace_back(node.get(), (*fvi)[9][0], (*fvi)[9][1], (*fvi)[9][2], 4, 4, 4);
120 faces.emplace_back(node.get(), (*fvi)[10][0], (*fvi)[10][1], (*fvi)[10][2], 5, 5, 5);
121 faces.emplace_back(node.get(), (*fvi)[11][0], (*fvi)[11][1], (*fvi)[11][2], 5, 5, 5);
123 FacesEntity nodeFacesEntity(node.get(),
"primitive.facesentity");
127 vector<FacesEntity> nodeFacesEntities;
128 nodeFacesEntities.push_back(nodeFacesEntity);
130 node->setVertices(vertices);
131 node->setNormals(normals);
132 node->setFacesEntities(nodeFacesEntities);
134 model->getNodes()[
"node"] = node.get();
135 model->getSubNodes()[
"node"] = node.get();
138 model->getMaterials()[material->getId()] = material.get();
143 return model.release();
149 auto model = make_unique<Model>(
id,
id, UpVector::Y_UP, RotationOrder::XYZ,
nullptr);
151 auto material = make_unique<Material>(
"primitive");
152 auto specularMaterialProperties = make_unique<SpecularMaterialProperties>();
153 specularMaterialProperties->setAmbientColor(
155 245.0f / 255.0f * 0.5f,
156 40.0f / 255.0f * 0.5f,
157 135.0f / 255.0f * 0.5f,
161 specularMaterialProperties->setDiffuseColor(
163 245.0f / 255.0f * 0.5f,
164 40.0f / 255.0f * 0.5f,
165 135.0f / 255.0f * 0.5f,
169 specularMaterialProperties->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
170 material->setSpecularMaterialProperties(specularMaterialProperties.release());
172 auto node = make_unique<Node>(model.get(),
nullptr,
"primitive",
"primitive");
174 auto fvi = OrientedBoundingBox::getFacesVerticesIndexes();
176 vector<Vector3> vertices;
177 for (
const auto& vertex : orientedBoundingBox->
getVertices()) {
181 auto axes = orientedBoundingBox->
getAxes();
182 vector<Vector3> normals;
192 faces.emplace_back(node.get(), fvi[0][0], fvi[0][1], fvi[0][2], 0, 0, 0);
193 faces.emplace_back(node.get(), fvi[1][0], fvi[1][1], fvi[1][2], 0, 0, 0);
195 faces.emplace_back(node.get(), fvi[2][0], fvi[2][1], fvi[2][2], 1, 1, 1);
196 faces.emplace_back(node.get(), fvi[3][0], fvi[3][1], fvi[3][2], 1, 1, 1);
198 faces.emplace_back(node.get(), fvi[4][0], fvi[4][1], fvi[4][2], 2, 2, 2);
199 faces.emplace_back(node.get(), fvi[5][0], fvi[5][1], fvi[5][2], 2, 2, 2);
201 faces.emplace_back(node.get(), fvi[6][0], fvi[6][1], fvi[6][2], 3, 3, 3);
202 faces.emplace_back(node.get(), fvi[7][0], fvi[7][1], fvi[7][2], 3, 3, 3);
204 faces.emplace_back(node.get(), fvi[8][0], fvi[8][1], fvi[8][2], 4, 4, 4);
205 faces.emplace_back(node.get(), fvi[9][0], fvi[9][1], fvi[9][2], 4, 4, 4);
207 faces.emplace_back(node.get(), fvi[10][0], fvi[10][1], fvi[10][2], 5, 5, 5);
208 faces.emplace_back(node.get(), fvi[11][0], fvi[11][1], fvi[11][2], 5, 5, 5);
210 FacesEntity nodeFacesEntity(node.get(),
"primitive.facesentity");
214 vector<FacesEntity> nodeFacesEntities;
215 nodeFacesEntities.push_back(nodeFacesEntity);
217 node->setVertices(vertices);
218 node->setNormals(normals);
219 node->setFacesEntities(nodeFacesEntities);
221 model->getNodes()[
"node"] = node.get();
222 model->getSubNodes()[
"node"] = node.get();
225 model->getMaterials()[material->getId()] = material.get();
231 return model.release();
239 auto model = make_unique<Model>(
id,
id, UpVector::Y_UP, RotationOrder::XYZ,
nullptr);
241 auto material = make_unique<Material>(
"primitive");
242 auto specularMaterialProperties = make_unique<SpecularMaterialProperties>();
243 specularMaterialProperties->setAmbientColor(
245 245.0f / 255.0f * 0.5f,
246 40.0f / 255.0f * 0.5f,
247 135.0f / 255.0f * 0.5f,
251 specularMaterialProperties->setDiffuseColor(
253 245.0f / 255.0f * 0.5f,
254 40.0f / 255.0f * 0.5f,
255 135.0f / 255.0f * 0.5f,
259 specularMaterialProperties->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
260 material->setSpecularMaterialProperties(specularMaterialProperties.release());
262 auto node = make_unique<Node>(model.get(),
nullptr,
"primitive",
"primitive");
264 vector<Vector3> vertices;
265 for (
auto ySegment = 0; ySegment < segmentsY + 1; ySegment++)
266 for (
auto xSegment = 0; xSegment < segmentsX; xSegment++) {
269 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::cos(Math::PI * 2 * xSegment / segmentsX))),
270 ((Math::cos(Math::PI * ySegment / segmentsY))),
271 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::sin(Math::PI * 2 * xSegment / segmentsX))))
276 vector<Vector3> normals;
279 int32_t vi0, vi1, vi2;
281 for (
auto y = 0; y < segmentsY + 1; y++) {
282 for (
auto x = 0; x < segmentsX; x++) {
283 vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
284 vi1 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
285 vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
288 array<Vector3, 3> faceVertices = {
294 normals.push_back(normal);
297 faces.emplace_back(node.get(), vi0, vi1, vi2, ni + 0, ni + 1, ni + 2);
298 vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
299 vi1 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
300 vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
303 array<Vector3, 3> faceVertices = {
309 normals.push_back(normal);
312 faces.emplace_back(node.get(), vi0, vi1, vi2, ni + 0, ni + 1, ni + 2);
316 FacesEntity nodeFacesEntity(node.get(),
"primitive.facesentity");
320 vector<FacesEntity> nodeFacesEntities;
321 nodeFacesEntities.push_back(nodeFacesEntity);
323 node->setVertices(vertices);
324 node->setNormals(normals);
325 node->setFacesEntities(nodeFacesEntities);
327 model->getNodes()[
"node"] = node.get();
328 model->getSubNodes()[
"node"] = node.get();
331 model->getMaterials()[material->getId()] = material.get();
337 return model.release();
343 const auto radius = capsule->
getRadius();
344 const auto& a = capsule->
getA();
345 const auto& b = capsule->
getB();
346 const auto& center = capsule->
getCenter();
351 Vector3 yAxis(0.0f, -1.0f, 0.0f);
354 if (Math::abs(abNormalized[0]) < Math::EPSILON && Math::abs(abNormalized[2]) < Math::EPSILON) {
355 rotationAxis.
set(abNormalized[1], 0.0f, 0.0f);
357 rotationAxis = Vector3::computeCrossProduct(yAxis, abNormalized).
normalize();
359 auto angle = Vector3::computeAngle(yAxis, abNormalized, yAxis);
360 rotationQuaternion.
rotate(rotationAxis, angle);
361 auto rotationQuaternionMatrixInverted = rotationQuaternion.
computeMatrix();
362 rotationQuaternionMatrixInverted.
invert();
363 auto aInverted = a.
clone().sub(center);
364 auto bInverted = b.
clone().sub(center);
365 aInverted = rotationQuaternionMatrixInverted.
multiply(aInverted);
366 bInverted = rotationQuaternionMatrixInverted.multiply(bInverted);
368 auto model = make_unique<Model>(
id,
id, UpVector::Y_UP, RotationOrder::XYZ,
nullptr);
370 auto material = make_unique<Material>(
"primitive");
371 auto specularMaterialProperties = make_unique<SpecularMaterialProperties>();
372 specularMaterialProperties->setAmbientColor(
374 245.0f / 255.0f * 0.5f,
375 40.0f / 255.0f * 0.5f,
376 135.0f / 255.0f * 0.5f,
380 specularMaterialProperties->setDiffuseColor(
382 245.0f / 255.0f * 0.5f,
383 40.0f / 255.0f * 0.5f,
384 135.0f / 255.0f * 0.5f,
388 specularMaterialProperties->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
389 material->setSpecularMaterialProperties(specularMaterialProperties.release());
391 auto node = make_unique<Node>(model.get(),
nullptr,
"primitive",
"primitive");
393 vector<Vector3> vertices;
395 for (
auto ySegment = 0; ySegment < segmentsY / 2; ySegment++)
396 for (
auto xSegment = 0; xSegment < segmentsX; xSegment++) {
400 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::cos(Math::PI * 2 * xSegment / segmentsX))),
401 ((Math::cos(Math::PI * ySegment / segmentsY))),
402 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::sin(Math::PI * 2 * xSegment / segmentsX)))
405 vertex.
scale(radius);
406 vertex = rotationQuaternionMatrixInverted.
multiply(vertex);
407 vertex.
add(bInverted);
411 for (
auto ySegment = segmentsY / 2; ySegment < segmentsY + 1; ySegment++)
412 for (
auto xSegment = 0; xSegment < segmentsX; xSegment++) {
416 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::cos(Math::PI * 2 * xSegment / segmentsX))),
417 ((Math::cos(Math::PI * ySegment / segmentsY))),
418 ((Math::sin(Math::PI * ySegment / segmentsY) * Math::sin(Math::PI * 2 * xSegment / segmentsX)))
421 vertex.
scale(radius);
422 vertex = rotationQuaternionMatrixInverted.
multiply(vertex);
423 vertex.
add(aInverted);
427 vector<Vector3> normals;
430 int32_t vi0, vi1, vi2;
432 for (
auto y = 0; y < segmentsY + 1; y++) {
433 for (
auto x = 0; x < segmentsX; x++) {
434 vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
435 vi1 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
436 vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
439 array<Vector3, 3> faceVertices = {
445 normals.push_back(normal);
448 faces.emplace_back(node.get(), vi0, vi1, vi2, ni + 0, ni + 1, ni + 2);
449 vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
450 vi1 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
451 vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
453 array<Vector3, 3> faceVertices = {
459 normals.push_back(normal);
462 faces.emplace_back(node.get(), vi0, vi1, vi2, ni + 0, ni + 1, ni + 2);
466 FacesEntity nodeFacesEntity(node.get(),
"primitive.facesentity");
470 vector<FacesEntity> nodeFacesEntities;
471 nodeFacesEntities.push_back(nodeFacesEntity);
473 node->setVertices(vertices);
474 node->setNormals(normals);
475 node->setFacesEntities(nodeFacesEntities);
477 model->getNodes()[
"node"] = node.get();
478 model->getSubNodes()[
"node"] = node.get();
481 model->getMaterials()[material->getId()] = material.get();
487 return model.release();
491 Console::println(
"Primitives::createConvexMeshModel(): This is not supported. Rather load the model and use Primitives::setupConvexMeshModel().");
500 auto material = make_unique<Material>(
"primitive");
501 auto specularMaterialProperties = make_unique<SpecularMaterialProperties>();
502 specularMaterialProperties->setAmbientColor(
504 245.0f / 255.0f * 0.5f,
505 40.0f / 255.0f * 0.5f,
506 135.0f / 255.0f * 0.5f,
510 specularMaterialProperties->setDiffuseColor(
512 245.0f / 255.0f * 0.5f,
513 40.0f / 255.0f * 0.5f,
514 135.0f / 255.0f * 0.5f,
518 specularMaterialProperties->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
519 material->setSpecularMaterialProperties(specularMaterialProperties.release());
520 model->
getMaterials()[material->getId()] = material.get();
526 for (
const auto& [nodeId, node]: nodes) {
527 auto facesEntities = node->getFacesEntities();
528 for (
auto& faceEntity : facesEntities) {
529 faceEntity.setMaterial(material);
531 node->setFacesEntities(facesEntities);
546 if (
dynamic_cast<Sphere*
>(boundingVolume) !=
nullptr) {
549 if (
dynamic_cast<Capsule*
>(boundingVolume) !=
nullptr) {
552 if (
dynamic_cast<ConvexMesh*
>(boundingVolume) !=
nullptr) {
555 Console::println(
string(
"Primitives::createModel(): unsupported bounding volume"));
Color 4 definition class.
Represents a model face, consisting of vertex, normal, tangent and bitangent vectors,...
Node faces entity A node can have multiple entities containing faces and a applied material.
void setMaterial(Material *material)
Set up the entity's material.
void setFaces(const vector< Face > &faces)
Set up entity's faces.
Representation of a 3D model.
unordered_map< string, Node * > & getSubNodes()
Returns object's sub nodes.
unordered_map< string, Material * > & getMaterials()
Returns all object materials.
void setImportTransformMatrix(const Matrix4x4 &importTransformMatrix)
Set import transform matrix.
const Matrix4x4 & getImportTransformMatrix()
Represents rotation orders of a model.
Represents specular material properties.
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
const vector< Vector3 > & getVertices() const
Returns bounding box vertices.
Bounding volume interface.
const Vector3 & getCenter() const
Capsule physics primitive.
const Vector3 & getB() const
const Vector3 & getA() const
Convex mesh physics primitive.
Oriented bounding box physics primitive.
const array< Vector3, 8 > getVertices() const
const array< Vector3, 3 > & getAxes() const
Sphere physics primitive.
Matrix4x4 clone() const
Clones this matrix.
Matrix4x4 & scale(float scalar)
Scales by scalar.
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Matrix4x4 & invert()
Inverts this matrix.
Quaternion class representing quaternion mathematical structure and operations with x,...
Quaternion & identity()
Creates identity quaternion.
Quaternion & add(const Quaternion &quaternion)
Adds quaternion.
Quaternion & scale(float scalar)
Scales by scalar.
Matrix4x4 computeMatrix() const
Computes a rotation matrix4x4 from this quaternion.
Quaternion & multiply(const Quaternion quaternion)
Multiplies this quaternion with given quaternion.
Quaternion & rotate(const Vector3 &axis, float angle)
Creates rotation quaternion.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Vector3 clone() const
Clones this vector3.
Vector3 & sub(float scalar)
Subtracts a scalar.
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Vector3 & normalize()
Normalizes this vector3.
static void println()
Print new line to console.
Helper class to create models from physics primitive bounding volumes.
static void setupConvexMeshMaterial(const unordered_map< string, Node * > &nodes, Material *material)
Set up convex mesh material.
static constexpr int32_t SPHERE_SEGMENTS_X
static Vector3 transformVector3(BoundingVolume *boundingVolume, const reactphysics3d::Vector3 &vector)
Transforms a given ReactPhysics3D vector with bounding volume transform.
static void setupConvexMeshModel(Model *model)
Set up a convex mesh model.
static Model * createBoundingBoxModel(BoundingBox *boundingBox, const string &id)
Creates a model from bounding box.
static Model * createSphereModel(Sphere *sphere, const string &id, int32_t segmentsX, int32_t segmentsY)
Creates a model from oriented bounding box.
static Vector3 transformVector3Normal(BoundingVolume *boundingVolume, const reactphysics3d::Vector3 &normal)
Transforms a given ReactPhysics3D vector with bounding volume transform.
static constexpr int32_t SPHERE_SEGMENTS_Y
static Model * createModel(BoundingBox *boundingVolume, const string &id)
Creates a model from bounding volume.
static Model * createConvexMeshModel(ConvexMesh *mesh, const string &id)
Creates a model from convex mesh.
static Model * createOrientedBoundingBoxModel(OrientedBoundingBox *orientedBoundingBox, const string &id)
Creates a model from oriented bounding box.
static constexpr int32_t CAPSULE_SEGMENTS_Y
static constexpr int32_t CAPSULE_SEGMENTS_X
static Model * createCapsuleModel(Capsule *capsule, const string &id, int32_t segmentsX, int32_t segmentsY)
Creates a model from capsule.
static reactphysics3d::Vector3 toRP3DVector3(const Vector3 &vector)
Converts a TDME2 vector to ReactPhysics3D vector.