59 using std::make_unique;
62 using std::unique_ptr;
116 Engine* Tools::osEngine =
nullptr;
117 Model* Tools::gizmoAll =
nullptr;
118 Model* Tools::gizmoTranslationScale =
nullptr;
119 Model* Tools::gizmoTranslation =
nullptr;
120 Model* Tools::gizmoScale =
nullptr;
121 Model* Tools::gizmoRotations =
nullptr;
122 Model* Tools::defaultOBB =
nullptr;
123 Tools::ToolsShutdown Tools::toolsShutdown;
125 string Tools::formatFloat(
float value)
128 string floatString = to_string(value);
129 return floatString.substr(0, floatString.length() - 3);
150 osEngine = Engine::createOffScreenInstance(128, 128,
false,
true,
false);
170 oseLookFromRotations.
update();
185 auto maxAxisDimension = 0.0f;
187 if (dimension.
getX() > maxAxisDimension) maxAxisDimension = dimension.
getX();
188 if (dimension.
getY() > maxAxisDimension) maxAxisDimension = dimension.
getY();
189 if (dimension.
getZ() > maxAxisDimension) maxAxisDimension = dimension.
getZ();
190 return maxAxisDimension;
195 auto modelId =
"tdme.ground" + to_string(
static_cast<int>(width * 100)) +
"x" + to_string(
static_cast<int>(depth * 100)) +
"@" + to_string(
static_cast<int>(y * 100));
196 auto ground = make_unique<Model>(modelId, modelId, UpVector::Y_UP, RotationOrder::ZYX,
nullptr);
198 auto groundMaterial = make_unique<Material>(
"ground");
199 groundMaterial->setSpecularMaterialProperties(make_unique<SpecularMaterialProperties>().release());
200 groundMaterial->getSpecularMaterialProperties()->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
201 groundMaterial->getSpecularMaterialProperties()->setDiffuseTexture(
"resources/engine/textures",
"groundplate.png");
203 auto groundNode = make_unique<Node>(ground.get(),
nullptr,
"ground",
"ground");
204 vector<Vector3> groundVertices;
205 groundVertices.emplace_back(-width/2, y, -depth/2);
206 groundVertices.emplace_back(-width/2, y, +depth/2);
207 groundVertices.emplace_back(+width/2, y, +depth/2);
208 groundVertices.emplace_back(+width/2, y, -depth/2);
209 vector<Vector3> groundNormals;
210 groundNormals.emplace_back(0.0f, 1.0f, 0.0f);
211 vector<Vector2> groundTextureCoordinates;
212 groundTextureCoordinates.emplace_back(0.0f, 0.0f);
213 groundTextureCoordinates.emplace_back(0.0f, depth);
214 groundTextureCoordinates.emplace_back(width, depth);
215 groundTextureCoordinates.emplace_back(width, 0.0f);
216 vector<Face> groundFacesGround;
217 groundFacesGround.emplace_back(groundNode.get(), 0, 1, 2, 0, 0, 0, 0, 1, 2);
218 groundFacesGround.emplace_back(groundNode.get(), 2, 3, 0, 0, 0, 0, 2, 3, 0);
219 FacesEntity nodeFacesEntityGround(groundNode.get(),
"ground.facesentity");
220 nodeFacesEntityGround.
setMaterial(groundMaterial.get());
221 vector<FacesEntity> nodeFacesEntities;
222 nodeFacesEntityGround.
setFaces(groundFacesGround);
223 nodeFacesEntities.push_back(nodeFacesEntityGround);
224 groundNode->setVertices(groundVertices);
225 groundNode->setNormals(groundNormals);
226 groundNode->setTextureCoordinates(groundTextureCoordinates);
227 groundNode->setFacesEntities(nodeFacesEntities);
228 ground->getNodes()[
"ground"] = groundNode.get();
229 ground->getSubNodes()[
"ground"] = groundNode.get();
230 groundNode.release();
232 ground->getMaterials()[
"ground"] = groundMaterial.get();
233 groundMaterial.release();
235 ModelTools::prepareForIndexedRendering(ground.get());
237 return ground.release();
243 auto groundPlate = make_unique<Model>(
"tdme.grid",
"tdme.grid", UpVector::Y_UP, RotationOrder::XYZ, make_unique<BoundingBox>(
Vector3(0.0f, -0.01f, 0.0f),
Vector3(10000.0f, +0.01f, 10000.0f)).release());
245 auto groundPlateMaterial = make_unique<Material>(
"ground");
246 groundPlateMaterial->setSpecularMaterialProperties(make_unique<SpecularMaterialProperties>().release());
247 groundPlateMaterial->getSpecularMaterialProperties()->setDiffuseColor(
249 groundPlateMaterial->getSpecularMaterialProperties()->getDiffuseColor().getRed(),
250 groundPlateMaterial->getSpecularMaterialProperties()->getDiffuseColor().getGreen(),
251 groundPlateMaterial->getSpecularMaterialProperties()->getDiffuseColor().getBlue(),
255 groundPlateMaterial->getSpecularMaterialProperties()->setDiffuseTexture(
"resources/engine/textures",
"groundplate.png");
256 groundPlateMaterial->getSpecularMaterialProperties()->setSpecularColor(
Color4(0.0f, 0.0f, 0.0f, 1.0f));
258 auto groundNode = make_unique<Node>(groundPlate.get(),
nullptr,
"grid",
"grid");
259 vector<Vector3> groundVertices;
260 groundVertices.emplace_back(0.0f, 0.0f, 0.0f);
261 groundVertices.emplace_back(0.0f, 0.0f, 10000.0f);
262 groundVertices.emplace_back(10000.0f, 0.0f, 10000.0f);
263 groundVertices.emplace_back(10000.0f, 0.0f, 0.0f);
264 vector<Vector3> groundNormals;
265 groundNormals.emplace_back(0.0f, 1.0f, 0.0f);
266 vector<Vector2> groundTextureCoordinates;
267 groundTextureCoordinates.emplace_back(0.0f, 0.0f);
268 groundTextureCoordinates.emplace_back(0.0f, 10000.0f);
269 groundTextureCoordinates.emplace_back(10000.0f, 10000.0f);
270 groundTextureCoordinates.emplace_back(10000.0f, 0.0f);
271 vector<Face> groundFacesGround;
272 groundFacesGround.emplace_back(groundNode.get(), 0, 1, 2, 0, 0, 0, 0, 1, 2);
273 groundFacesGround.emplace_back(groundNode.get(), 2, 3, 0, 0, 0, 0, 2, 3, 0);
274 FacesEntity nodeFacesEntityGround(groundNode.get(),
"tdme.sceneeditor.grid.facesentity");
275 nodeFacesEntityGround.
setMaterial(groundPlateMaterial.get());
276 nodeFacesEntityGround.
setFaces(groundFacesGround);
277 vector<FacesEntity> nodeFacesEntities;
278 nodeFacesEntities.push_back(nodeFacesEntityGround);
279 groundNode->setVertices(groundVertices);
280 groundNode->setNormals(groundNormals);
281 groundNode->setTextureCoordinates(groundTextureCoordinates);
282 groundNode->setFacesEntities(nodeFacesEntities);
283 groundPlate->getNodes()[groundNode->getId()] = groundNode.get();
284 groundPlate->getSubNodes()[groundNode->getId()] = groundNode.get();
285 groundNode.release();
287 groundPlate->getMaterials()[
"grid"] = groundPlateMaterial.get();
288 groundPlateMaterial.release();
290 ModelTools::prepareForIndexedRendering(groundPlate.get());
292 return groundPlate.release();
297 if (prototype ==
nullptr)
return;
300 auto entityBoundingBoxFallback = make_unique<BoundingBox>(
Vector3(-2.5f, 0.0f, -2.5f),
Vector3(2.5f, 2.0f, 2.5f));
302 Entity* modelEntity =
nullptr;
303 objectScale.
set(1.0f, 1.0f, 1.0f);
304 Color4 colorMul(1.0f, 1.0f, 1.0f, 1.0f);
305 Color4 colorAdd(0.0f, 0.0f, 0.0f, 0.0f);
308 auto entityBoundingVolumesHierarchy =
new EntityHierarchy(
"tdme.prototype.bvs");
312 if (prototypeBoundingVolume->getModel() !=
nullptr) {
313 auto bvObject =
new Object(
"tdme.prototype.bv." + to_string(i), prototypeBoundingVolume->getModel());
314 bvObject->setEnabled(
false);
315 entityBoundingVolumesHierarchy->addEntity(bvObject);
320 entityBoundingVolumesHierarchy->update();
321 engine->
addEntity(entityBoundingVolumesHierarchy);
324 if (prototype->
getType() == Prototype_Type::TRIGGER ||
325 prototype->
getType() == Prototype_Type::ENVIRONMENTMAPPING ||
326 prototype->
getType() == Prototype_Type::DECAL) {
327 entityBoundingBox = entityBoundingVolumesHierarchy->getBoundingBox();
329 if (prototype->
getType() == Prototype_Type::PARTICLESYSTEM) {
330 modelEntity = SceneConnector::createEntity(prototype,
"model",
Transform());
331 if (modelEntity !=
nullptr) engine->
addEntity(modelEntity);
333 if (prototype->
getModel() !=
nullptr) {
335 Model* model =
nullptr;
343 if (lodLevelEntity !=
nullptr) {
344 model = lodLevelEntity->getModel();
345 colorMul.
set(lodLevelEntity->getColorMul());
346 colorAdd.
set(lodLevelEntity->getColorAdd());
353 if (lodLevelEntity !=
nullptr) {
354 model = lodLevelEntity->getModel();
355 colorMul.
set(lodLevelEntity->getColorMul());
356 colorAdd.
set(lodLevelEntity->getColorAdd());
363 if (imposterLOD !=
nullptr) {
366 imposterLOD->getModels()
375 for (
const auto& parameterName: Engine::getShaderParameterNames(prototype->
getShader())) {
377 object->setShaderParameter(parameterName, parameterValue);
384 if (model !=
nullptr) {
385 modelEntity =
new Object(
"model", model);
390 auto object =
dynamic_cast<Object*
>(modelEntity);
392 for (
const auto& parameterName: Engine::getShaderParameterNames(prototype->
getShader())) {
394 object->setShaderParameter(parameterName, parameterValue);
401 auto entityBoundingBoxToUse = entityBoundingBox !=
nullptr?entityBoundingBox:entityBoundingBoxFallback.get();
405 if (maxAxisDimension < Math::EPSILON) maxAxisDimension = 1.0f;
407 if (modelEntity !=
nullptr) {
419 auto groundObject =
new Object(
"ground", ground);
420 groundObject->setEnabled(
false);
421 groundObject->setScale(objectScale);
422 groundObject->setShader(
"solid");
423 groundObject->update();
431 if (resetup ==
false) {
436 light0->setDiffuse(
Color4(0.3f, 0.3f, 0.3f, 1.0f));
437 light0->setSpecular(
Color4(1.0f, 1.0f, 1.0f, 1.0f));
441 20.0f * maxAxisDimension,
442 20.0f * maxAxisDimension,
446 light0->setSpotDirection(
Vector3(0.0f, 0.0f, 0.0f).
sub(
Vector3(light0->getPosition().getX(), light0->getPosition().getY(), light0->getPosition().getZ())).normalize());
447 light0->setConstantAttenuation(0.5f);
448 light0->setLinearAttenuation(0.0f);
449 light0->setQuadraticAttenuation(0.0f);
450 light0->setSpotExponent(0.0f);
451 light0->setSpotCutOff(180.0f);
452 light0->setEnabled(
true);
457 lookAt.
set(entityBoundingBoxToUse->getCenter().clone().scale(objectScale));
458 Vector3 forwardVector(0.0f, 0.0f, 1.0f);
462 if (cameraRotationInputHandler !=
nullptr) {
464 cameraRotationInputHandler->
setScale(maxAxisDimension * scale);
466 auto forwardVectorTransformed = _lookFromRotations.
getTransformMatrix().
multiply(forwardVector).
scale(cameraRotationInputHandler !=
nullptr?cameraRotationInputHandler->
getScale():maxAxisDimension * scale);
468 auto lookFrom = lookAt.
clone().
add(forwardVectorTransformed);
469 cam->setLookFrom(lookFrom);
470 cam->setLookAt(lookAt);
471 cam->setUpVector(upVector);
473 if (cameraRotationInputHandler !=
nullptr) {
481 auto newFileName = StringTools::replace(fileName,
'\\',
'/');
482 auto cutFileNameIdx = string::npos;
483 if (cutFileNameIdx == string::npos) {
484 cutFileNameIdx = fileName.rfind(
"/resources/");
485 if (cutFileNameIdx != string::npos) {
486 newFileName = StringTools::substring(fileName, cutFileNameIdx + 1);
489 if (cutFileNameIdx == string::npos) {
490 cutFileNameIdx = fileName.rfind(
"resources/");
491 if (cutFileNameIdx != string::npos) {
492 newFileName = StringTools::substring(fileName, cutFileNameIdx);
500 auto newFileName = StringTools::replace(fileName,
'\\',
'/');
501 auto applicationRootPathNameIdx = string::npos;
502 if (applicationRootPathNameIdx == string::npos) {
503 applicationRootPathNameIdx = fileName.rfind(
"/resources/");
504 if (applicationRootPathNameIdx != string::npos)
return StringTools::substring(fileName, 0, applicationRootPathNameIdx);
506 if (StringTools::startsWith(fileName,
"resources/") ==
true) {
509 if (StringTools::endsWith(fileName,
"/resources") ==
true) {
510 return StringTools::substring(fileName, 0, fileName.size() -
string(
"/resources").size());
517 auto newFileName = StringTools::replace(fileName,
'\\',
'/');
518 auto applicationSubPathNameIdx = -1;
519 if (applicationSubPathNameIdx == -1) {
520 applicationSubPathNameIdx = fileName.rfind(
"/resources/");
521 if (applicationSubPathNameIdx != -1) {
522 applicationSubPathNameIdx+= string(
"/resources/").size();
523 auto applicationSubPathName = StringTools::substring(fileName, applicationSubPathNameIdx, fileName.find(
"/", applicationSubPathNameIdx));
524 if (applicationSubPathName ==
"engine")
return applicationSubPathName;
else
525 if (applicationSubPathName ==
"project")
return applicationSubPathName;
else
526 if (applicationSubPathName ==
"installer")
return applicationSubPathName;
else
530 if (applicationSubPathNameIdx == -1) {
531 applicationSubPathNameIdx = fileName.rfind(
"resources/");
532 if (applicationSubPathNameIdx != -1) {
533 applicationSubPathNameIdx+= string(
"resources/").size();
534 auto applicationSubPathName = StringTools::substring(fileName, applicationSubPathNameIdx, fileName.find(
"/", applicationSubPathNameIdx));
535 if (applicationSubPathName ==
"engine")
return applicationSubPathName;
else
536 if (applicationSubPathName ==
"project")
return applicationSubPathName;
else
537 if (applicationSubPathName ==
"installer")
return applicationSubPathName;
else
546 return FileSystem::getInstance()->getPathName(fileName);
551 return FileSystem::getInstance()->getFileName(fileName);
556 auto idx = fileName.rfind(
'.');
557 if (idx == string::npos) {
560 return fileName.substr(0, idx);
566 if (StringTools::endsWith(StringTools::toLowerCase(fileName),
"." + extension) ==
true) {
575 auto idx = fileName.rfind(
'.');
576 if (idx == string::npos) {
579 return fileName.substr(idx + 1);
588 settings.
load(
"settings",
"settings.properties");
590 Console::println(
"Tools::loadSettings(): An error occurred: " +
string(exception.what()));
594 if (settings.
get(
"4k",
"false") ==
"true") {
599 application->
setWindowWidth(Integer::parse(settings.
get(
"window_width",
"1024")));
608 gizmoAll = ModelReader::read(
"resources/engine/models",
"gizmo_all.tm");
609 ModelTools::prepareForShader(
gizmoAll);
610 ModelTools::changeFrontFace(
gizmoAll);
628 gizmoTranslation = ModelReader::read(
"resources/engine/models",
"gizmo_translate.tm");
638 gizmoScale = ModelReader::read(
"resources/engine/models",
"gizmo_scale.tm");
648 gizmoRotations = ModelReader::read(
"resources/engine/models",
"gizmo_rotate.tm");
660 OrientedBoundingBox::AABB_AXIS_X,
661 OrientedBoundingBox::AABB_AXIS_Y,
662 OrientedBoundingBox::AABB_AXIS_Z,
665 defaultOBB = Primitives::createModel(&obb,
"tdme.obb.default");
676 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
677 for (
const auto& extension: extensions) {
678 if (StringTools::endsWith(fileNameLowerCase,
"." + extension) ==
true)
return true;
Application base class, please make sure to allocate application on heap to have correct application ...
void setWindowXPosition(int windowXPosition)
Set window X position when initializing.
void setWindowYPosition(int windowYPosition)
Set window Y position when initializing.
void setWindowWidth(int windowWidth)
Set window width.
void setFullScreen(bool fullScreen)
Set full screen mode.
void setWindowHeight(int windowHeight)
Set window height.
const Vector3 & getLookAt() const
Color 4 definition class.
void set(float r, float g, float b, float a)
Sets this color by its components.
Light * getLightAt(int32_t idx)
Returns light at idx (0 <= idx < 8)
void display()
Renders the scene.
bool makeScreenshot(const string &pathName, const string &fileName, bool removeAlphaChannel=true)
Creates a PNG file from current screen( This does not seem to work with GLES2 and offscreen engines.
void setPartition(Partition *partition)
Set partition.
void addEntity(Entity *entity)
Adds an entity by id.
void dispose()
Shutdown the engine.
Entity * getEntity(const string &id)
Returns a entity by given id.
void reset()
Removes all entities and caches.
void setSceneColor(const Color4 &sceneColor)
Set scene color.
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...
virtual void setScale(const Vector3 &scale)=0
Set scale.
virtual void setEffectColorMul(const Color4 &effectColorMul)=0
Set effect color that will be multiplied with fragment color.
virtual void update()=0
Update transform.
virtual void setContributesShadows(bool contributesShadows)=0
Enable/disable contributes shadows.
virtual void setPickable(bool pickable)=0
Set this entity pickable.
virtual void setReceivesShadows(bool receivesShadows)=0
Enable/disable receives shadows.
virtual void setEffectColorAdd(const Color4 &effectColorAdd)=0
Set effect color that will be added to fragment color.
Imposter object to be used with engine class.
void setShader(const string &id)
Set shader id.
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.
const Vector4 & getPosition() const
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 to be used with engine class.
void setShader(const string &id)
Set shader.
const Quaternion & getQuaternion() const
Scene engine/physics connector.
Bogus/Simple partition implementation.
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.
void setShaderModel(ShaderModel *shaderModel)
Set preferred shader model.
BoundingBox * getBoundingBox()
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.
Oriented bounding box physics primitive.
Prototype bounding volume definition.
Prototype LOD level definition.
PrototypeLODLevel * getLODLevel3()
PrototypeImposterLOD * getImposterLOD()
const string & getShader()
Get shader.
UniquePtrSequenceIterator< PrototypeBoundingVolume > getBoundingVolumes()
PrototypeLODLevel * getLODLevel2()
Prototype_Type * getType()
const EntityShaderParameters & getShaderParameters()
Get shader parameters.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Quaternion class representing quaternion mathematical structure and operations with x,...
Quaternion & add(const Quaternion &quaternion)
Adds quaternion.
Quaternion & multiply(const Quaternion quaternion)
Multiplies this quaternion with given quaternion.
Quaternion clone() const
Clones this quaternion.
Quaternion & normalize()
Normalizes this quaternion.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
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 & scale(float scalar)
Scales by scalar.
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Vector4 class representing vector4 mathematical structure and operations with x, y,...
File system singleton class.
Helper class to create models from physics primitive bounding volumes.
Properties class, which helps out with storeing or loading key value pairs from/to property files.
const string & get(const string &key, const string &defaultValue) const
Get property value by key.
void load(const string &pathName, const string &fileName, FileSystemInterface *fileSystem=nullptr)
Load property file.
std::exception Exception
Exception base class.