27 using std::make_unique;
30 using std::unique_ptr;
53 ObjectRenderGroup::ObjectRenderGroup(
56 float modelLOD2MinDistance,
57 float modelLOD3MinDistance,
58 int modelLOD2ReduceBy,
59 int modelLOD3ReduceBy,
87 if (combinedModelNode ==
nullptr) {
88 auto newCombinedModelNode = make_unique<Node>(
95 combinedModel->
getSubNodes()[newCombinedModelNode->getId()] = newCombinedModelNode.get();
97 combinedModelNode->getParentNode()->getSubNodes()[newCombinedModelNode->getId()] = newCombinedModelNode.get();
99 combinedModel->
getNodes()[newCombinedModelNode->getId()] = newCombinedModelNode.get();
101 combinedModelNode = newCombinedModelNode.release();
105 auto sourceNodeVerticesSize = sourceNode->
getVertices().size();
106 auto sourceNodeNormalsSize = sourceNode->
getNormals().size();
108 auto sourceNodeTangentsSize = sourceNode->
getTangents().size();
109 auto sourceNodeBitangentsSize = sourceNode->
getBitangents().size();
112 auto combinedModelNodeVertices = combinedModelNode->getVertices();
113 auto combinedModelNodeNormals = combinedModelNode->getNormals();
114 auto combinedModelNodeTextureCoordinates = combinedModelNode->getTextureCoordinates();
115 auto combinedModelNodeTangents = combinedModelNode->getTangents();
116 auto combinedModelNodeBitangents = combinedModelNode->getBitangents();
117 auto combinedModelNodeFacesEntities = combinedModelNode->getFacesEntities();
118 auto combinedModelNodeOrigins = combinedModelNode->getOrigins();
121 auto combinedModelNodeVerticesIdxStart = combinedModelNodeVertices.size();
122 auto combinedModelNodeNormalsIdxStart = combinedModelNodeNormals.size();
123 auto combinedModelNodeTextureCoordinatesIdxStart = combinedModelNodeTextureCoordinates.size();
124 auto combinedModelNodeTangentsIdxStart = combinedModelNodeTangents.size();
125 auto combinedModelNodeBitangentsIdxStart = combinedModelNodeBitangents.size();
130 for (
const auto& objectParentTransformMatrix: objectParentTransformMatrices) {
136 for (
const auto& vertex: sourceNode->
getVertices()) {
137 combinedModelNodeOrigins.push_back(origins[i]);
140 for (
const auto& normal: sourceNode->
getNormals()) {
144 combinedModelNodeTextureCoordinates.push_back(textureCoordinate);
146 for (
const auto& tangent: sourceNode->
getTangents()) {
160 bool haveTextureCoordinates = facesEntity.isTextureCoordinatesAvailable();
161 bool haveTangentsBitangents = facesEntity.isTangentBitangentAvailable();
164 FacesEntity* combinedModelNodeFacesEntity =
nullptr;
165 for (
auto& combinedModelNodeFacesEntityExisting: combinedModelNodeFacesEntities) {
166 if (combinedModelNodeFacesEntityExisting.getId() == facesEntity.getId()) {
167 combinedModelNodeFacesEntity = &combinedModelNodeFacesEntityExisting;
172 if (combinedModelNodeFacesEntity ==
nullptr) {
177 combinedModelNodeFacesEntities.push_back(newFacesEntity);
178 combinedModelNodeFacesEntity = &combinedModelNodeFacesEntities[combinedModelNodeFacesEntities.size() - 1];
179 auto combinedModelNodeFacesEntityMaterial = combinedModel->
getMaterials()[facesEntity.getMaterial()->getId()];
180 if (combinedModelNodeFacesEntityMaterial ==
nullptr) {
181 combinedModelNodeFacesEntityMaterial = ModelTools::cloneMaterial(facesEntity.getMaterial());
182 combinedModel->
getMaterials()[combinedModelNodeFacesEntityMaterial->getId()] = combinedModelNodeFacesEntityMaterial;
184 combinedModelNodeFacesEntity->
setMaterial(combinedModelNodeFacesEntityMaterial);
188 auto combinedModelNodeFaces = combinedModelNodeFacesEntity->
getFaces();
191 auto combinedModelNodeVerticesIdx = combinedModelNodeVerticesIdxStart;
192 auto combinedModelNodeNormalsIdx = combinedModelNodeNormalsIdxStart;
193 auto combinedModelNodeTextureCoordinatesIdx = combinedModelNodeTextureCoordinatesIdxStart;
194 auto combinedModelNodeTangentsIdx = combinedModelNodeTangentsIdxStart;
195 auto combinedModelNodeBitangentsIdx = combinedModelNodeBitangentsIdxStart;
196 for (
const auto& objectParentTransformMatrix: objectParentTransformMatrices) {
198 for (
const auto& face: facesEntity.getFaces()) {
200 const auto& faceVertexIndices = face.getVertexIndices();
201 const auto& faceNormalIndices = face.getNormalIndices();
202 const auto& faceTextureCoordinatesIndices = face.getTextureCoordinateIndices();
203 const auto& faceTangentIndices = face.getTangentIndices();
204 const auto& faceBitangentIndices = face.getBitangentIndices();
207 auto combinedModelNodeFace =
210 combinedModelNodeVerticesIdx + faceVertexIndices[0],
211 combinedModelNodeVerticesIdx + faceVertexIndices[1],
212 combinedModelNodeVerticesIdx + faceVertexIndices[2],
213 combinedModelNodeNormalsIdx + faceNormalIndices[0],
214 combinedModelNodeNormalsIdx + faceNormalIndices[1],
215 combinedModelNodeNormalsIdx + faceNormalIndices[2]
217 if (haveTextureCoordinates ==
true) {
218 combinedModelNodeFace.setTextureCoordinateIndices(
219 combinedModelNodeTextureCoordinatesIdx + faceTextureCoordinatesIndices[0],
220 combinedModelNodeTextureCoordinatesIdx + faceTextureCoordinatesIndices[1],
221 combinedModelNodeTextureCoordinatesIdx + faceTextureCoordinatesIndices[2]
224 if (haveTangentsBitangents ==
true) {
225 combinedModelNodeFace.setTangentIndices(
226 combinedModelNodeTangentsIdx + faceTangentIndices[0],
227 combinedModelNodeTangentsIdx + faceTangentIndices[1],
228 combinedModelNodeTangentsIdx + faceTangentIndices[2]
230 combinedModelNodeFace.setBitangentIndices(
231 combinedModelNodeBitangentsIdx + faceBitangentIndices[0],
232 combinedModelNodeBitangentsIdx + faceBitangentIndices[1],
233 combinedModelNodeBitangentsIdx + faceBitangentIndices[2]
236 combinedModelNodeFaces.push_back(combinedModelNodeFace);
240 combinedModelNodeVerticesIdx+= sourceNodeVerticesSize;
241 combinedModelNodeNormalsIdx+= sourceNodeNormalsSize;
242 combinedModelNodeTextureCoordinatesIdx+= sourceNodeTextureCoordinatesSize;
243 combinedModelNodeTangentsIdx+= sourceNodeTangentsSize;
244 combinedModelNodeBitangentsIdx+= sourceNodeBitangentsSize;
246 combinedModelNodeFacesEntity->
setFaces(combinedModelNodeFaces);
250 combinedModelNode->setVertices(combinedModelNodeVertices);
251 combinedModelNode->setNormals(combinedModelNodeNormals);
252 combinedModelNode->setTextureCoordinates(combinedModelNodeTextureCoordinates);
253 combinedModelNode->setTangents(combinedModelNodeTangents);
254 combinedModelNode->setBitangents(combinedModelNodeBitangents);
255 combinedModelNode->setFacesEntities(combinedModelNodeFacesEntities);
256 combinedModelNode->setOrigins(combinedModelNodeOrigins);
260 for (
const auto& [subNodeId, subNode]: sourceNode->
getSubNodes()) {
261 combineNode(subNode, origins, objectParentTransformMatrices, combinedModel);
266 vector<Matrix4x4> objectTransformMatrices;
267 vector<Vector3> origins;
268 for (
const auto& objectTransform: objectsTransform) {
273 origins.push_back(objectTransform.getTranslation());
275 for (
const auto& [subNodeId, subNode]: model->
getSubNodes()) {
276 combineNode(subNode, origins, objectTransformMatrices, combinedModel);
291 id +
".o3rg.lod." + to_string(i),
292 id +
".o3rg.lod." + to_string(i),
305 auto objectCount = 0;
306 vector<Transform> reducedObjectsTransform;
307 for (
const auto& objectTransform: objectsTransform) {
308 if (objectCount % reduceByFactor != 0) {
312 reducedObjectsTransform.push_back(objectTransform);
315 combineObjects(model, reducedObjectsTransform, combinedModel.get());
321 if (combinedModel !=
nullptr) {
323 ModelTools::shrinkToFit(combinedModel.get());
324 ModelTools::createDefaultAnimation(combinedModel.get(), 0);
325 ModelTools::setupJoints(combinedModel.get());
326 ModelTools::fixAnimationLength(combinedModel.get());
340 combinedObject->setParentEntity(
this);
342 combinedObject->setShader(
shaderId);
345 combinedObject->setEngine(
engine);
347 combinedObject->update();
363 combinedLODObject->setParentEntity(
this);
365 combinedLODObject->setShader(
shaderId);
368 combinedLODObject->setEngine(
engine);
370 if (combinedLODObject->objectLOD1 !=
nullptr) {
373 if (combinedLODObject->objectLOD2 !=
nullptr) {
376 if (combinedLODObject->objectLOD3 !=
nullptr) {
379 combinedLODObject->update();
435 if (this->enabled ==
enabled)
return;
462 if (this->frustumCulling ==
true) {
void set(float r, float g, float b, float a)
Sets this color by its components.
unique_ptr< Partition > partition
void updateEntityRegistration(Entity *entity)
Updates registration of engine by performing deregisterEntity() and registerEntity()
void deregisterEntity(Entity *entity)
Removes a entity from internal lists, those entities can also be sub entities from entity hierarchy o...
void removeEntityFromLists(Entity *entity)
Remove entity.
void registerEntity(Entity *entity)
Adds a entity to internal lists, those entities can also be sub entities from entity hierarchy or par...
LOD object to be used with engine class.
Object render group for static objects that might be animated by shaders.
void dispose() override
Dispose this entity.
static void combineNode(Node *sourceNode, const vector< Vector3 > &origins, const vector< Matrix4x4 > &objectParentTransformMatrices, Model *combinedModel)
Combine node into given combined model.
Transform parentTransform
BoundingBox worldBoundingBox
void initialize() override
Initiates this entity.
~ObjectRenderGroup()
Destructor.
EntityShaderParameters shaderParameters
void update() override
Update transform.
void updateRenderGroup()
Update render group model and bounding box.
vector< unique_ptr< Model > > combinedModels
array< int, 3 > lodReduceBy
float modelLOD3MinDistance
Matrix4x4 entityTransformMatrix
void setTransform(const Transform &transform) override
Set transform.
void updateBoundingBox()
Compute bounding box.
unordered_map< Model *, vector< Transform > > transformByModel
float modelLOD2MinDistance
void addObject(Model *model, const Transform &transform)
Adds a instance to this render group.
static void combineObjects(Model *model, const vector< Transform > &objectsTransform, Model *combinedModel)
Combine model with transform into current model.
unique_ptr< Entity > combinedEntity
void setFrustumCulling(bool frustumCulling) override
Set frustum culling.
void setEngine(Engine *engine) override
Set up engine.
void setEnabled(bool enabled) override
Enable/disable rendering.
bool isFrustumCulling() override
void setRenderer(Renderer *renderer) override
Set up renderer.
Object to be used with engine 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.
const vector< Face > & getFaces() const
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.
const Matrix4x4 & getImportTransformMatrix()
unordered_map< string, Node * > & getNodes()
Returns all object's nodes.
Node * getNodeById(const string &id)
Returns a node by given name or null.
const vector< Vector3 > & getBitangents() const
unordered_map< string, Node * > & getSubNodes()
const vector< Vector3 > & getTangents() const
const vector< Vector3 > & getVertices() const
const vector< Vector3 > & getNormals() const
const vector< Vector2 > & getTextureCoordinates() const
const string & getId()
Returns id.
const vector< FacesEntity > & getFacesEntities() const
const Matrix4x4 & getTransformMatrix() const
Represents rotation orders of a model.
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
void fromBoundingVolumeWithTransformMatrix(BoundingBox *original, const Matrix4x4 &transformMatrix)
Create bounding volume from given original(of same type) with applied transform matrix.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Matrix4x4 & identity()
Creates identity matrix.
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Matrix4x4 & set(float r0c0, float r0c1, float r0c2, float r0c3, float r1c0, float r1c1, float r1c2, float r1c3, float r2c0, float r2c1, float r2c2, float r2c3, float r3c0, float r3c1, float r3c2, float r3c3)
Sets this matrix by its components.
Vector3 multiplyNoTranslation(const Vector3 &vector3) const
Multiplies this matrix with vector3 while ignoring translation.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Vector3 class representing vector3 mathematical structure and operations with x, y,...