// HARFANG(R) Copyright (C) 2021 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include "foundation/file.h" #include "foundation/format.h" #include "foundation/log.h" #include "foundation/math.h" #include "engine/assets.h" #include "engine/scene.h" namespace hg { // void Scene::ReserveTransforms(const size_t count) { transforms.reserve(transforms.size() + count); } void Scene::ReserveCameras(const size_t count) { cameras.reserve(cameras.size() + count); } void Scene::ReserveObjects(const size_t count) { objects.reserve(objects.size() + count); } void Scene::ReserveLights(const size_t count) { lights.reserve(lights.size() + count); } void Scene::ReserveScripts(const size_t count) { scripts.reserve(scripts.size() + count); } // static bool IsChildOf(Scene &scene, NodeRef node, ComponentRef transform) { if (scene.GetNode(node).GetTransform().ref == transform) return true; while (node != InvalidNodeRef) { const auto parent = scene.GetNode(node).GetTransform().GetParent(); if (scene.GetNode(parent).GetTransform().ref == transform) return true; node = parent; } return false; } // Transform Scene::CreateTransform() { const auto ref = transforms.add_ref({}); if (ref.idx >= transform_worlds.size()) transform_worlds.resize(ref.idx + 64, Mat4::Identity); // so that GetWorld works straight away return {scene_ref, ref}; } void Scene::DestroyTransform(ComponentRef ref) { transforms.remove_ref(ref); } Vec3 Scene::GetTransformPos(ComponentRef ref) const { if (const auto *c = GetComponent_(transforms, ref)) return c->TRS.pos; warn("Invalid transform component"); return {}; } void Scene::SetTransformPos(ComponentRef ref, const Vec3 &v) { if (auto *c = GetComponent_(transforms, ref)) c->TRS.pos = v; else warn("Invalid transform component"); } bool Transform::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidTransformRef(ref) : false; } Vec3 Transform::GetPos() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformPos(ref); warn("Orphaned transform component"); return {}; } void Transform::SetPos(const Vec3 &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformPos(ref, v); else warn("Orphaned transform component"); } void Transform::GetPosRot(Vec3 &p, Vec3 &r) { p = GetPos(); r = GetRot(); } void Transform::SetPosRot(const Vec3 &p, const Vec3 &r) { SetPos(p); SetRot(r); } Vec3 Scene::GetTransformRot(ComponentRef ref) const { if (const auto *c = GetComponent_(transforms, ref)) return c->TRS.rot; warn("Invalid transform component"); return {}; } void Scene::SetTransformRot(ComponentRef ref, const Vec3 &v) { if (auto *c = GetComponent_(transforms, ref)) c->TRS.rot = v; else warn("Invalid transform component"); } Vec3 Transform::GetRot() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformRot(ref); warn("Orphaned transform component"); return {}; } void Transform::SetRot(const Vec3 &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformRot(ref, v); else warn("Orphaned transform component"); } Vec3 Scene::GetTransformScale(ComponentRef ref) const { if (const auto *c = GetComponent_(transforms, ref)) return c->TRS.scl; warn("Invalid transform component"); return {}; } void Scene::SetTransformScale(ComponentRef ref, const Vec3 &v) { if (auto *c = GetComponent_(transforms, ref)) c->TRS.scl = v; else warn("Invalid transform component"); } Vec3 Transform::GetScale() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformScale(ref); warn("Orphaned transform component"); return {}; } void Transform::SetScale(const Vec3 &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformScale(ref, v); else warn("Orphaned transform component"); } TransformTRS Scene::GetTransformTRS(ComponentRef ref) const { if (const auto *c = GetComponent_(transforms, ref)) return c->TRS; warn("Invalid transform component"); return {}; } void Scene::SetTransformTRS(ComponentRef ref, const TransformTRS &v) { if (auto *c = GetComponent_(transforms, ref)) c->TRS = v; else warn("Invalid transform component"); } TransformTRS Transform::GetTRS() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformTRS(ref); warn("Orphaned transform component"); return {}; } void Transform::SetTRS(const TransformTRS &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformTRS(ref, v); else warn("Orphaned transform component"); } NodeRef Scene::GetTransformParent(ComponentRef ref) const { if (const auto *c = GetComponent_(transforms, ref)) return c->parent; warn("Invalid transform component"); return {}; } void Scene::SetTransformParent(ComponentRef ref, const NodeRef &v) { if (auto *c = GetComponent_(transforms, ref)) { if (!hg::IsChildOf(*scene_ref->scene, v, ref)) c->parent = v; else warn("Cyclical reference detected"); } else { warn("Invalid transform component"); } } NodeRef Transform::GetParent() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformParent(ref); warn("Orphaned transform component"); return {}; } void Transform::SetParent(NodeRef v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformParent(ref, v); else warn("Orphaned transform component"); } Node Transform::GetParentNode() const { if (scene_ref && scene_ref->scene) return {scene_ref, scene_ref->scene->GetTransformParent(ref)}; warn("Orphaned transform component"); return {}; } void Transform::SetParentNode(const Node &n) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformParent(ref, n.ref); else warn("Orphaned transform component"); } Transform Scene::CreateTransform(const Vec3 &pos, const Vec3 &rot, const Vec3 &scl, NodeRef parent) { return {scene_ref, transforms.add_ref({{pos, rot, scl}, parent})}; } Transform Scene::CreateTransform(const Mat4 &mtx, NodeRef parent) { Vec3 pos, rot, scl; Decompose(mtx, &pos, &rot, &scl); return CreateTransform(pos, rot, scl); } // void Scene::SetTransformLocalMatrix(ComponentRef ref, const Mat4 &local) { if (auto trs = GetComponent_(transforms, ref)) { Decompose(local, &trs->TRS.pos, &trs->TRS.rot, &trs->TRS.scl); const auto parent_trs_ref = GetNodeComponentRef_(trs->parent); const auto world = IsValidTransformRef(parent_trs_ref) ? transform_worlds[parent_trs_ref.idx] * local : local; transform_worlds[ref.idx] = world; } else { warn("Invalid transform component"); } } Mat4 Scene::GetTransformWorldMatrix(const uint32_t transform_idx) const { if (transform_idx < transform_worlds.size()) return transform_worlds[transform_idx]; warn("Invalid transform index"); return Mat4::Identity; } Mat4 Scene::GetPreviousTransformWorldMatrix(const uint32_t transform_idx) const { if (transform_idx < previous_transform_worlds.size()) return previous_transform_worlds[transform_idx]; warn("Invalid transform index"); return transform_worlds[transform_idx]; } void Scene::SetTransformWorldMatrix(ComponentRef ref, const Mat4 &world) { if (auto trs = GetComponent_(transforms, ref)) { if (ref.idx < transform_worlds.size()) { transform_worlds[ref.idx] = world; const auto parent_trs_ref = GetNodeComponentRef_(trs->parent); const auto local = IsValidTransformRef(parent_trs_ref) ? InverseFast(transform_worlds[parent_trs_ref.idx]) * world : world; Decompose(local, &trs->TRS.pos, &trs->TRS.rot, &trs->TRS.scl); } else { warn("Invalid transform index"); } } else { warn("Invalid transform component"); } } // Mat4 Transform::GetWorld() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetTransformWorldMatrix(ref.idx); warn("Orphaned transform component"); return Mat4::Identity; } void Transform::SetWorld(const Mat4 &world) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformWorldMatrix(ref, world); else warn("Orphaned transform component"); } void Transform::SetLocal(const Mat4 &local) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetTransformLocalMatrix(ref, local); else warn("Orphaned transform component"); } // Camera Scene::CreateCamera() { return {scene_ref, cameras.add_ref({})}; } void Scene::DestroyCamera(ComponentRef ref) { cameras.remove_ref(ref); } float Scene::GetCameraZNear(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->zrange.znear; warn("Invalid camera component"); return {}; } void Scene::SetCameraZNear(ComponentRef ref, float v) { if (auto *c = GetComponent_(cameras, ref)) c->zrange.znear = Clamp(v, 0.0001f, c->zrange.zfar - 0.0001f); else warn("Invalid camera component"); } void Scene::SetCameraCenterOffset(ComponentRef ref, const Vec2 & v) { if (auto *c = GetComponent_(cameras, ref)) c->center_offset = v; else warn("Invalid camera component"); } Vec2 Scene::GetCameraCenterOffset(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->center_offset; warn("Invalid camera component"); return {}; } bool Camera::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidCameraRef(ref) : false; } float Camera::GetZNear() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraZNear(ref); warn("Orphaned camera component"); return {}; } void Camera::SetZNear(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraZNear(ref, v); else warn("Orphaned camera component"); } float Scene::GetCameraZFar(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->zrange.zfar; warn("Invalid camera component"); return {}; } void Scene::SetCameraZFar(ComponentRef ref, float v) { if (auto *c = GetComponent_(cameras, ref)) c->zrange.zfar = Max(v, c->zrange.znear + 0.0001f); else warn("Invalid camera component"); } float Camera::GetZFar() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraZFar(ref); warn("Orphaned camera component"); return {}; } void Camera::SetZFar(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraZFar(ref, v); else warn("Orphaned camera component"); } CameraZRange Scene::GetCameraZRange(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->zrange; warn("Invalid camera component"); return {}; } void Scene::SetCameraZRange(ComponentRef ref, CameraZRange v) { if (auto *c = GetComponent_(cameras, ref)) { const auto znear = Clamp(v.znear, 0.0001f, v.zfar - 0.0001f), zfar = Max(v.zfar, znear); c->zrange = {znear, zfar}; } else { warn("Invalid camera component"); } } CameraZRange Camera::GetZRange() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraZRange(ref); warn("Orphaned camera component"); return {}; } void Camera::SetZRange(CameraZRange v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraZRange(ref, v); else warn("Orphaned camera component"); } float Scene::GetCameraFov(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->fov; warn("Invalid camera component"); return {}; } void Scene::SetCameraFov(ComponentRef ref, float v) { if (auto *c = GetComponent_(cameras, ref)) c->fov = Clamp(v, Deg(0.0001f), Deg(180.f - 0.0001f)); else warn("Invalid camera component"); } float Camera::GetFov() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraFov(ref); warn("Orphaned camera component"); return {}; } void Camera::SetFov(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraFov(ref, v); else warn("Orphaned camera component"); } bool Scene::GetCameraIsOrthographic(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->ortho; warn("Invalid camera component"); return {}; } void Scene::SetCameraIsOrthographic(ComponentRef ref, const bool &v) { if (auto *c = GetComponent_(cameras, ref)) c->ortho = v; } bool Camera::GetIsOrthographic() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraIsOrthographic(ref); warn("Orphaned camera component"); return {}; } void Camera::SetIsOrthographic(bool v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraIsOrthographic(ref, v); else warn("Orphaned camera component"); } float Scene::GetCameraSize(ComponentRef ref) const { if (const auto *c = GetComponent_(cameras, ref)) return c->size; warn("Invalid camera component"); return {}; } void Scene::SetCameraSize(ComponentRef ref, float v) { if (auto *c = GetComponent_(cameras, ref)) c->size = v != 0.f ? v : 0.0001f; else warn("Invalid camera component"); } float Camera::GetSize() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraSize(ref); warn("Orphaned camera component"); return {}; } void Camera::SetSize(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraSize(ref, v); else warn("Orphaned camera component"); } void Camera::SetCenterOffset(const Vec2 & v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCameraCenterOffset(ref, v); else warn("Orphaned camera component"); } Vec2 Camera::GetCenterOffset() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCameraCenterOffset(ref); warn("Orphaned camera component"); return {}; } Camera Scene::CreateCamera(const float znear, const float zfar, const float fov) { return {scene_ref, cameras.add_ref({{znear, zfar}, fov, false})}; } Camera Scene::CreateOrthographicCamera(const float znear, const float zfar, const float size) { return {scene_ref, cameras.add_ref({{znear, zfar}, Deg(45.f), true, size})}; } // Object Scene::CreateObject() { return {scene_ref, objects.add_ref({})}; } void Scene::DestroyObject(ComponentRef ref) { objects.remove_ref(ref); } ModelRef Scene::GetObjectModel(ComponentRef ref) const { if (const auto *c = GetComponent_(objects, ref)) return c->model; warn("Invalid object component"); return {}; } void Scene::SetObjectModel(ComponentRef ref, const ModelRef &v) { if (auto *c = GetComponent_(objects, ref)) { c->model = v; } else { warn("Invalid object component"); } } bool Object::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidObjectRef(ref) : false; } ModelRef Object::GetModelRef() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectModel(ref); warn("Orphaned object component"); return {}; } void Object::SetModelRef(ModelRef v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectModel(ref, v); else warn("Orphaned object component"); }; void Object::ClearModelRef() { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectModel(ref, InvalidModelRef); else warn("Orphaned object component"); }; // static Material null_bound_material; Material &Scene::GetObjectMaterial(ComponentRef ref, size_t slot_idx) { if (auto *c = GetComponent_(objects, ref)) return slot_idx < c->materials.size() ? c->materials[slot_idx] : null_bound_material; warn("Invalid object component"); return null_bound_material; } void Scene::SetObjectMaterial(ComponentRef ref, size_t slot_idx, Material material) { if (auto *c = GetComponent_(objects, ref)) { if (c->materials.size() <= slot_idx) c->materials.resize(slot_idx + 1); c->materials[slot_idx] = std::move(material); } else { warn("Invalid object component"); } } Material *Scene::GetObjectMaterial(ComponentRef ref, const std::string &name) { if (auto *c = GetComponent_(objects, ref)) { size_t i = 0; for (; i < c->material_infos.size(); ++i) if (c->material_infos[i].name == name) break; if (i == c->material_infos.size() || i >= c->materials.size()) { warn(format("Object has no material named '%1'").arg(name)); return nullptr; } return &c->materials[i]; } warn("Invalid object component"); return nullptr; } Material &Object::GetMaterial(const size_t slot_idx) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectMaterial(ref, slot_idx); warn("Orphaned object component"); return null_bound_material; } void Object::SetMaterial(const size_t slot_idx, Material material) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectMaterial(ref, slot_idx, material); else warn("Orphaned object component"); } std::string Scene::GetObjectMaterialName(ComponentRef ref, size_t slot_idx) const { if (auto *c = GetComponent_(objects, ref)) { if (slot_idx < c->material_infos.size()) return c->material_infos[slot_idx].name; warn("Invalid object material slot index"); } else { warn("Invalid object component"); } return {}; } void Scene::SetObjectMaterialName(ComponentRef ref, size_t slot_idx, const std::string &name) { if (auto *c = GetComponent_(objects, ref)) { c->material_infos.resize(slot_idx + 1); c->material_infos[slot_idx].name = name; } else { warn("Invalid object component"); } } // size_t Scene::GetObjectBoneCount(ComponentRef ref) const { if (auto *c = GetComponent_(objects, ref)) return c->bones.size(); warn("Invalid object component"); return 0; } size_t Object::GetBoneCount() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectBoneCount(ref); warn("Orphaned object component"); return 0; } void Scene::SetObjectBoneCount(ComponentRef ref, size_t count) { if (auto *c = GetComponent_(objects, ref)) c->bones.resize(count); else warn("Invalid object component"); } void Object::SetBoneCount(size_t count) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectBoneCount(ref, count); else warn("Orphaned object component"); } bool Scene::SetObjectBone(ComponentRef ref, size_t idx, NodeRef bone_node) { if (auto *c = GetComponent_(objects, ref)) { if (idx < c->bones.size()) { c->bones[idx] = bone_node; return true; } else { warn("Invalid bone index"); } } else { warn("Invalid object component"); } return false; } bool Object::SetBone(size_t idx, NodeRef bone) { if (scene_ref && scene_ref->scene) return scene_ref->scene->SetObjectBone(ref, idx, bone); warn("Orphaned object component"); return false; } NodeRef Scene::GetObjectBone(ComponentRef ref, size_t idx) const { if (auto *c = GetComponent_(objects, ref)) { if (idx < c->bones.size()) return c->bones[idx]; else warn("Invalid bone index"); } return InvalidNodeRef; } NodeRef Object::GetBone(size_t idx) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectBone(ref, idx); warn("Orphaned object component"); return InvalidNodeRef; } Node Object::GetBoneNode(size_t idx) const { return {scene_ref, GetBone(idx)}; } bool Object::SetBoneNode(size_t idx, const Node &node) { return SetBone(idx, node.ref); } // std::string Object::GetMaterialName(size_t slot_idx) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectMaterialName(ref, slot_idx); warn("Orphaned object component"); return {}; } void Object::SetMaterialName(size_t slot_idx, const std::string &name) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectMaterialName(ref, slot_idx, name); else warn("Orphaned object component"); } size_t Scene::GetObjectMaterialCount(ComponentRef ref) const { if (const auto *c = GetComponent_(objects, ref)) return c->materials.size(); warn("Invalid object component"); return 0; } void Scene::SetObjectMaterialCount(ComponentRef ref, size_t v) { if (auto *c = GetComponent_(objects, ref)) { c->material_infos.resize(v); c->materials.resize(v); } else { warn("Invalid object component"); } } size_t Object::GetMaterialCount() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectMaterialCount(ref); warn("Orphaned object component"); return 0; } void Object::SetMaterialCount(size_t v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetObjectMaterialCount(ref, v); else warn("Orphaned object component"); } Material *Object::GetMaterial(const std::string &name) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectMaterial(ref, name); warn("Orphaned object component"); return nullptr; } bool Scene::GetObjectMinMax(ComponentRef ref, const PipelineResources &resources, MinMax &minmax) const { const auto *c = GetComponent_(objects, ref); if (!c) { warn("Invalid object component"); return false; } if (!resources.models.IsValidRef(c->model)) return false; const auto &mdl = resources.models.Get_unsafe_(c->model.ref.idx); if (mdl.bounds.empty()) return false; minmax = mdl.bounds[0]; for (size_t i = 1; i < mdl.bounds.size(); ++i) minmax = Union(minmax, mdl.bounds[i]); return true; } bool Object::GetMinMax(const PipelineResources &resources, MinMax &minmax) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetObjectMinMax(ref, resources, minmax); warn("Orphaned object component"); return false; } Object Scene::CreateObject(const ModelRef &model, std::vector materials) { return {scene_ref, objects.add_ref({model, std::move(materials)})}; } // Light Scene::CreateLight() { return {scene_ref, lights.add_ref({})}; } void Scene::DestroyLight(ComponentRef ref) { lights.remove_ref(ref); } LightType Scene::GetLightType(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->type; warn("Invalid light component"); return {}; } void Scene::SetLightType(ComponentRef ref, LightType v) { if (auto *c = GetComponent_(lights, ref)) c->type = v; else warn("Invalid light component"); } LightShadowType Scene::GetLightShadowType(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->shadow_type; warn("Invalid light component"); return {}; } void Scene::SetLightShadowType(ComponentRef ref, LightShadowType v) { if (auto *c = GetComponent_(lights, ref)) c->shadow_type = v; else warn("Invalid light component"); } bool Light::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidLightRef(ref) : false; } LightType Light::GetType() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightType(ref); warn("Orphaned light component"); return {}; } void Light::SetType(LightType v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightType(ref, v); else warn("Orphaned light component"); } LightShadowType Light::GetShadowType() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightShadowType(ref); warn("Orphaned light component"); return {}; } void Light::SetShadowType(LightShadowType v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightShadowType(ref, v); else warn("Orphaned light component"); } Color Scene::GetLightDiffuseColor(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->diffuse; warn("Invalid light component"); return {}; } void Scene::SetLightDiffuseColor(ComponentRef ref, const Color &v) { if (auto *c = GetComponent_(lights, ref)) c->diffuse = v; else warn("Invalid light component"); } float Scene::GetLightDiffuseIntensity(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->diffuse_intensity; warn("Invalid light component"); return {}; } void Scene::SetLightDiffuseIntensity(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->diffuse_intensity = v; else warn("Invalid light component"); } Color Light::GetDiffuseColor() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightDiffuseColor(ref); warn("Orphaned light component"); return {}; } void Light::SetDiffuseColor(const Color &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightDiffuseColor(ref, v); else warn("Orphaned light component"); } float Light::GetDiffuseIntensity() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightDiffuseIntensity(ref); warn("Orphaned light component"); return {}; } void Light::SetDiffuseIntensity(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightDiffuseIntensity(ref, v); else warn("Ophaned Light"); } Color Scene::GetLightSpecularColor(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->specular; warn("Invalid light component"); return {}; } void Scene::SetLightSpecularColor(ComponentRef ref, const Color &v) { if (auto *c = GetComponent_(lights, ref)) c->specular = v; else warn("Invalid light component"); } float Scene::GetLightSpecularIntensity(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->specular_intensity; warn("Invalid light component"); return {}; } void Scene::SetLightSpecularIntensity(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->specular_intensity = v; else warn("Invalid light component"); } Color Light::GetSpecularColor() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightSpecularColor(ref); warn("Orphaned light component"); return {}; } void Light::SetSpecularColor(const Color &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightSpecularColor(ref, v); else warn("Orphaned light component"); } float Light::GetSpecularIntensity() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightSpecularIntensity(ref); warn("Orphaned light component"); return {}; } void Light::SetSpecularIntensity(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightSpecularIntensity(ref, v); else warn("Orphaned light component"); } float Scene::GetLightRadius(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->radius; warn("Invalid light component"); return {}; } void Scene::SetLightRadius(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->radius = Max(v, 0.f); else warn("Invalid light component"); } float Light::GetRadius() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightRadius(ref); warn("Orphaned light component"); return {}; } void Light::SetRadius(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightRadius(ref, v); else warn("Orphaned light component"); } float Scene::GetLightInnerAngle(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->inner_angle; warn("Invalid light component"); return {}; } void Scene::SetLightInnerAngle(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->inner_angle = Clamp(v, 0.0001f, c->outer_angle - 0.0001f); else warn("Invalid light component"); } float Light::GetInnerAngle() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightInnerAngle(ref); warn("Orphaned light component"); return {}; } void Light::SetInnerAngle(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightInnerAngle(ref, v); else warn("Orphaned light component"); } float Scene::GetLightOuterAngle(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->outer_angle; warn("Invalid light component"); return {}; } void Scene::SetLightOuterAngle(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->outer_angle = Max(v, c->inner_angle + 0.0001f); else warn("Invalid light component"); } float Light::GetOuterAngle() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightOuterAngle(ref); warn("Orphaned light component"); return {}; } void Light::SetOuterAngle(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightOuterAngle(ref, v); else warn("Orphaned light component"); } Vec4 Scene::GetLightPSSMSplit(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->pssm_split; warn("Invalid light component"); return {}; } void Scene::SetLightPSSMSplit(ComponentRef ref, const Vec4 &v) { if (auto *c = GetComponent_(lights, ref)) c->pssm_split = v; else warn("Invalid light component"); } Vec4 Light::GetPSSMSplit() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightPSSMSplit(ref); warn("Orphaned light component"); return {}; } void Light::SetPSSMSplit(const Vec4 &v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightPSSMSplit(ref, v); else warn("Orphaned light component"); } float Scene::GetLightPriority(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->priority; warn("Invalid light component"); return {}; } void Scene::SetLightPriority(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->priority = v; else warn("Invalid light component"); } float Light::GetPriority() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightPriority(ref); warn("Orphaned light component"); return 0; } void Light::SetPriority(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightPriority(ref, v); else warn("Orphaned light component"); } float Scene::GetLightShadowBias(ComponentRef ref) const { if (const auto *c = GetComponent_(lights, ref)) return c->shadow_bias; warn("Invalid light component"); return {}; } void Scene::SetLightShadowBias(ComponentRef ref, float v) { if (auto *c = GetComponent_(lights, ref)) c->shadow_bias = v; else warn("Invalid light component"); } float Light::GetShadowBias() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetLightShadowBias(ref); warn("Orphaned light component"); return {}; } void Light::SetShadowBias(float v) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetLightShadowBias(ref, v); else warn("Orphaned light component"); } // Light Scene::CreateLinearLight(const Color &diffuse, float diffuse_intensity, const Color &specular, float specular_intensity, float priority, LightShadowType shadow_type, float shadow_bias, const Vec4 &pssm_split) { return {scene_ref, lights.add_ref({LT_Linear, shadow_type, diffuse, diffuse_intensity, specular, specular_intensity, 0, 0, 0, pssm_split, priority, shadow_bias})}; } Light Scene::CreatePointLight(const float radius, const Color &diffuse, float diffuse_intensity, const Color &specular, float specular_intensity, float priority, LightShadowType shadow_type, float shadow_bias) { return {scene_ref, lights.add_ref({LT_Point, shadow_type, diffuse, diffuse_intensity, specular, specular_intensity, radius, 0, 0, Vec4::Zero, priority, shadow_bias})}; } Light Scene::CreateSpotLight(const float radius, const float inner_angle, const float outer_angle, const Color &diffuse, float diffuse_intensity, const Color &specular, float specular_intensity, float priority, LightShadowType shadow_type, float shadow_bias) { return {scene_ref, lights.add_ref({LT_Spot, shadow_type, diffuse, diffuse_intensity, specular, specular_intensity, radius, inner_angle, outer_angle, Vec4::Zero, priority, shadow_bias})}; } // bool RigidBody::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidRigidBodyRef(ref) : false; } RigidBodyType RigidBody::GetType() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyType(ref); warn("Orphaned rigidBody component"); return {}; } void RigidBody::SetType(RigidBodyType type) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyType(ref, type); else warn("Orphaned rigidBody component"); } float RigidBody::GetLinearDamping() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyLinearDamping(ref); warn("Orphaned rigidBody component"); return 0.f; } void RigidBody::SetLinearDamping(float damping) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyLinearDamping(ref, damping); else warn("Orphaned rigidBody component"); } float RigidBody::GetAngularDamping() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyAngularDamping(ref); warn("Orphaned rigidBody component"); return 0.f; } void RigidBody::SetAngularDamping(float damping) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyAngularDamping(ref, damping); else warn("Orphaned rigidBody component"); } float RigidBody::GetRestitution() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyRestitution(ref); warn("Orphaned rigidBody component"); return 0.f; } void RigidBody::SetRestitution(float restitution) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyRestitution(ref, restitution); else warn("Orphaned rigidBody component"); } float RigidBody::GetFriction() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyFriction(ref); warn("Orphaned rigidBody component"); return 0.5f; } void RigidBody::SetFriction(float friction) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyFriction(ref, friction); else warn("Orphaned rigidBody component"); } float RigidBody::GetRollingFriction() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetRigidBodyRollingFriction(ref); warn("Orphaned rigidBody component"); return 0.f; } void RigidBody::SetRollingFriction(float rolling_friction) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetRigidBodyRollingFriction(ref, rolling_friction); else warn("Orphaned rigidBody component"); } // bool Collision::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidCollisionRef(ref) : false; } CollisionType Collision::GetType() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionType(ref); warn("Orphaned collision component"); return CT_Sphere; } void Collision::SetType(CollisionType type) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionType(ref, type); else warn("Orphaned collision component"); } Mat4 Collision::GetLocalTransform() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionLocalTransform(ref); warn("Orphaned collision component"); return Mat4::Identity; } void Collision::SetLocalTransform(const Mat4 &local) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionLocalTransform(ref, local); else warn("Orphaned collision component"); } Vec3 Collision::GetPosition() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionPosition(ref); warn("Orphaned collision component"); return Vec3::Zero; } void Collision::SetPosition(const Vec3 &pos) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionPosition(ref, pos); else warn("Orphaned collision component"); } Vec3 Collision::GetRotation() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionRotation(ref); warn("Orphaned collision component"); return Vec3::Zero; } void Collision::SetRotation(const Vec3 &rot) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionRotation(ref, rot); else warn("Orphaned collision component"); } float Collision::GetMass() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionMass(ref); warn("Orphaned collision component"); return 0.f; } void Collision::SetMass(float mass) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionMass(ref, mass); else warn("Orphaned collision component"); } float Collision::GetRadius() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionRadius(ref); warn("Orphaned collision component"); return 0.f; } void Collision::SetRadius(float radius) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionRadius(ref, radius); else warn("Orphaned collision component"); } float Collision::GetHeight() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionHeight(ref); warn("Orphaned collision component"); return {}; } void Collision::SetHeight(float height) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionHeight(ref, height); else warn("Orphaned collision component"); } Vec3 Collision::GetSize() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionSize(ref); warn("Orphaned collision component"); return {}; } void Collision::SetSize(const Vec3 &size) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionSize(ref, size); else warn("Orphaned collision component"); } std::string Collision::GetCollisionResource() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetCollisionResource(ref); warn("Orphaned collision component"); return {}; } void Collision::SetCollisionResource(const std::string &path) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetCollisionResource(ref, path); else warn("Orphaned collision component"); } // bool Instance::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidInstanceRef(ref) : false; } std::string Instance::GetPath() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetInstancePath(ref); warn("Orphaned instance component"); return {}; } void Instance::SetPath(const std::string &path) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetInstancePath(ref, path); else warn("Orphaned instance component"); } void Instance::SetOnInstantiateAnim(const std::string &anim) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetOnInstantiateAnim(ref, anim); else warn("Orphaned instance component"); } void Instance::SetOnInstantiateAnimLoopMode(AnimLoopMode loop_mode) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetOnInstantiateAnimLoopMode(ref, loop_mode); else warn("Orphaned instance component"); } void Instance::ClearOnInstantiateAnim() { if (scene_ref && scene_ref->scene) scene_ref->scene->ClearOnInstantiateAnim(ref); else warn("Orphaned instance component"); } std::string Instance::GetOnInstantiateAnim() { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetOnInstantiateAnim(ref); warn("Orphaned instance component"); return {}; } AnimLoopMode Instance::GetOnInstantiateAnimLoopMode() { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetOnInstantiateAnimLoopMode(ref); warn("Orphaned instance component"); return {}; } ScenePlayAnimRef Instance::GetOnInstantiatePlayAnimRef() { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetOnInstantiatePlayAnimRef(ref); warn("Orphaned instance component"); return {}; } // bool Script::IsValid() const { return scene_ref && scene_ref->scene ? scene_ref->scene->IsValidScriptRef(ref) : false; } std::string Script::GetPath() const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetScriptPath(ref); warn("Orphaned script component"); return {}; } void Script::SetPath(const std::string &path) { if (scene_ref && scene_ref->scene) scene_ref->scene->SetScriptPath(ref, path); else warn("Orphaned script component"); } // bool Script::HasParam(const std::string &name) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->ScriptHasParam(ref, name); warn("Orphaned script component"); return false; } ScriptParam Script::GetParam(const std::string &name) const { if (scene_ref && scene_ref->scene) return scene_ref->scene->GetScriptParam(ref, name); warn("Orphaned script component"); return {}; } bool Script::SetParam(const std::string &name, ScriptParam param) { if (scene_ref && scene_ref->scene) return scene_ref->scene->SetScriptParam(ref, name, param); warn("Orphaned script component"); return false; } } // namespace hg