3 #if defined(_WIN32) && defined(_MSC_VER)
4 #pragma warning(disable:4503)
9 #include <unordered_map>
88 using std::make_unique;
91 using std::unique_ptr;
92 using std::unordered_map;
171 Model* SceneConnector::emptyModel =
nullptr;
172 float SceneConnector::renderGroupsPartitionWidth = 64.0f;
173 float SceneConnector::renderGroupsPartitionHeight = 64.0f;
174 float SceneConnector::renderGroupsPartitionDepth = 64.0f;
175 int SceneConnector::renderGroupsReduceBy = 1;
176 int SceneConnector::renderGroupsLODLevels = 3;
177 float SceneConnector::renderGroupsLOD2MinDistance = 25.0;
178 float SceneConnector::renderGroupsLOD3MinDistance = 50.0;
179 int SceneConnector::renderGroupsLOD2ReduceBy = 4;
180 int SceneConnector::renderGroupsLOD3ReduceBy = 16;
182 void SceneConnector::setNaturalLights(
Engine* engine,
float t) {
184 for (
auto light: engine->
getLights()) light->setEnabled(
false);
187 auto sunColor =
Vector3(1.0f, 1.0f, 1.0f);
188 auto sunAmbientColor = sunColor * 0.5;
189 auto sunDiffuseColor = sunColor * 0.3;
190 sunLight->setupSun(t);
191 sunLight->setAmbient(
Color4(sunAmbientColor[0], sunAmbientColor[1], sunAmbientColor[2], 1.0f));
192 sunLight->setDiffuse(
Color4(sunDiffuseColor[0], sunDiffuseColor[1], sunDiffuseColor[2], 1.0f));
193 sunLight->setSpecular(
Color4(1.0f, 1.0f, 1.0f, 1.0f));
194 sunLight->setEnabled(
true);
197 auto moonColor =
Vector3(1.0f, 1.0f, 1.0f);
198 auto moonAmbientColor = moonColor * 0.5 * 0.5;
199 auto moonDiffuseColor = moonColor * 0.3 * 0.5;
200 moonLight->setupMoon(t);
201 moonLight->setAmbient(
Color4(moonAmbientColor[0], moonAmbientColor[1], moonAmbientColor[2], 1.0f));
202 moonLight->setDiffuse(
Color4(moonDiffuseColor[0], moonDiffuseColor[1], moonDiffuseColor[2], 1.0f));
203 moonLight->setSpecular(
Color4(1.0f, 1.0f, 1.0f, 1.0f));
204 moonLight->setEnabled(
true);
213 for (
auto sceneLight: scene->
getLights()) {
228 sceneLight->getPosition().getX() + translation.
getX(),
229 sceneLight->getPosition().getY() + translation.
getY(),
230 sceneLight->getPosition().getZ() + translation.
getZ(),
231 sceneLight->getPosition().getW()
241 unique_ptr<ParticleEmitter> engineEmitter;
243 auto emitterType = particleSystem->
getEmitter();
244 if (emitterType == PrototypeParticleSystem_Emitter::NONE) {
247 if (emitterType == PrototypeParticleSystem_Emitter::POINT_PARTICLE_EMITTER) {
249 engineEmitter = make_unique<PointParticleEmitter>(emitter->getCount(), emitter->getLifeTime(), emitter->getLifeTimeRnd(), emitter->getMass(), emitter->getMassRnd(), emitter->getPosition(), emitter->getVelocity(), emitter->getVelocityRnd(), emitter->getColorStart(), emitter->getColorEnd());
251 if (emitterType == PrototypeParticleSystem_Emitter::BOUNDINGBOX_PARTICLE_EMITTER) {
253 engineEmitter = make_unique<BoundingBoxParticleEmitter>(emitter->getCount(), emitter->getLifeTime(), emitter->getLifeTimeRnd(), emitter->getMass(), emitter->getMassRnd(),
new OrientedBoundingBox(emitter->getObbCenter(), emitter->getObbAxis0(), emitter->getObbAxis1(), emitter->getObbAxis2(), emitter->getObbHalfextension()), emitter->getVelocity(), emitter->getVelocityRnd(), emitter->getColorStart(), emitter->getColorEnd());
255 if (emitterType == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER) {
257 engineEmitter = make_unique<CircleParticleEmitter>(emitter->getCount(), emitter->getLifeTime(), emitter->getLifeTimeRnd(), emitter->getAxis0(), emitter->getAxis1(), emitter->getCenter(), emitter->getRadius(), emitter->getMass(), emitter->getMassRnd(), emitter->getVelocity(), emitter->getVelocityRnd(), emitter->getColorStart(), emitter->getColorEnd());
259 if (emitterType == PrototypeParticleSystem_Emitter::CIRCLE_PARTICLE_EMITTER_PLANE_VELOCITY) {
261 engineEmitter = make_unique<CircleParticleEmitterPlaneVelocity>(emitter->getCount(), emitter->getLifeTime(), emitter->getLifeTimeRnd(), emitter->getAxis0(), emitter->getAxis1(), emitter->getCenter(), emitter->getRadius(), emitter->getMass(), emitter->getMassRnd(), emitter->getVelocity(), emitter->getVelocityRnd(), emitter->getColorStart(), emitter->getColorEnd());
263 if (emitterType == PrototypeParticleSystem_Emitter::SPHERE_PARTICLE_EMITTER) {
265 engineEmitter = make_unique<SphereParticleEmitter>(emitter->getCount(), emitter->getLifeTime(), emitter->getLifeTimeRnd(), emitter->getMass(), emitter->getMassRnd(),
new Sphere(emitter->getCenter(), emitter->getRadius()), emitter->getVelocity(), emitter->getVelocityRnd(), emitter->getColorStart(), emitter->getColorEnd());
269 "SceneConnector::createParticleSystem(): unknown particle system emitter '" +
279 auto particleSystemType = particleSystem->
getType();
280 if (particleSystemType == PrototypeParticleSystem_Type::NONE) {
283 if (particleSystemType == PrototypeParticleSystem_Type::OBJECT_PARTICLE_SYSTEM) {
285 if (objectParticleSystem->getModel() ==
nullptr)
return nullptr;
287 make_unique<ObjectParticleSystem>(
289 objectParticleSystem->getModel(),
290 objectParticleSystem->getScale(),
291 objectParticleSystem->isAutoEmit(),
292 enableDynamicShadows,
293 enableDynamicShadows,
294 objectParticleSystem->getMaxCount(),
295 engineEmitter.release()
298 if (particleSystemType == PrototypeParticleSystem_Type::POINT_PARTICLE_SYSTEM) {
301 make_unique<PointsParticleSystem>(
303 engineEmitter.release(),
304 pointParticleSystem->getMaxPoints(),
305 pointParticleSystem->getPointSize(),
306 pointParticleSystem->isAutoEmit(),
307 pointParticleSystem->getTextureReference(),
308 pointParticleSystem->getTextureHorizontalSprites(),
309 pointParticleSystem->getTextureVerticalSprites(),
310 pointParticleSystem->getTextureSpritesFPS()
313 if (particleSystemType == PrototypeParticleSystem_Type::FOG_PARTICLE_SYSTEM) {
316 make_unique<FogParticleSystem>(
318 engineEmitter.release(),
319 fogParticleSystem->getMaxPoints(),
320 fogParticleSystem->getPointSize(),
321 fogParticleSystem->getTextureReference(),
322 fogParticleSystem->getTextureHorizontalSprites(),
323 fogParticleSystem->getTextureVerticalSprites(),
324 fogParticleSystem->getTextureSpritesFPS()
329 "SceneConnector::createParticleSystem(): unknown particle system type '" +
341 emptyModel = ModelReader::read(
"resources/engine/models",
"empty.tm");
347 entity->setTransform(transform);
353 if (prototype->
getType() != Prototype_Type::DECAL)
return nullptr;
359 auto entityHierarchy = make_unique<EntityHierarchy>(
id);
363 if (prototypeBoundingVolume->getModel() !=
nullptr) {
364 auto bvObject =
new Object(
"tdme.prototype.bv." + to_string(i), prototypeBoundingVolume->getModel());
366 entityHierarchy->addEntity(bvObject);
374 entityHierarchy->addEntity(
387 entityHierarchy->setTransform(transform);
388 entityHierarchy->update();
389 if (entityHierarchy->getEntities().size() == 0) {
390 entityHierarchy->dispose();
392 entity = entityHierarchy.release();
403 if (prototype->
getModel() !=
nullptr) {
408 if (imposterLOD !=
nullptr) {
412 imposterLOD->getModels(),
413 imposterLOD->getMinDistance()
417 imposterLodObject->setEffectColorMulLOD2(imposterLOD->getColorMul());
419 imposterLodObject->setShader(prototype->
getShader());
422 imposterLodObject->setShaderParameter(parameterName, parameterValue);
425 if (lodLevel2 !=
nullptr) {
429 lodLevel2->getType(),
430 lodLevel2->getMinDistance(),
431 lodLevel2->getModel(),
433 lodLevel3 !=
nullptr?lodLevel3->getMinDistance():0.0f,
434 lodLevel3 !=
nullptr?lodLevel3->getModel():
nullptr
436 auto lodObject =
dynamic_cast<LODObject*
>(entity);
438 lodObject->setEffectColorMulLOD2(lodLevel2->getColorMul());
439 if (lodLevel3 !=
nullptr) {
440 lodObject->setEffectColorAddLOD3(lodLevel3->getColorAdd());
441 lodObject->setEffectColorMulLOD3(lodLevel3->getColorMul());
444 lodObject->setShader(prototype->
getShader());
447 lodObject->setShaderParameter(parameterName, parameterValue);
456 auto object =
dynamic_cast<Object*
>(entity);
459 object->setShader(prototype->
getShader());
462 object->setShaderParameter(parameterName, parameterValue);
467 if (prototype->
getType() == Prototype_Type::PARTICLESYSTEM) {
468 vector<ParticleSystem*> particleSystems;
472 prototypeParticleSystem,
473 id + (i == 0?
"":
"." + to_string(i)),
476 if (particleSystem !=
nullptr) particleSystems.push_back(
dynamic_cast<ParticleSystem*
>(particleSystem));
479 if (particleSystems.size() == 1) {
480 entity =
dynamic_cast<Entity*
>(particleSystems[0]);
482 if (particleSystems.size() > 1) {
493 if (prototype->
getType() == Prototype_Type::DECAL) {
505 if (prototype->
getType() == Prototype_Type::TRIGGER ||
506 prototype->
getType() == Prototype_Type::ENVIRONMENTMAPPING) {
508 auto entityHierarchy = make_unique<EntityHierarchy>(
id);
512 if (prototypeBoundingVolume->getModel() !=
nullptr) {
513 auto bvObject =
new Object(
"tdme.prototype.bv." + to_string(i), prototypeBoundingVolume->getModel());
515 entityHierarchy->addEntity(bvObject);
520 if (prototype->
getType() == Prototype_Type::ENVIRONMENTMAPPING &&
527 entityHierarchy->addEntity(environmentMapping);
529 entityHierarchy->update();
530 if (entityHierarchy->getEntities().size() == 0) {
531 entityHierarchy->dispose();
533 entity = entityHierarchy.release();
540 entityHierarchy->addEntity(entity);
542 entity = entityHierarchy;
546 if (entity !=
nullptr) {
579 auto progressCallbackPtr = unique_ptr<ProgressCallback>(progressCallback);
580 if (progressCallbackPtr !=
nullptr) progressCallbackPtr->progress(0.0f);
589 if (prototype !=
nullptr) {
593 auto depth = terrain->getDepth();
596 vector<Model*> terrainModels;
597 Terrain::createTerrainModels(width, depth, 0.0f, terrain->getHeightVector(), terrainBoundingBox, terrainModels);
598 if (terrainModels.empty() ==
false) {
600 for (
auto terrainModel: terrainModels) {
601 auto terrainObject =
new Object(
"tdme.terrain." + to_string(idx++), terrainModel);
603 terrainObject->setShader(
"terrain");
604 terrainObject->setContributesShadows(
true);
605 terrainObject->setReceivesShadows(
true);
606 terrainObject->setPickable(pickable);
607 terrainObject->setEnabled(enable);
608 terrainObject->setTranslation(translation);
609 terrainObject->update();
616 auto waterPositionMapsIndices = terrain->getWaterPositionMapsIndices();
617 for (
auto waterPositionMapIdx: waterPositionMapsIndices) {
618 vector<Model*> waterModels;
619 Terrain::createWaterModels(
621 prototype->getTerrain()->getWaterPositionMap(waterPositionMapIdx),
622 prototype->getTerrain()->getWaterPositionMapHeight(waterPositionMapIdx),
626 for (
auto waterModel: waterModels) {
627 auto waterObject =
new Object(
"tdme.water." + to_string(idx++), waterModel);
629 waterObject->setShader(
"water");
631 waterObject->setContributesShadows(
false);
632 waterObject->setReceivesShadows(
false);
633 waterObject->setReflectionEnvironmentMappingId(
"sky_environment_mapping");
634 waterObject->setReflectionEnvironmentMappingPosition(
635 Terrain::computeWaterReflectionEnvironmentMappingPosition(
636 terrain->getWaterPositionMap(waterPositionMapIdx),
637 terrain->getWaterPositionMapHeight(waterPositionMapIdx)
640 waterObject->setPickable(pickable);
641 waterObject->setEnabled(enable);
642 waterObject->setTranslation(translation);
643 waterObject->update();
651 const auto& foliageMaps = terrain->getFoliageMaps();
654 auto foliageRenderGroupIdx = 0;
655 auto partitionIdx = 0;
656 unordered_map<int, int> prototypeEntityIdx;
657 for (
auto& foliageMapPartition: foliageMaps) {
658 auto partitionPrototypeInstanceCount = 0;
659 for (
const auto& [prototypeIdx, transformVector]: foliageMapPartition) {
660 partitionPrototypeInstanceCount+= transformVector.size();
662 if (partitionPrototypeInstanceCount > 0) {
663 unordered_map<string, ObjectRenderGroup*> objectRenderGroupByShaderParameters;
664 for (
const auto& [prototypeIdx, transformVector]: foliageMapPartition) {
665 if (transformVector.empty() ==
true)
continue;
666 auto foliagePrototype = prototype->getTerrain()->getFoliagePrototype(prototypeIdx);
667 if (foliagePrototype->isRenderGroups() ==
false) {
668 for (
auto& transform: transformVector) {
669 auto entity =
createEntity(foliagePrototype,
"tdme.foliage." + to_string(prototypeIdx) +
"." + to_string(prototypeEntityIdx[prototypeIdx]++), transform);
670 if (entity ==
nullptr)
continue;
671 entity->setTranslation(entity->getTranslation().clone().add(translation));
672 entity->setPickable(pickable);
673 entity->setEnabled(enable);
680 auto receivesShadows = foliagePrototype->isReceivesShadows();
681 auto hash = foliagePrototype->getShaderParameters().getShaderParametersHash() +
"|" + to_string(contributesShadows) +
"|" + to_string(receivesShadows);
682 auto foliagePartitionObjectRenderGroupIt = objectRenderGroupByShaderParameters.find(hash);
683 if (foliagePartitionObjectRenderGroupIt != objectRenderGroupByShaderParameters.end()) {
684 foliagePartitionObjectRenderGroup = foliagePartitionObjectRenderGroupIt->second;
686 if (foliagePartitionObjectRenderGroup ==
nullptr) {
687 foliagePartitionObjectRenderGroup =
689 "tdme.fo3rg." + to_string(foliageRenderGroupIdx++),
698 foliagePartitionObjectRenderGroup->
setShader(foliagePrototype->getShader());
700 auto parameterValue = foliagePrototype->getShaderParameters().getShaderParameter(parameterName);
703 foliagePartitionObjectRenderGroup->
setPickable(
false);
704 foliagePartitionObjectRenderGroup->
setEnabled(enable);
705 objectRenderGroupByShaderParameters[hash] = foliagePartitionObjectRenderGroup;
710 for (
auto& transform: transformVector) {
713 foliagePartitionObjectRenderGroup->
addObject(foliagePrototype->getModel(), transform);
717 for (
const auto& [shaderHashId, foliagePartitionObjectRenderGroup]: objectRenderGroupByShaderParameters) {
718 foliagePartitionObjectRenderGroup->updateRenderGroup();
719 foliagePartitionObjectRenderGroup->setTranslation(translation);
720 foliagePartitionObjectRenderGroup->update();
721 engine->
addEntity(foliagePartitionObjectRenderGroup);
731 unordered_map<string, unordered_map<string, unordered_map<Model*, vector<Transform*>>>> renderGroupEntitiesByShaderPartitionModel;
732 unordered_map<Model*, Prototype*> renderGroupSceneEditorEntities;
733 auto progressStepCurrent = 0;
735 if (progressCallbackPtr !=
nullptr && progressStepCurrent % 1000 == 0) progressCallbackPtr->progress(0.0f +
static_cast<float>(progressStepCurrent) /
static_cast<float>(scene->
getEntityCount()) * 0.5f);
736 progressStepCurrent++;
738 if (addEmpties ==
false && sceneEntity->getPrototype()->getType() == Prototype_Type::EMPTY)
continue;
739 if (addTrigger ==
false && sceneEntity->getPrototype()->getType() == Prototype_Type::TRIGGER)
continue;
741 if (sceneEntity->getPrototype()->isRenderGroups() ==
true) {
742 auto minX = sceneEntity->getTransform().getTranslation().getX();
743 auto minY = sceneEntity->getTransform().getTranslation().getY();
744 auto minZ = sceneEntity->getTransform().getTranslation().getZ();
748 renderGroupSceneEditorEntities[sceneEntity->getPrototype()->getModel()] = sceneEntity->getPrototype();
749 renderGroupEntitiesByShaderPartitionModel[sceneEntity->getPrototype()->getShader()][to_string(partitionX) +
"," + to_string(partitionY) +
"," + to_string(partitionZ)][sceneEntity->getPrototype()->getModel()].push_back(&sceneEntity->getTransform());
752 if (entity ==
nullptr)
continue;
754 entity->setTranslation(entity->getTranslation().clone().add(translation));
755 entity->setPickable(pickable);
756 entity->setContributesShadows(sceneEntity->getPrototype()->isContributesShadows());
757 entity->setReceivesShadows(sceneEntity->getPrototype()->isReceivesShadows());
758 if (sceneEntity->getPrototype()->getType() == Prototype_Type::EMPTY) {
759 entity->setScale(
Vector3(Math::sign(entity->getScale().getX()), Math::sign(entity->getScale().getY()), Math::sign(entity->getScale().getZ())));
761 if (sceneEntity->getPrototype()->getType()->hasNonEditScaleDownMode() ==
true) {
763 sceneEntity->getPrototype()->getType()->getNonEditScaleDownModeDimension().
767 1.0f / (sceneEntity->getTransform().getScale().getX() * entity->getBoundingBox()->getDimensions().getX()),
768 1.0f / (sceneEntity->getTransform().getScale().getY() * entity->getBoundingBox()->getDimensions().getY()),
769 1.0f / (sceneEntity->getTransform().getScale().getZ() * entity->getBoundingBox()->getDimensions().getZ())
775 entity->setEnabled(enable);
777 auto object =
dynamic_cast<Object*
>(entity);
787 progressStepCurrent = 0;
788 auto progressStepMax = 0;
789 if (progressCallbackPtr !=
nullptr) {
790 for (
const auto& [shaderId, shaderPartitionModelTranformsMap]: renderGroupEntitiesByShaderPartitionModel) {
791 for (
const auto& [partitionId, modelTranformsMap]: shaderPartitionModelTranformsMap) {
792 for (
const auto& [model, transformVector]: modelTranformsMap) {
798 for (
const auto& [shaderId, shaderPartitionModelTranformsMap]: renderGroupEntitiesByShaderPartitionModel) {
799 for (
const auto& [partitionId, modelTranformsMap]: shaderPartitionModelTranformsMap) {
800 unordered_map<string, ObjectRenderGroup*> objectRenderGroupsByShaderParameters;
801 for (
const auto& [model, transformVector]: modelTranformsMap) {
802 if (progressCallbackPtr !=
nullptr) {
803 progressCallbackPtr->progress(0.5f +
static_cast<float>(progressStepCurrent) /
static_cast<float>(progressStepMax) * 0.5f);
805 progressStepCurrent++;
806 auto prototype = renderGroupSceneEditorEntities[model];
807 auto contributesShadows = prototype->isContributesShadows();
808 auto receivesShadows = prototype->isReceivesShadows();
809 auto hash = prototype->getShaderParameters().getShaderParametersHash() +
"|" + to_string(contributesShadows) +
"|" + to_string(receivesShadows);
810 if (objectRenderGroupsByShaderParameters.find(hash) == objectRenderGroupsByShaderParameters.end()) {
811 auto objectRenderNode =
813 "tdme.o3rg." + to_string(idx++),
820 objectRenderNode->setContributesShadows(contributesShadows);
821 objectRenderNode->setReceivesShadows(receivesShadows);
822 objectRenderNode->setShader(prototype->getShader());
824 auto parameterValue = prototype->getShaderParameters().getShaderParameter(parameterName);
825 objectRenderNode->setShaderParameter(parameterName, parameterValue);
827 objectRenderGroupsByShaderParameters[hash] = objectRenderNode;
829 auto objectRenderNode = objectRenderGroupsByShaderParameters[hash];
831 for (
const auto& transform: transformVector) {
834 objectRenderNode->addObject(prototype->getModel(), *transform);
837 for (
const auto& [hash, objectRenderNode]: objectRenderGroupsByShaderParameters) {
838 objectRenderNode->updateRenderGroup();
846 if (progressCallbackPtr !=
nullptr) {
847 progressCallbackPtr->progress(1.0f);
853 if (prototype->
getType() == Prototype_Type::EMPTY)
return nullptr;
855 if (prototype->
getPhysics() ==
nullptr)
return nullptr;
857 auto physicsType = overrideType !=
nullptr?overrideType:prototype->
getPhysics()->
getType();
859 if (prototype->
getType() == Prototype_Type::TRIGGER) {
860 vector<BoundingVolume*> boundingVolumes;
863 if (index == -1 || index == j) boundingVolumes.push_back(prototypeBoundingVolume->getBoundingVolume());
866 if (boundingVolumes.size() == 0)
return nullptr;
877 if (prototype->
getType() == Prototype_Type::MODEL &&
880 auto terrainMesh =
new TerrainMesh(&terrainModel, transform);
881 if (physicsType == PrototypePhysics_BodyType::COLLISION_BODY) {
891 if (physicsType == PrototypePhysics_BodyType::STATIC_RIGIDBODY) {
902 if (physicsType == PrototypePhysics_BodyType::DYNAMIC_RIGIDBODY) {
918 vector<BoundingVolume*> boundingVolumes;
921 if (index == -1 || index == j) boundingVolumes.push_back(entityBv->getBoundingVolume());
923 if (boundingVolumes.size() == 0)
return nullptr;
924 if (physicsType == PrototypePhysics_BodyType::COLLISION_BODY) {
934 if (physicsType == PrototypePhysics_BodyType::STATIC_RIGIDBODY) {
945 if (physicsType == PrototypePhysics_BodyType::DYNAMIC_RIGIDBODY) {
966 transform.
setTranslation(transform.getTranslation().clone().add(translation));
969 return createBody(world, sceneEntity->
getPrototype(), sceneEntity->
getId(), transform, collisionTypeId, hierarchy, index, overrideType);
974 if (bodyHierarchy ==
nullptr) {
975 Console::println(
"SceneConnector::createSubBody(): body hierarchy not found: " + bodyHierarchyId);
979 bodyHierarchy->update();
980 return bodyHierarchy;
985 auto progressCallbackPtr = unique_ptr<ProgressCallback>(progressCallback);
986 if (progressCallbackPtr !=
nullptr) progressCallbackPtr->progress(0.0f);
987 auto progressStepCurrent = 0;
995 if (prototype !=
nullptr) {
999 auto depth = terrain->getDepth();
1000 auto terrainHeightVectorVerticesPerX =
static_cast<int>(Math::ceil(width / Terrain::STEP_SIZE));
1001 auto terreinHeightVectorVerticesPerZ =
static_cast<int>(Math::ceil(depth / Terrain::STEP_SIZE));
1003 auto minHeight = terrain->getHeightVector()[0];
1004 auto maxHeight = terrain->getHeightVector()[0];
1005 for (
auto heightValue: terrain->getHeightVector()) {
1006 if (heightValue < minHeight) minHeight = heightValue;
1007 if (heightValue > maxHeight) maxHeight = heightValue;
1011 auto heightMap = make_unique<HeightMap>(
1012 terrainHeightVectorVerticesPerX,
1013 terreinHeightVectorVerticesPerZ,
1016 terrain->getHeightVector().data()
1037 const auto& foliageMaps = terrain->getFoliageMaps();
1040 unordered_map<int, int> prototypeBodyIdx;
1041 for (
const auto& foliageMapPartition: foliageMaps) {
1042 for (
const auto& [prototypeIdx, transformVector]: foliageMapPartition) {
1043 if (transformVector.empty() ==
true)
continue;
1044 auto foliagePrototype = prototype->getTerrain()->getFoliagePrototype(prototypeIdx);
1045 if (foliagePrototype->isRenderGroups() ==
true)
continue;
1046 for (
const auto& foliageTransform: transformVector) {
1047 auto body =
createBody(world, foliagePrototype,
"tdme.foliage." + to_string(prototypeIdx) +
"." + to_string(prototypeBodyIdx[prototypeIdx]++), foliageTransform);
1048 if (body ==
nullptr)
continue;
1050 auto transform = foliageTransform;
1051 transform.setTranslation(transform.getTranslation().clone().add(translation));
1053 body->setTransform(transform);
1055 body->setEnabled(enable);
1066 if (progressCallbackPtr !=
nullptr && progressStepCurrent % 1000 == 0) progressCallbackPtr->progress(0.0f +
static_cast<float>(progressStepCurrent) /
static_cast<float>(scene->
getEntityCount()) * 1.0f);
1067 progressStepCurrent++;
1070 auto rigidBody =
createBody(world, sceneEntity);
1071 if (rigidBody ==
nullptr)
continue;
1073 auto transform = sceneEntity->getTransform();
1074 transform.setTranslation(transform.getTranslation().clone().add(translation));
1076 rigidBody->setTransform(transform);
1078 rigidBody->setEnabled(enable);
1082 if (progressCallbackPtr !=
nullptr) {
1083 progressCallbackPtr->progress(1.0f);
1092 Entity* entity =
nullptr;
1093 while ((entity = engine->
getEntity(
"tdme.terrain." + to_string(idx++))) !=
nullptr) {
1099 Entity* entity =
nullptr;
1100 while ((entity = engine->
getEntity(
"tdme.water." + to_string(idx++))) !=
nullptr) {
1106 Entity* entity =
nullptr;
1107 while ((entity = engine->
getEntity(
"tdme.fo3rg." + to_string(idx++))) !=
nullptr) {
1113 Entity* entity =
nullptr;
1114 while ((entity = engine->
getEntity(
"tdme.o3rg." + to_string(idx++))) !=
nullptr) {
1125 if (prototype !=
nullptr) {
1129 for (
auto prototypeIdx: terrain->getFoliagePrototypeIndices()) {
1131 if (foliagePrototype->isRenderGroups() ==
true)
continue;
1132 for (
auto& entityId: terrain->getFoliagePrototypeEntityIds(prototypeIdx)) {
1133 auto entity = engine->
getEntity(entityId);
1134 if (entity !=
nullptr) entity->
setEnabled(
false);
1142 auto entity = engine->
getEntity(sceneEntity->getId());
1143 if (entity ==
nullptr)
1154 auto body = world->
getBody(
"tdme.terrain");
1155 if (body !=
nullptr) body->
setEnabled(
false);
1164 if (prototype !=
nullptr) {
1168 for (
auto prototypeIdx: terrain->getFoliagePrototypeIndices()) {
1170 if (foliagePrototype->isRenderGroups() ==
true)
continue;
1171 for (
auto& bodyId: terrain->getFoliagePrototypeEntityIds(prototypeIdx)) {
1172 auto body = world->
getBody(bodyId);
1173 if (body !=
nullptr) body->
setEnabled(
false);
1181 auto body = world->
getBody(sceneEntity->getId());
1182 if (body ==
nullptr)
continue;
1192 Entity* entity =
nullptr;
1193 while ((entity = engine->
getEntity(
"tdme.terrain." + to_string(idx++))) !=
nullptr) {
1199 Entity* entity =
nullptr;
1200 while ((entity = engine->
getEntity(
"tdme.water." + to_string(idx++))) !=
nullptr) {
1206 Entity* entity =
nullptr;
1207 while ((entity = engine->
getEntity(
"tdme.fo3rg." + to_string(idx++))) !=
nullptr) {
1213 Entity* entity =
nullptr;
1214 while ((entity = engine->
getEntity(
"tdme.o3rg." + to_string(idx++))) !=
nullptr) {
1225 if (prototype !=
nullptr) {
1229 for (
auto prototypeIdx: terrain->getFoliagePrototypeIndices()) {
1231 if (foliagePrototype->isRenderGroups() ==
true)
continue;
1232 for (
auto& entityId: terrain->getFoliagePrototypeEntityIds(prototypeIdx)) {
1233 auto entity = engine->
getEntity(entityId);
1234 if (entity !=
nullptr) entity->
setEnabled(
true);
1242 auto entity = engine->
getEntity(sceneEntity->getId());
1243 if (entity ==
nullptr)
1247 entity->setTranslation(entity->getTranslation().clone().add(translation));
1248 if (sceneEntity->getPrototype()->getType() == Prototype_Type::EMPTY) {
1249 entity->setScale(
Vector3(Math::sign(entity->getScale().getX()), Math::sign(entity->getScale().getY()), Math::sign(entity->getScale().getZ())));
1252 entity->setEnabled(
true);
1260 auto body = world->
getBody(
"tdme.terrain");
1261 if (body !=
nullptr) {
1273 if (prototype !=
nullptr) {
1277 for (
auto prototypeIdx: terrain->getFoliagePrototypeIndices()) {
1279 if (foliagePrototype->isRenderGroups() ==
true)
continue;
1280 for (
auto& bodyId: terrain->getFoliagePrototypeEntityIds(prototypeIdx)) {
1281 auto body = world->
getBody(bodyId);
1291 auto rigidBody = world->
getBody(sceneEntity->getId());
1292 if (rigidBody ==
nullptr)
continue;
1296 rigidBody->setTransform(transform);
1297 rigidBody->setEnabled(
true);
1304 Entity* entity =
nullptr;
1305 while ((entity = engine->
getEntity(
"tdme.terrain." + to_string(idx++))) !=
nullptr) {
1312 Entity* entity =
nullptr;
1313 while ((entity = engine->
getEntity(
"tdme.water." + to_string(idx++))) !=
nullptr) {
1323 for (
auto soundDefinition: prototype->
getSounds()) {
1324 if (soundDefinition->getFileName().length() > 0) {
1325 for (
auto poolIdx = 0; poolIdx < poolSize; poolIdx++) {
1326 string pathName = PrototypeReader::getResourcePathName(
1328 soundDefinition->getFileName()
1330 string fileName = Tools::getFileName(soundDefinition->getFileName());
1331 auto sound =
new Sound(
1332 id +
"." + soundDefinition->getId() + (poolSize > 1?
"." + to_string(poolIdx):
""),
1336 sound->setGain(soundDefinition->getGain());
1337 sound->setPitch(soundDefinition->getPitch());
1338 sound->setLooping(soundDefinition->isLooping());
1339 sound->setFixed(soundDefinition->isFixed());
Interface to audio module.
void addEntity(AudioEntity *entity)
Adds a audio entity.
Sound audio entity implementation.
Color 4 definition class.
Decal entity to be used with engine class.
bool removeEntity(const string &id)
Removes an entity.
Light * getLightAt(int32_t idx)
Returns light at idx (0 <= idx < 8)
UniquePtrSequenceIterator< Light > getLights()
void addEntity(Entity *entity)
Adds an entity by id.
Entity * getEntity(const string &id)
Returns a entity by given id.
void reset()
Removes all entities and caches.
static int32_t getEnvironmentMappingWidth()
static int32_t getEnvironmentMappingHeight()
static const vector< string > getShaderParameterNames(const string &shaderId)
Returns shader parameter names of shader with given id.
Entity hierarchy to be used with engine class.
const ShaderParameter getShaderParameter(const string ¶meterName) const
Returns shader parameter for given parameter name, if the value does not exist, the default will be r...
@ RENDERPASS_POST_POSTPROCESSING
virtual const string & getId()=0
virtual void setRenderPass(RenderPass renderPass)=0
Set render pass.
virtual EntityType getEntityType()=0
virtual void setTransform(const Transform &transform)=0
Set transform.
virtual void setContributesShadows(bool contributesShadows)=0
Enable/disable contributes shadows.
virtual void setReceivesShadows(bool receivesShadows)=0
Enable/disable receives shadows.
virtual void setEnabled(bool enabled)=0
Enable/disable rendering.
Environment mapping entity.
Fog particle system entity to be used with engine class.
LOD object + imposter to be used with engine class.
void setEffectColorAddLOD2(const Color4 &effectColorAddLOD2)
Set effect color add for LOD2 level.
LOD object to be used with engine class.
void setEffectColorAddLOD2(const Color4 &effectColorAddLOD2)
Set effect color add for LOD2 level.
void setEnabled(bool enabled)
Set enabled.
void setSpecular(const Color4 &specular)
Set specular light component.
void setConstantAttenuation(float constantAttenuation)
Set up constant attenuation.
void setSpotDirection(const Vector3 &spotDirection)
Set spot direction.
void setAmbient(const Color4 &ambient)
Set ambient light component.
void setQuadraticAttenuation(float quadraticAttenuation)
Set up quadratic attenuation.
void setSpotCutOff(float spotCutOff)
Set spot cut off.
void setPosition(const Vector4 &position)
Set light position.
void setDiffuse(const Color4 &diffuse)
Set diffuse light component.
void setLinearAttenuation(float linearAttenuation)
Set up linear attenuation.
void setSpotExponent(float spotExponent)
Set up spot exponent.
Object particle system entity to be used with engine class.
Object render group for static objects that might be animated by shaders.
void setShader(const string &id)
Set shader id.
void setReceivesShadows(bool receivesShadows) override
Enable/disable receives shadows.
void setPickable(bool pickable) override
Set this entity pickable.
void setShaderParameter(const string ¶meterName, const ShaderParameter ¶meterValue)
Set shader parameter for given parameter name.
void addObject(Model *model, const Transform &transform)
Adds a instance to this render group.
bool isContributesShadows() override
void setEnabled(bool enabled) override
Enable/disable rendering.
void setContributesShadows(bool contributesShadows) override
Enable/disable contributes shadows.
Object to be used with engine class.
void setReflectionEnvironmentMappingId(const string &reflectionEnvironmentMappingId)
void setAnimationComputationLODEnabled(bool animationComputationLODEnabled)
Set transform computing LOD enabled.
Particle system group, which combines several particle systems into a group, to be used with engine c...
Point particle system entity to be used with engine class.
Scene engine/physics connector.
static STATIC_DLL_IMPEXT int renderGroupsLODLevels
static Entity * createEditorDecalEntity(Prototype *prototype, const string &id, const Transform &transform, int instances=1)
Create editor decal engine entity.
static BodyHierarchy * createSubBody(World *world, Prototype *prototype, const string &id, const Transform &transform, const string &bodyHierarchyId, const string &bodyHierarchyParentId)
Create sub body in body hierarchy.
static constexpr uint16_t BODY_TYPEID_DYNAMIC
static Entity * createEmpty(const string &id, const Transform &transform)
Create engine entity.
static STATIC_DLL_IMPEXT int renderGroupsReduceBy
static constexpr uint16_t BODY_TYPEID_TRIGGER
static STATIC_DLL_IMPEXT Model * emptyModel
static STATIC_DLL_IMPEXT float renderGroupsPartitionHeight
static void enableScene(Engine *engine, Scene *scene, const Vector3 &translation=Vector3(0.0f, 0.0f, 0.0f))
Enable disabled scene in engine.
static STATIC_DLL_IMPEXT int renderGroupsLOD3ReduceBy
static constexpr uint16_t BODY_TYPEID_COLLISION
static STATIC_DLL_IMPEXT int renderGroupsLOD2ReduceBy
static void setNaturalLights(Engine *engine, float t=0.15f)
Set sun/moon lights.
static void disableScene(Engine *engine, Scene *scene)
Disable scene in engine.
static Entity * createEntity(Prototype *prototype, const string &id, const Transform &transform, int instances=1, bool noEntityHierarchy=false)
Create engine entity.
static constexpr uint16_t BODY_TYPEID_STATIC
static void addScene(Engine *engine, Scene *scene, bool addEmpties, bool addTrigger, bool addEnvironmentMapping, bool useEditorDecals, bool pickable, bool enable=true, const Vector3 &translation=Vector3(0.0f, 0.0f, 0.0f), ProgressCallback *progressCallback=nullptr)
Add scene to engine.
static STATIC_DLL_IMPEXT float renderGroupsPartitionDepth
static Entity * createParticleSystem(PrototypeParticleSystem *particleSystem, const string &id, bool enableDynamicShadows=true)
Create particle system.
static void resetEngine(Engine *engine, Scene *scene)
Reset engine regarding given scene.
static STATIC_DLL_IMPEXT float renderGroupsPartitionWidth
static STATIC_DLL_IMPEXT float renderGroupsLOD3MinDistance
static void setLights(Engine *engine, Scene *scene, float t=0.15f, const Vector3 &translation=Vector3(0.0f, 0.0f, 0.0f))
Set lights from scene.
static STATIC_DLL_IMPEXT float renderGroupsLOD2MinDistance
static Body * createBody(World *world, Prototype *prototype, const string &id, const Transform &transform, uint16_t collisionTypeId=BODY_TYPEID_STANDARD, bool hierarchy=false, int index=BOUNDINGVOLUME_INDEX_NONE, PrototypePhysics_BodyType *overrideType=nullptr)
Create body.
static void addSounds(Audio *audio, Prototype *prototype, const string &id, int poolSize=1)
Add scene entity sounds into given audio instance associated with given id.
Representation of a 3D model.
void setEnabled(bool enabled)
Set up if rigid body is enabled.
Dynamic physics world class.
BodyHierarchy * getBodyHierarchy(const string &id)
Returns body hierarchy identified by id.
Body * getBody(const string &id)
Returns body identified by id.
Body * addStaticRigidBody(const string &id, uint16_t collisionTypeId, bool enabled, const Transform &transform, float friction, const vector< BoundingVolume * > &boundingVolumes, bool hierarchy=false)
Add a static rigid body.
Body * addStaticCollisionBody(const string &id, uint16_t collisionTypeId, bool enabled, const Transform &transform, const vector< BoundingVolume * > &boundingVolumes, bool hierarchy=false)
Add a static collision body.
Body * addRigidBody(const string &id, uint16_t collisionTypeId, bool enabled, const Transform &transform, float restitution, float friction, float mass, const Vector3 &inertiaTensor, const vector< BoundingVolume * > &boundingVolumes, bool hierarchy=false)
Add a rigid body.
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Convex mesh physics primitive.
Height map physics primitive.
Oriented bounding box physics primitive.
Sphere physics primitive.
Terrain mesh physics primitive.
Base property model class.
Prototype audio definition.
Prototype bounding volume definition.
BoundingVolume * getBoundingVolume()
float getTextureSpritesFPS()
Texture * getTextureReference()
int getTextureVerticalSprites()
int getTextureHorizontalSprites()
Prototype LOD level definition.
Prototype bounding box particle emitter definition.
Prototype circle particle emitter plane velocity definition.
Prototype circle particle emitter definition.
Prototype particle system emitter type enum.
Prototype point particle system definition.
Prototype object particle system definition.
Prototype point particle emitter definition.
Prototype point particle system definition.
Prototype sphere particle emitter definition.
Prototype particle system type enum.
Prototype particle system definition.
PrototypeParticleSystem_PointParticleSystem * getPointParticleSystem()
PrototypeParticleSystem_SphereParticleEmitter * getSphereParticleEmitter()
PrototypeParticleSystem_CircleParticleEmitterPlaneVelocity * getCircleParticleEmitterPlaneVelocity()
PrototypeParticleSystem_PointParticleEmitter * getPointParticleEmitter()
PrototypeParticleSystem_CircleParticleEmitter * getCircleParticleEmitter()
PrototypeParticleSystem_Emitter * getEmitter()
PrototypeParticleSystem_BoundingBoxParticleEmitter * getBoundingBoxParticleEmitters()
PrototypeParticleSystem_ObjectParticleSystem * getObjectParticleSystem()
PrototypeParticleSystem_FogParticleSystem * getFogParticleSystem()
PrototypeParticleSystem_Type * getType()
Prototype physics body type enum.
Prototype physics body definitions.
float getFriction() const
float getRestitution() const
PrototypePhysics_BodyType * getType() const
const Vector3 & getInertiaTensor() const
Prototype terrain definition.
Prototype * getFoliagePrototype(int prototypeIdx)
Get foliage prototype by given index.
const vector< BoundingVolume * > getBoundingVolumesPrimitives()
Get bounding volumes primitibves to be added to physics engine.
PrototypeLODLevel * getLODLevel3()
PrototypeImposterLOD * getImposterLOD()
PrototypeTerrain * getTerrain()
const string & getFileName()
PrototypeDecal * getDecal()
const string & getShader()
Get shader.
PrototypeBoundingVolume * getBoundingVolume(int idx)
Get bounding volume at given index.
UniquePtrSequenceIterator< PrototypeParticleSystem > getParticleSystems()
bool isContributesShadows()
UniquePtrSequenceIterator< PrototypeAudio > getSounds()
bool isTerrainMesh()
Is terrain mesh.
UniquePtrSequenceIterator< PrototypeBoundingVolume > getBoundingVolumes()
PrototypeLODLevel * getLODLevel2()
Prototype_Type * getType()
int getBoundingVolumeCount()
int64_t getEnvironmentMapTimeRenderUpdateFrequency()
PrototypePhysics * getPhysics()
int getEnvironmentMapRenderPassMask()
const EntityShaderParameters & getShaderParameters()
Get shader parameters.
Prototype * getPrototype()
Transform & getTransform()
Scene prototype library definition.
Prototype * getTerrainPrototype()
Get a terrain prototype.
UniquePtrSequenceIterator< SceneLight > getLights()
UniquePtrSequenceIterator< SceneEntity > getEntities()
SceneLibrary * getLibrary()
Bounding box particle emitter.
Circle particle emitter with velocity that lives in plane only.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Vector3 & add(float scalar)
Adds a scalar.
Vector3 clone() const
Clones this vector3.
bool equals(const Vector3 &vector3, float tolerance=Math::EPSILON) const
Compares this vector3 with given vector3.
Vector4 class representing vector4 mathematical structure and operations with x, y,...
const string & getName() const
Mutable utf8 aware string class.
Helper class to create models from physics primitive bounding volumes.
Particle system entity interface.