From fcdeff9d99ee5d5dd4a933823dd77c0542f669e6 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 27 Jun 2021 22:27:57 -0400 Subject: [PATCH] Added triggers and targetting system for brushes. Added corresponding Scripting API endpoint for accessing those. --- Editor/resources/Scripts/Scene.wren | 38 +- Editor/resources/Scripts/Trigger.wren | 33 +- .../src/Core/Physics/CharacterController.cpp | 8 +- Nuake/src/Core/Physics/CharacterController.h | 4 + Nuake/src/Core/Physics/DynamicWorld.cpp | 4 +- Nuake/src/Core/Physics/GhostObject.cpp | 13 +- .../src/Scene/Components/BSPBrushComponent.h | 5 + Nuake/src/Scene/Components/TriggerZone.h | 14 +- Nuake/src/Scene/Systems/PhysicsSystem.cpp | 43 ++- Nuake/src/Scene/Systems/QuakeMapBuilder.cpp | 353 +++++++++++++----- Nuake/src/Scene/Systems/QuakeMapBuilder.h | 11 +- Nuake/src/Scripting/Modules/SceneModule.h | 44 ++- Nuake/src/Scripting/ScriptingEngine.cpp | 3 + 13 files changed, 454 insertions(+), 119 deletions(-) diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index 3acd7b66..72b0c58e 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -30,8 +30,9 @@ class Scene { return this.GetScript_(id) } else if (component == "Trigger") { return Trigger.new(id) + } else if (component == "Brush") { + return Brush.new(id) } - } // @@ -67,6 +68,9 @@ class Scene { foreign static TriggerGetOverlappingBodyCount_(e) foreign static TriggerGetOverlappingBodies_(e) + + foreign static BrushGetTargets_(e) + foreign static BrushGetTargetsCount_(e) } class Entity { @@ -170,12 +174,40 @@ class Trigger { } GetOverlappingBodies() { - bodies = Scene.TriggerGetOverlappingBodies_(_entityId) + if(this.GetOverlappingBodyCount() <= 0) { + return [] + } - entities = [] + var bodies = Scene.TriggerGetOverlappingBodies_(_entityId) + + var entities = [] for(b in bodies) { entities.add(Entity.new(b)) } + return entities + } +} + +class Brush { + construct new(id) { + _entityId = id + } + + GetTargetsCount() { + return Scene.BrushGetTargetsCount_(_entityId) + } + + GetTargets() { + if(this.GetTargetsCount() <= 0) { + return [] + } + + var entities = [] + var targets = Scene.BrushGetTargets_(_entityId) + for(t in targets) { + entities.add(Entity.new(t)) + } + return entities } } \ No newline at end of file diff --git a/Editor/resources/Scripts/Trigger.wren b/Editor/resources/Scripts/Trigger.wren index 8aceac87..e9bada17 100644 --- a/Editor/resources/Scripts/Trigger.wren +++ b/Editor/resources/Scripts/Trigger.wren @@ -7,20 +7,43 @@ import "Scripts/Physics" for Physics, CollisionResult class TriggerScript is ScriptableEntity { construct new() { - + _Activated = false } init() { - Engine.Log("Hello, I'm a trigger") } update(ts) { - } + fixedUpdate(ts) { var trigger = this.GetComponent("Trigger") - - Engine.Log("Current overlap: %(trigger.GetOverlappingBodyCount())") + if(trigger.GetOverlappingBodyCount() > 0) { + var bodies = trigger.GetOverlappingBodies() + var brush = this.GetComponent("Brush") + var isPlayer = bodies[0].HasComponent("CharacterController") + if(isPlayer) { + _Activated = true + } + + } + if(_Activated) { + var brush = this.GetComponent("Brush") + for(t in brush.GetTargets()) { + var transform = t.GetComponent("Transform") + var pos = transform.GetTranslation() + + var target = t.GetComponent("Brush") + var pos2 = target.GetTargets()[0].GetComponent("Transform") + var targetPos = pos2.GetTranslation() + + if(pos.y < targetPos.y) { + pos.y = pos.y + 3.0 * ts + } + + transform.SetTranslation(pos) + } + } } exit() { diff --git a/Nuake/src/Core/Physics/CharacterController.cpp b/Nuake/src/Core/Physics/CharacterController.cpp index 2d0e7ea3..196af851 100644 --- a/Nuake/src/Core/Physics/CharacterController.cpp +++ b/Nuake/src/Core/Physics/CharacterController.cpp @@ -49,6 +49,12 @@ namespace Physics //m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); } + void CharacterController::SetEntity(Entity& ent) + { + m_Rigidbody->setUserIndex(ent.GetHandle()); + m_GhostObject->setUserIndex(ent.GetHandle()); + } + void CharacterController::MoveAndSlide(glm::vec3 velocity) { m_Rigidbody->setGravity(btVector3(0, 0, 0)); @@ -77,7 +83,7 @@ namespace Physics manifoldArray.clear(); const btBroadphasePair& pair = pairArray[i]; - + btDiscreteDynamicsWorld* world = PhysicsManager::Get()->GetWorld()->GetDynamicWorld(); btBroadphasePair* collisionPair = world->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1); diff --git a/Nuake/src/Core/Physics/CharacterController.h b/Nuake/src/Core/Physics/CharacterController.h index 3bbf41a6..05de355f 100644 --- a/Nuake/src/Core/Physics/CharacterController.h +++ b/Nuake/src/Core/Physics/CharacterController.h @@ -6,6 +6,9 @@ #include #include #include "../Core/Maths.h" + + +class Entity; namespace Physics { class CharacterController @@ -37,6 +40,7 @@ namespace Physics float m_jumpRechargeTimer; CharacterController(float height, float radius, float mass, Vector3 position); + void SetEntity(Entity& ent); void MoveAndSlide(glm::vec3 velocity); private: void ParseGhostContacts(); diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index 87fdd7b7..f1be1152 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -51,7 +51,7 @@ namespace Physics void DynamicWorld::AddGhostbody(Ref gb) { - dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter); + dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter); } void DynamicWorld::AddCharacterController(Ref cc) @@ -59,7 +59,7 @@ namespace Physics dynamicsWorld->addRigidBody(cc->m_Rigidbody); // Specify filters manually, otherwise ghost doesn't collide with statics for some reason - dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter ); + dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter ); } diff --git a/Nuake/src/Core/Physics/GhostObject.cpp b/Nuake/src/Core/Physics/GhostObject.cpp index 0324f1c4..54328dd3 100644 --- a/Nuake/src/Core/Physics/GhostObject.cpp +++ b/Nuake/src/Core/Physics/GhostObject.cpp @@ -1,5 +1,8 @@ #include "GhostObject.h" #include +#include +#include +#include GhostObject::GhostObject(Vector3 position, Ref shape) @@ -7,7 +10,8 @@ GhostObject::GhostObject(Vector3 position, Ref shape) m_OverlappingEntities = std::vector(); m_BulletObject = new btGhostObject(); - btTransform transform; + btTransform transform = btTransform(); + transform.setIdentity(); transform.setOrigin(btVector3(position.x, position.y, position.z)); m_BulletObject->setWorldTransform(transform); @@ -32,9 +36,14 @@ void GhostObject::SetEntityID(Entity ent) void GhostObject::ScanOverlap() { ClearOverlappingList(); + for (int i = 0; i < OverlappingCount(); i++) { - Entity handle = Engine::GetCurrentScene()->GetEntity(m_BulletObject->getOverlappingObject(i)->getUserIndex()); + int index = m_BulletObject->getOverlappingObject(i)->getUserIndex(); + if (index == -1) + continue; + + Entity handle = Engine::GetCurrentScene()->GetEntity(index); m_OverlappingEntities.push_back(handle); } } diff --git a/Nuake/src/Scene/Components/BSPBrushComponent.h b/Nuake/src/Scene/Components/BSPBrushComponent.h index a6086b0e..83b0490d 100644 --- a/Nuake/src/Scene/Components/BSPBrushComponent.h +++ b/Nuake/src/Scene/Components/BSPBrushComponent.h @@ -11,9 +11,14 @@ public: std::vector> Meshes; std::vector< Ref> Materials; std::vector> Rigidbody; + + std::string target = ""; + std::vector Targets; + bool IsSolid = true; bool IsTrigger = false; bool IsTransparent = false; + bool IsFunc = false; BSPBrushComponent() { Meshes = std::vector>(); diff --git a/Nuake/src/Scene/Components/TriggerZone.h b/Nuake/src/Scene/Components/TriggerZone.h index 66df8248..e5a5d085 100644 --- a/Nuake/src/Scene/Components/TriggerZone.h +++ b/Nuake/src/Scene/Components/TriggerZone.h @@ -1,24 +1,32 @@ #pragma once #include "src/Core//Physics/GhostObject.h" #include - +# class TriggerZone { public: Ref GhostObject; + std::string target = ""; + std::vector Targets; bool Enabled = true; TriggerZone() { - + Targets = std::vector(); } + + int GetOverLappingCount() { - //if (!Enabled) return 0; + if (!Enabled) return 0; return GhostObject->OverlappingCount(); } + std::vector GetTargets() { + return Targets; + } + std::vector GetOverlappingBodies() { if (!Enabled) diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index 1dcd0da3..b0dcabb6 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -33,6 +33,7 @@ void PhysicsSystem::Init() Ref boxShape = CreateRef(boxComponent.Size); Ref btRigidbody = CreateRef(mass, transform.Translation, boxShape); + rigidbody.m_Rigidbody = btRigidbody; btRigidbody->SetKinematic(rigidbody.IsKinematic); @@ -41,8 +42,6 @@ void PhysicsSystem::Init() } } - - // character controllers auto ccview = m_Scene->m_Registry.view(); for (auto e : ccview) @@ -51,6 +50,7 @@ void PhysicsSystem::Init() cc.CharacterController = CreateRef(cc.Height, cc.Radius, cc.Mass, transform.Translation); Entity ent = Entity({ e, m_Scene }); + cc.CharacterController->SetEntity(ent); PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController); } @@ -78,14 +78,11 @@ void PhysicsSystem::Init() for (auto e : bspTriggerView) { auto [transform, brush, trigger] = bspTriggerView.get(e); - for (auto m : brush.Meshes) - { - Ref meshShape = CreateRef(m); - Ref ghostBody = CreateRef(transform.GlobalTranslation, meshShape); - trigger.GhostObject = ghostBody; - ghostBody->SetEntityID(Entity{ e, m_Scene }); - PhysicsManager::Get()->RegisterGhostBody(ghostBody); - } + Ref meshShape = CreateRef(brush.Meshes[0]); + Ref ghostBody = CreateRef(transform.GlobalTranslation, meshShape); + trigger.GhostObject = ghostBody; + + PhysicsManager::Get()->RegisterGhostBody(ghostBody); } } @@ -102,12 +99,36 @@ void PhysicsSystem::Update(Timestep ts) r->m_Transform->setOrigin(btVector3(transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z)); r->UpdateTransform(*r->m_Transform); } + + if (!brush.IsFunc) + continue; + + brush.Targets.clear(); + auto targetnameView = m_Scene->m_Registry.view(); + for (auto e2 : targetnameView) { + auto [ttransform, name] = targetnameView.get(e2); + + if (name.Name == brush.target) { + brush.Targets.push_back(Entity{ e2, m_Scene }); + } + } } + auto bspTriggerView = m_Scene->m_Registry.view(); for (auto e : bspTriggerView) { auto [transform, brush, trigger] = bspTriggerView.get(e); - Logger::Log(std::to_string(trigger.GetOverLappingCount())); + trigger.GhostObject->ScanOverlap(); + + brush.Targets.clear(); + auto targetnameView = m_Scene->m_Registry.view(); + for (auto e2 : targetnameView) { + auto [ttransform, name] = targetnameView.get(e2); + + if (name.Name == brush.target) { + brush.Targets.push_back(Entity{ e2, m_Scene }); + } + } } auto physicGroup = m_Scene->m_Registry.view(); diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index bc890279..6882fe2d 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -20,7 +20,7 @@ extern "C" { #include #include - +Ref DefaultMaterial; std::vector split(const std::string& s, char delim) { std::vector result; std::stringstream ss(s); @@ -33,6 +33,239 @@ std::vector split(const std::string& s, char delim) { return result; } +void QuakeMapBuilder::CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) +{ + std::vector vertices; + std::vector indices; + + Entity brushEntity = scene->CreateEntity("Trigger"); + TransformComponent& transformComponent = brushEntity.GetComponent(); + TriggerZone& trigger = brushEntity.AddComponent(); + trigger.target = target; + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3(brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + BSPBrushComponent& bsp = brushEntity.AddComponent(); + bsp.IsSolid = false; + bsp.target = target; + int indexOffset = 0; + for (int f = 0; f < brush->face_count; ++f) + { + face* face = &brush->faces[f]; + + face_geometry* face_geo_inst = &brush_inst->faces[f]; + + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex{ + vertexPos, + Vector2(0,0), + vertexNormal, + vertexTangent, + glm::vec3(0.0, 1.0, 0.0), 0.0f + }); + } + + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back((unsigned int)indexOffset + index); + } + + indexOffset += face_geo_inst->vertex_count; + } + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); +} + +void QuakeMapBuilder::CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) +{ + std::vector vertices; + std::vector indices; + Entity brushEntity = scene->CreateEntity(targetname); + TransformComponent& transformComponent = brushEntity.GetComponent(); + BSPBrushComponent& bsp = brushEntity.AddComponent(); + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3(brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + int index_offset = 0; + int lastTextureID = -1; + std::string lastTexturePath = ""; + for (int f = 0; f < brush->face_count; ++f) + { + face* face = &brush->faces[f]; + texture_data* texture = &textures[face->texture_idx]; + if (std::string(texture->name) == "__TB_empty") { + texture->height = 1; + texture->width = 1; + } + else { + std::string path = "resources/Textures/" + std::string(texture->name) + ".png"; + auto tex = TextureManager::Get()->GetTexture(path); + texture->height = tex->GetHeight(); + texture->width = tex->GetWidth(); + } + + face_geometry* face_geo_inst = &brush_inst->faces[f]; + + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); + + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex{ + vertexPos, + vertexUV, + vertexNormal, + vertexTangent, + glm::vec3(0.0, 1.0, 0.0), 0.0f + }); + } + + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back(index_offset + (unsigned int)index); + } + + if (lastTextureID != face->texture_idx) + { + lastTexturePath = "resources/Textures/" + std::string(texture->name) + ".png"; + if (std::string(texture->name) == "__TB_empty") + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); + else + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); + + index_offset = 0; + vertices.clear(); + indices.clear(); + lastTextureID = face->texture_idx; + } + else + { + index_offset += (face_geo_inst->vertex_count); + } + } + + if (vertices.size() > 0) + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); +} + +void QuakeMapBuilder::CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) +{ + std::vector vertices; + std::vector indices; + Entity brushEntity = scene->CreateEntity(targetname); + TransformComponent& transformComponent = brushEntity.GetComponent(); + BSPBrushComponent& bsp = brushEntity.AddComponent(); + bsp.IsFunc = true; + bsp.target = target; + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3(brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + int index_offset = 0; + int lastTextureID = -1; + std::string lastTexturePath = ""; + for (int f = 0; f < brush->face_count; ++f) + { + face* face = &brush->faces[f]; + texture_data* texture = &textures[face->texture_idx]; + if (std::string(texture->name) == "__TB_empty") { + texture->height = 1; + texture->width = 1; + } + else { + std::string path = "resources/Textures/" + std::string(texture->name) + ".png"; + auto tex = TextureManager::Get()->GetTexture(path); + texture->height = tex->GetHeight(); + texture->width = tex->GetWidth(); + } + + face_geometry* face_geo_inst = &brush_inst->faces[f]; + + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); + + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex{ + vertexPos, + vertexUV, + vertexNormal, + vertexTangent, + glm::vec3(0.0, 1.0, 0.0), 0.0f + }); + } + + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back(index_offset + (unsigned int)index); + } + + if (lastTextureID != face->texture_idx) + { + lastTexturePath = "resources/Textures/" + std::string(texture->name) + ".png"; + if (std::string(texture->name) == "__TB_empty") + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); + else + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); + + index_offset = 0; + vertices.clear(); + indices.clear(); + lastTextureID = face->texture_idx; + } + else + { + index_offset += (face_geo_inst->vertex_count); + } + } + + if (vertices.size() > 0) + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); +} + void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) { if (!ent.HasComponent()) @@ -52,7 +285,7 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) map_parser_load(quakeMapC.Path.c_str()); geo_generator_run(); - Ref DefaultMaterial = MaterialManager::Get()->GetMaterial("resources/Textures/default/Default.png"); + DefaultMaterial = MaterialManager::Get()->GetMaterial("resources/Textures/default/Default.png"); for (int e = 0; e < entity_count; ++e) { entity* entity_inst = &entities[e]; @@ -64,7 +297,12 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) newEntity.GetComponent().Name = "Group " + std::to_string(e); bool isTrigger = false; + bool isFunc = false; + bool isPos = false; ent.AddChild(newEntity); + + std::string target = ""; + std::string targetname = ""; for (int i = 0; i < entity_inst->property_count; i++) { property* prop = &(entity_inst->properties)[i]; std::string key = prop->key; @@ -93,105 +331,42 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) { //newEntity.AddComponent(); isTrigger = true; - newEntity.GetComponent().Name = "Trigger " + std::to_string(i); } + else if (value == "func_any") { + isFunc = true; + newEntity.GetComponent().Name = "func_any " + std::to_string(i); + } + else if (value == "position") { + isPos = true; + } + } + if (key == "targetname") { + if (isPos) { + + newEntity.GetComponent().Name = value; + isPos = false; + } + targetname = value; + } + if (key == "target") { + target = value; } - } for (int b = 0; b < entity_inst->brush_count; ++b) { - std::vector vertices; - std::vector indices; brush* brush_inst = &entity_inst->brushes[b]; brush_geometry* brush_geo_inst = &entity_geo_inst->brushes[b]; - Entity brushEntity = m_Scene->CreateEntity("Brush " + std::to_string(e)); - TransformComponent& transformComponent = brushEntity.GetComponent(); - BSPBrushComponent& bsp = brushEntity.AddComponent(); - - newEntity.AddChild(brushEntity); - if (isTrigger) { - bsp.IsTrigger = true; - bsp.IsSolid = false; - brushEntity.AddComponent(); + CreateTrigger(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); } - - transformComponent.Translation = Vector3(brush_inst->center.y * (1.0f / 64), - brush_inst->center.z * (1.0f / 64), - brush_inst->center.x * (1.0f / 64)); - - int index_offset = 0; - int lastTextureID = -1; - std::string lastTexturePath = ""; - for (int f = 0; f < brush_inst->face_count; ++f) - { - face* face = &brush_inst->faces[f]; - texture_data* texture = &textures[face->texture_idx]; - if (std::string(texture->name) == "__TB_empty") { - texture->height = 1; - texture->width = 1; - } - else { - std::string path = "resources/Textures/" + std::string(texture->name) + ".png"; - auto tex = TextureManager::Get()->GetTexture(path); - texture->height = tex->GetHeight(); - texture->width = tex->GetWidth(); - } - - face_geometry* face_geo_inst = &brush_geo_inst->faces[f]; - - for (int i = 0; i < face_geo_inst->vertex_count; ++i) - { - face_vertex vertex = face_geo_inst->vertices[i]; - vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); - - Vector3 vertexPos = Vector3( - (vertex.vertex.y - brush_inst->center.y) * (1.0f / 64), - (vertex.vertex.z - brush_inst->center.z) * (1.0f / 64), - (vertex.vertex.x - brush_inst->center.x) * (1.0f / 64) - ); - Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); - Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); - Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); - - vertices.push_back(Vertex{ - vertexPos, - vertexUV, - vertexNormal, - vertexTangent, - glm::vec3(0.0, 1.0, 0.0), 0.0f - }); - } - - for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) - { - unsigned int index = face_geo_inst->indices[i]; - indices.push_back(index_offset + (unsigned int)index); - } - - if (lastTextureID != face->texture_idx) - { - lastTexturePath = "resources/Textures/" + std::string(texture->name) + ".png"; - if (std::string(texture->name) == "__TB_empty") - bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); - else - bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); - - index_offset = 0; - vertices.clear(); - indices.clear(); - lastTextureID = face->texture_idx; - } - else - { - index_offset += (face_geo_inst->vertex_count); - } + else if (isFunc) { + CreateFuncBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); + } + else { + CreateBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); } - - if (vertices.size() > 0) - bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); } } } \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.h b/Nuake/src/Scene/Systems/QuakeMapBuilder.h index 8d6a7046..ff3243a3 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.h +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.h @@ -1,10 +1,19 @@ #pragma once - +#include class Entity; +class Scene; +struct brush; +struct brush_geometry; class QuakeMapBuilder { +private: + void CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); + void CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); + void CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); public: QuakeMapBuilder(){} void BuildQuakeMap(Entity& ent, bool Collisions = true); + + }; \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index cdfe2cb6..a408615a 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace ScriptAPI { @@ -46,6 +47,9 @@ namespace ScriptAPI RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount); RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies); + + RegisterMethod("BrushGetTargets_(_)", (void*)BrushGetTargets); + RegisterMethod("BrushGetTargetsCount_(_)", (void*)BrushGetTargetsCount); } static void GetEntity(WrenVM* vm) @@ -76,6 +80,11 @@ namespace ScriptAPI bool result = ent.HasComponent(); wrenSetSlotBool(vm, 0, result); } + if (name == "CharacterController") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } if (name == "Camera") { bool result = ent.HasComponent(); @@ -95,9 +104,14 @@ namespace ScriptAPI bool result = ent.HasComponent(); wrenSetSlotBool(vm, 0, result); } + if (name == "Brush") { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } } - static void GetScript(WrenVM* vm) { + static void GetScript(WrenVM* vm) + { int handle = wrenGetSlotDouble(vm, 1); Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); @@ -254,8 +268,9 @@ namespace ScriptAPI std::vector entities = trigger.GetOverlappingBodies(); - wrenEnsureSlots(vm, entities.size()); + wrenEnsureSlots(vm, entities.size() ); + wrenSetSlotNewList(vm, 0); int idx = 1; for (auto& e : entities) { @@ -263,7 +278,32 @@ namespace ScriptAPI wrenInsertInList(vm, 0, -1, idx); idx++; } + } + + static void BrushGetTargets(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + BSPBrushComponent& brush = ent.GetComponent(); + wrenEnsureSlots(vm, brush.Targets.size()); wrenSetSlotNewList(vm, 0); + + int idx = 1; + for (auto& e : brush.Targets) + { + wrenSetSlotDouble(vm, idx, e.GetHandle()); + wrenInsertInList(vm, 0, -1, idx); + idx++; + } + } + + static void BrushGetTargetsCount(WrenVM* vm) { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + BSPBrushComponent& brush = ent.GetComponent(); + wrenSetSlotDouble(vm, 0, brush.Targets.size()); } }; } \ No newline at end of file diff --git a/Nuake/src/Scripting/ScriptingEngine.cpp b/Nuake/src/Scripting/ScriptingEngine.cpp index 7ae73ee0..4f8831cd 100644 --- a/Nuake/src/Scripting/ScriptingEngine.cpp +++ b/Nuake/src/Scripting/ScriptingEngine.cpp @@ -23,6 +23,7 @@ void errorFn(WrenVM* vm, WrenErrorType errorType, { case WREN_ERROR_COMPILE: { + Engine::ExitPlayMode(); printf("[%s line %d] [Error] %s\n", module, line, msg); } break; case WREN_ERROR_STACK_TRACE: @@ -34,6 +35,8 @@ void errorFn(WrenVM* vm, WrenErrorType errorType, printf("[Runtime Error] %s\n", msg); } break; } + + }