#include "SceneNetAPI.h" #include "Engine.h" #include "src/Scene/Entities/Entity.h" #include "src/Scene/Components/ParentComponent.h" #include "src/Scene/Components/PrefabComponent.h" #include "src/Scene/Components/CameraComponent.h" #include "src/Scene/Components/AudioEmitterComponent.h" #include "src/Scene/Components/ModelComponent.h" #include "src/Scene/Components/SkinnedModelComponent.h" #include "src/Scene/Components/BoneComponent.h" #include "src/Scene/Components/BoxCollider.h" #include "src/Scene/Components/SphereCollider.h" #include "src/Scene/Components/CapsuleColliderComponent.h" #include "src/Scene/Components/CylinderColliderComponent.h" #include "src/Scene/Components/MeshCollider.h" #include "src/Scene/Components/CharacterControllerComponent.h" #include "src/Scene/Components/ParticleEmitterComponent.h" #include "src/Scene/Components/BSPBrushComponent.h" #include "src/Scene/Components/SpriteComponent.h" #include "src/Scene/Components/QuakeMap.h" #include "src/Physics/PhysicsManager.h" #include "src/Scripting/ScriptingEngineNet.h" #include #include namespace Nuake { uint32_t GetEntity(Coral::String entityName) { auto scene = Engine::GetCurrentScene(); if (!scene->EntityExists(entityName)) { return UINT32_MAX; // Error code: entity not found. } return scene->GetEntity(entityName).GetHandle(); } Coral::ManagedObject GetEntityScriptFromName(Coral::String entityName) { auto scene = Engine::GetCurrentScene(); if (!scene->EntityExists(entityName)) { return Coral::ManagedObject(); // Error code: entity not found. } Entity entity = scene->GetEntity(entityName); auto& scriptingEngine = ScriptingEngineNet::Get(); if (scriptingEngine.HasEntityScriptInstance(entity)) { auto instance = scriptingEngine.GetEntityScript(entity); return instance; } } Coral::ManagedObject GetEntityScriptFromHandle(int entityHandle) { auto scene = Engine::GetCurrentScene(); Entity entity = { (entt::entity)(entityHandle), scene.get()}; if (!entity.IsValid()) { return Coral::ManagedObject(); // Error code: entity not found. } auto& scriptingEngine = ScriptingEngineNet::Get(); if (scriptingEngine.HasEntityScriptInstance(entity)) { auto instance = scriptingEngine.GetEntityScript(entity); return instance; } } int InstancePrefab(Coral::String path) { if (!FileSystem::FileExists(path)) { return -1; } const auto& prefab = Prefab::New(path); return prefab->Root.GetHandle(); } enum ComponentTypes { Unknown = -1, PARENT = 0, NAME, PREFAB, TRANSFORM, LIGHT, CAMERA, AUDIO_EMITTER, MODEL, SKINNED_MODEL, BONE, RIGIDBODY, BOX_COLLIDER, SPHERE_COLLIDER, CAPSULE_COLLIDER, CYLINDER_COLLIDER, MESH_COLLIDER, CHARACTER_CONTROLLER, PARTICLE_EMITTER, QUAKE_MAP, BSP_BRUSH, SPRITE, NAVMESH }; bool EntityHasComponent(int id, int componentType) { uint32_t componentEnumValue = 3; //Entity entity = Engine::GetCurrentScene()->GetEntityByID(id); Entity entity = { (entt::entity)(id), Engine::GetCurrentScene().get()}; if (!entity.IsValid()) { return false; } switch (static_cast(componentType)) { case PARENT: return entity.HasComponent(); case NAME: return entity.HasComponent(); case PREFAB: return entity.HasComponent(); case TRANSFORM: return entity.HasComponent(); case LIGHT: return entity.HasComponent(); case CAMERA: return entity.HasComponent(); case AUDIO_EMITTER: return entity.HasComponent(); case MODEL: return entity.HasComponent(); case SKINNED_MODEL: return entity.HasComponent(); case BONE: return entity.HasComponent(); case BOX_COLLIDER: return entity.HasComponent(); case SPHERE_COLLIDER: return entity.HasComponent(); case CAPSULE_COLLIDER: return entity.HasComponent(); case CYLINDER_COLLIDER: return entity.HasComponent(); case MESH_COLLIDER: return entity.HasComponent(); case CHARACTER_CONTROLLER: return entity.HasComponent(); case PARTICLE_EMITTER: return entity.HasComponent(); case QUAKE_MAP: return entity.HasComponent(); case BSP_BRUSH: return entity.HasComponent(); case SPRITE: return entity.HasComponent(); case NAVMESH: return entity.HasComponent(); default: return false; } } bool EntityHasManagedInstance(int handle) { Entity entity = { (entt::entity)(handle), Engine::GetCurrentScene().get() }; if (!entity.IsValid()) { return false; } return ScriptingEngineNet::Get().HasEntityScriptInstance(entity); } int EntityGetEntity(int handle, Coral::String input) { Ref scene = Engine::GetCurrentScene(); if (String::BeginsWith(input, "/")) { return scene->GetEntityFromPath(input).GetHandle(); } Entity entity = { (entt::entity)handle, scene.get() }; return scene->GetRelativeEntityFromPath(entity, input).GetHandle(); } Coral::String EntityGetName(int handle) { Entity entity = { (entt::entity)(handle), Engine::GetCurrentScene().get() }; if (!entity.IsValid()) { return Coral::String(); } return Coral::String::New(entity.GetComponent().Name); } void EntitySetName(int handle, Coral::String newName) { Entity entity = { (entt::entity)(handle), Engine::GetCurrentScene().get() }; if (!entity.IsValid()) { return; } const std::string newEntityName = Engine::GetCurrentScene()->GetUniqueEntityName(newName); entity.GetComponent().Name = newEntityName; } bool EntityIsValid(int handle) { Entity entity = { (entt::entity)(handle), Engine::GetCurrentScene().get() }; return entity.IsValid(); } Coral::String EntityGetTarget(int handle) { Entity entity = { (entt::entity)(handle), Engine::GetCurrentScene().get() }; if (entity.IsValid()) { if (entity.HasComponent()) { return Coral::String::New(entity.GetComponent().target); } } return Coral::String::New(""); } Coral::Array EntityGetTargets(Coral::String target) { std::vector targetsFound = std::vector(); if (target == "") { return Coral::Array::New(targetsFound); } Ref scene = Engine::GetCurrentScene(); auto brushView = scene->m_Registry.view(); for (auto e : brushView) { BSPBrushComponent& brushComponent = brushView.get(e); auto targets = brushComponent.Targets; if (brushComponent.TargetName == target) { Entity entity = { (entt::entity)(e), scene.get() }; targetsFound.push_back(entity.GetHandle()); } } return Coral::Array::New(targetsFound); } int PrefabInstance(Coral::String path, Vector3 position, float qx, float qy, float qz, float qw) { if (!FileSystem::FileExists(path)) { Logger::Log("Prefab path doesn't exist", ".net", CRITICAL); } const auto& prefab = Prefab::New(path); Entity root = prefab->Root; TransformComponent& transformComponent = root.GetComponent(); transformComponent.SetLocalPosition(position); transformComponent.SetLocalRotation(Quat(qw, qx, qy, qz)); return root.GetHandle(); } void TransformSetPosition(int entityId, float x, float y, float z) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); component.SetLocalPosition({ x, y, z }); if (entity.HasComponent()) { PhysicsManager::Get().SetCharacterControllerPosition(entity, { x, y, z }); } if (entity.HasComponent()) { PhysicsManager::Get().SetBodyTransform(entity, { x, y, z }, component.GetGlobalRotation()); } } } Coral::Array TransformGetPosition(int entityId) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); const auto& position = component.GetLocalPosition(); Coral::Array result = Coral::Array::New({ position.x, position.y, position.z }); return result; } } Coral::Array TransformGetGlobalPosition(int entityId) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); const auto& globalPosition = component.GetGlobalPosition(); Coral::Array result = Coral::Array::New({ globalPosition.x, globalPosition.y, globalPosition.z }); return result; } } void TransformRotate(int entityId, float x, float y, float z) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { Quat quat = QuatFromEuler(x, y, z); auto& component = entity.GetComponent(); component.SetLocalRotation(quat); } } float LightGetIntensity(int entityId) { Logger::Log("Get light intensity with id: " + std::to_string(entityId)); return -10.0f; } void LightSetIntensity(int entityId, float intensity) { Logger::Log("Set light intensity with id: " + std::to_string(intensity)); } Coral::Array CameraGetDirection(int entityId) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); const Vector3 camDirection = component.CameraInstance->GetDirection(); return Coral::Array::New({ camDirection.x, camDirection.y, camDirection.z }); } } float CameraGetFOV(int entityId) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); return component.CameraInstance->Fov; } } void CameraSetFOV(int entityId, float fov) { float safeFov = glm::clamp(fov, 1.0f, 180.0f); Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); component.CameraInstance->Fov = safeFov; } } void MoveAndSlide(int entityId, float vx, float vy, float vz) { Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() }; if (entity.IsValid() && entity.HasComponent()) { auto& component = entity.GetComponent(); if (std::isnan(vx) || std::isnan(vy) || std::isnan(vz)) { return; // Log message here? invalid input } component.GetCharacterController()->MoveAndSlide({ vx, vy, vz }); } } bool IsOnGround(int entityId) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); if (entity.IsValid() && entity.HasComponent()) { auto& characterController = entity.GetComponent(); return PhysicsManager::Get().GetWorld()->IsCharacterGrounded(entity); } return false; } Coral::Array GetGroundVelocity(int entityId) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); Coral::Array resultArray = Coral::Array::New(3); if (entity.IsValid() && entity.HasComponent()) { auto& characterController = entity.GetComponent(); Vector3 groundVelocity = PhysicsManager::Get().GetWorld()->GetCharacterGroundVelocity(entity); resultArray[0] = groundVelocity.x; resultArray[1] = groundVelocity.y; resultArray[2] = groundVelocity.z; return resultArray; } resultArray[0] = 0.0f; resultArray[1] = 0.0f; resultArray[2] = 0.0f; return resultArray; } Coral::Array GetGroundNormal(int entityId) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); Coral::Array resultArray = Coral::Array::New(3); if (entity.IsValid() && entity.HasComponent()) { auto& characterController = entity.GetComponent(); Vector3 groundVelocity = PhysicsManager::Get().GetWorld()->GetCharacterGroundNormal(entity); resultArray[0] = groundVelocity.x; resultArray[1] = groundVelocity.y; resultArray[2] = groundVelocity.z; return resultArray; } resultArray[0] = 0.0f; resultArray[1] = 0.0f; resultArray[2] = 0.0f; return resultArray; } void Play(int entityId, Coral::String animation) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); if (entity.IsValid() && entity.HasComponent()) { auto& skinnedModel = entity.GetComponent(); if (skinnedModel.ModelResource) { auto& model = skinnedModel.ModelResource; // Find animation from name int animIndex = 0; for (const auto& anim : model->GetAnimations()) { if (anim->GetName() == animation) { model->PlayAnimation(animIndex); } animIndex++; } } } } Coral::Array NavMeshComponentFindPath(int entityId, float startx, float starty, float startz, float endx, float endy, float endz) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); if (entity.IsValid() && entity.HasComponent()) { auto& navMeshVolume = entity.GetComponent(); if (navMeshVolume.NavMeshData && navMeshVolume.NavMeshData->IsValid()) { auto& navMesh = navMeshVolume.NavMeshData; const Vector3& startPosition = { startx, starty, startz }; const Vector3& endPosition = { endx, endy, endz }; auto waypoints = navMesh->FindStraightPath(startPosition, endPosition); // Convert Vector3 array into float array Coral::Array returnResult = Coral::Array::New(static_cast(waypoints.size()) * 3); for (int i = 0; i < waypoints.size(); i++) { returnResult[i * 3 + 0] = waypoints[i].x; returnResult[i * 3 + 1] = waypoints[i].y; returnResult[i * 3 + 2] = waypoints[i].z; } return returnResult; } } return {}; } bool AudioEmitterGetIsPlaying(int entityId) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); if (entity.IsValid() && entity.HasComponent()) { auto& audioEmitter = entity.GetComponent(); return audioEmitter.IsPlaying; } return false; } void AudioEmitterSetIsPlaying(int entityId, Coral::Bool32 isPlaying) { Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get()); if (entity.IsValid() && entity.HasComponent()) { auto& audioEmitter = entity.GetComponent(); audioEmitter.IsPlaying = isPlaying; } } void Nuake::SceneNetAPI::RegisterMethods() { // Entity RegisterMethod("Entity.EntityHasComponentIcall", &EntityHasComponent); RegisterMethod("Entity.EntityHasManagedInstanceIcall", &EntityHasManagedInstance); RegisterMethod("Entity.EntityGetEntityIcall", &EntityGetEntity); RegisterMethod("Entity.EntityGetNameIcall", &EntityGetName); RegisterMethod("Entity.EntitySetNameIcall", &EntitySetName); RegisterMethod("Entity.EntityIsValidIcall", &EntityIsValid); RegisterMethod("Entity.EntityGetTargetsIcall", &EntityGetTargets); RegisterMethod("Entity.EntityGetTargetIcall", &EntityGetTarget); // Prefab RegisterMethod("Prefab.PrefabInstanceIcall", &PrefabInstance); // Scene RegisterMethod("Scene.GetEntityIcall", &GetEntity); RegisterMethod("Scene.GetEntityScriptFromNameIcall", &GetEntityScriptFromName); RegisterMethod("Scene.GetEntityScriptFromHandleIcall", &GetEntityScriptFromHandle); RegisterMethod("Scene.InstancePrefabIcall", &InstancePrefab); // Components // Transform RegisterMethod("TransformComponent.SetPositionIcall", &TransformSetPosition); RegisterMethod("TransformComponent.GetPositionIcall", &TransformGetPosition); RegisterMethod("TransformComponent.GetGlobalPositionIcall", &TransformGetGlobalPosition); RegisterMethod("TransformComponent.RotateIcall", &TransformRotate); // Lights RegisterMethod("LightComponent.GetLightIntensityIcall", &LightGetIntensity); RegisterMethod("LightComponent.SetLightIntensityIcall", &LightSetIntensity); // Camera RegisterMethod("CameraComponent.GetDirectionIcall", &CameraGetDirection); RegisterMethod("CameraComponent.GetCameraFOVIcall", &CameraGetFOV); RegisterMethod("CameraComponent.SetCameraFOVIcall", &CameraSetFOV); // Character Controller RegisterMethod("CharacterControllerComponent.MoveAndSlideIcall", &MoveAndSlide); RegisterMethod("CharacterControllerComponent.IsOnGroundIcall", &IsOnGround); RegisterMethod("CharacterControllerComponent.GetGroundVelocityIcall", &GetGroundVelocity); RegisterMethod("CharacterControllerComponent.GetGroundNormalIcall", &GetGroundNormal); // Skinned RegisterMethod("SkinnedModelComponent.PlayIcall", &Play); // Navigation Mesh RegisterMethod("NavMeshVolumeComponent.FindPathIcall", &NavMeshComponentFindPath); // Audio Emitter RegisterMethod("AudioEmitterComponent.GetIsPlayingIcall", &AudioEmitterGetIsPlaying); RegisterMethod("AudioEmitterComponent.SetIsPlayingIcall", &AudioEmitterSetIsPlaying); } }