mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-09 20:08:57 +03:00
Added triggers and targetting system for brushes. Added corresponding Scripting API endpoint for accessing those.
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
#include <vector>
|
||||
#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();
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Physics
|
||||
|
||||
void DynamicWorld::AddGhostbody(Ref<GhostObject> gb)
|
||||
{
|
||||
dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter);
|
||||
dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter);
|
||||
}
|
||||
|
||||
void DynamicWorld::AddCharacterController(Ref<CharacterController> 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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "GhostObject.h"
|
||||
#include <dependencies/bullet3/src/BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
#include <dependencies/bullet3/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h>
|
||||
#include <dependencies/bullet3/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
|
||||
#include <src/Core/Physics/PhysicsManager.h>
|
||||
|
||||
|
||||
GhostObject::GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape)
|
||||
@@ -7,7 +10,8 @@ GhostObject::GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape)
|
||||
m_OverlappingEntities = std::vector<Entity>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,14 @@ public:
|
||||
std::vector<Ref<Mesh>> Meshes;
|
||||
std::vector< Ref<Material>> Materials;
|
||||
std::vector<Ref<Physics::RigidBody>> Rigidbody;
|
||||
|
||||
std::string target = "";
|
||||
std::vector<Entity> Targets;
|
||||
|
||||
bool IsSolid = true;
|
||||
bool IsTrigger = false;
|
||||
bool IsTransparent = false;
|
||||
bool IsFunc = false;
|
||||
|
||||
BSPBrushComponent() {
|
||||
Meshes = std::vector<Ref<Mesh>>();
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
#pragma once
|
||||
#include "src/Core//Physics/GhostObject.h"
|
||||
#include <vector>
|
||||
|
||||
#
|
||||
class TriggerZone {
|
||||
public:
|
||||
Ref<GhostObject> GhostObject;
|
||||
std::string target = "";
|
||||
|
||||
std::vector<Entity> Targets;
|
||||
bool Enabled = true;
|
||||
|
||||
TriggerZone() {
|
||||
|
||||
Targets = std::vector<Entity>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GetOverLappingCount()
|
||||
{
|
||||
//if (!Enabled) return 0;
|
||||
if (!Enabled) return 0;
|
||||
|
||||
return GhostObject->OverlappingCount();
|
||||
}
|
||||
|
||||
std::vector<Entity> GetTargets() {
|
||||
return Targets;
|
||||
}
|
||||
|
||||
std::vector<Entity> GetOverlappingBodies()
|
||||
{
|
||||
if (!Enabled)
|
||||
|
||||
@@ -33,6 +33,7 @@ void PhysicsSystem::Init()
|
||||
Ref<Physics::Box> boxShape = CreateRef<Physics::Box>(boxComponent.Size);
|
||||
|
||||
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(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<TransformComponent, CharacterControllerComponent>();
|
||||
for (auto e : ccview)
|
||||
@@ -51,6 +50,7 @@ void PhysicsSystem::Init()
|
||||
|
||||
cc.CharacterController = CreateRef<Physics::CharacterController>(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<TransformComponent, BSPBrushComponent, TriggerZone>(e);
|
||||
|
||||
for (auto m : brush.Meshes)
|
||||
{
|
||||
Ref<Physics::MeshShape> meshShape = CreateRef<Physics::MeshShape>(m);
|
||||
Ref<GhostObject> ghostBody = CreateRef<GhostObject>(transform.GlobalTranslation, meshShape);
|
||||
trigger.GhostObject = ghostBody;
|
||||
ghostBody->SetEntityID(Entity{ e, m_Scene });
|
||||
PhysicsManager::Get()->RegisterGhostBody(ghostBody);
|
||||
}
|
||||
Ref<Physics::MeshShape> meshShape = CreateRef<Physics::MeshShape>(brush.Meshes[0]);
|
||||
Ref<GhostObject> ghostBody = CreateRef<GhostObject>(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<TransformComponent, NameComponent>();
|
||||
for (auto e2 : targetnameView) {
|
||||
auto [ttransform, name] = targetnameView.get<TransformComponent, NameComponent>(e2);
|
||||
|
||||
if (name.Name == brush.target) {
|
||||
brush.Targets.push_back(Entity{ e2, m_Scene });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto bspTriggerView = m_Scene->m_Registry.view<TransformComponent, BSPBrushComponent, TriggerZone>();
|
||||
for (auto e : bspTriggerView) {
|
||||
auto [transform, brush, trigger] = bspTriggerView.get<TransformComponent, BSPBrushComponent, TriggerZone>(e);
|
||||
Logger::Log(std::to_string(trigger.GetOverLappingCount()));
|
||||
trigger.GhostObject->ScanOverlap();
|
||||
|
||||
brush.Targets.clear();
|
||||
auto targetnameView = m_Scene->m_Registry.view<TransformComponent, NameComponent>();
|
||||
for (auto e2 : targetnameView) {
|
||||
auto [ttransform, name] = targetnameView.get<TransformComponent, NameComponent>(e2);
|
||||
|
||||
if (name.Name == brush.target) {
|
||||
brush.Targets.push_back(Entity{ e2, m_Scene });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto physicGroup = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
#include <src/Scene/Components/NameComponent.h>
|
||||
#include <src/Scene/Components/TriggerZone.h>
|
||||
|
||||
|
||||
Ref<Material> DefaultMaterial;
|
||||
std::vector<std::string> split(const std::string& s, char delim) {
|
||||
std::vector<std::string> result;
|
||||
std::stringstream ss(s);
|
||||
@@ -33,6 +33,239 @@ std::vector<std::string> 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<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
Entity brushEntity = scene->CreateEntity("Trigger");
|
||||
TransformComponent& transformComponent = brushEntity.GetComponent<TransformComponent>();
|
||||
TriggerZone& trigger = brushEntity.AddComponent<TriggerZone>();
|
||||
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<BSPBrushComponent>();
|
||||
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<Mesh>(vertices, indices, DefaultMaterial));
|
||||
}
|
||||
|
||||
void QuakeMapBuilder::CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname)
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
Entity brushEntity = scene->CreateEntity(targetname);
|
||||
TransformComponent& transformComponent = brushEntity.GetComponent<TransformComponent>();
|
||||
BSPBrushComponent& bsp = brushEntity.AddComponent<BSPBrushComponent>();
|
||||
|
||||
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<Mesh>(vertices, indices, DefaultMaterial));
|
||||
else
|
||||
bsp.Meshes.push_back(CreateRef<Mesh>(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<Mesh>(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<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
Entity brushEntity = scene->CreateEntity(targetname);
|
||||
TransformComponent& transformComponent = brushEntity.GetComponent<TransformComponent>();
|
||||
BSPBrushComponent& bsp = brushEntity.AddComponent<BSPBrushComponent>();
|
||||
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<Mesh>(vertices, indices, DefaultMaterial));
|
||||
else
|
||||
bsp.Meshes.push_back(CreateRef<Mesh>(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<Mesh>(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath)));
|
||||
}
|
||||
|
||||
void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions)
|
||||
{
|
||||
if (!ent.HasComponent<QuakeMapComponent>())
|
||||
@@ -52,7 +285,7 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions)
|
||||
map_parser_load(quakeMapC.Path.c_str());
|
||||
geo_generator_run();
|
||||
|
||||
Ref<Material> 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<NameComponent>().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<LightComponent>();
|
||||
isTrigger = true;
|
||||
|
||||
newEntity.GetComponent<NameComponent>().Name = "Trigger " + std::to_string(i);
|
||||
}
|
||||
else if (value == "func_any") {
|
||||
isFunc = true;
|
||||
newEntity.GetComponent<NameComponent>().Name = "func_any " + std::to_string(i);
|
||||
}
|
||||
else if (value == "position") {
|
||||
isPos = true;
|
||||
}
|
||||
}
|
||||
if (key == "targetname") {
|
||||
if (isPos) {
|
||||
|
||||
newEntity.GetComponent<NameComponent>().Name = value;
|
||||
isPos = false;
|
||||
}
|
||||
targetname = value;
|
||||
}
|
||||
if (key == "target") {
|
||||
target = value;
|
||||
}
|
||||
|
||||
}
|
||||
for (int b = 0; b < entity_inst->brush_count; ++b)
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> 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<TransformComponent>();
|
||||
BSPBrushComponent& bsp = brushEntity.AddComponent<BSPBrushComponent>();
|
||||
|
||||
newEntity.AddChild(brushEntity);
|
||||
|
||||
if (isTrigger) {
|
||||
bsp.IsTrigger = true;
|
||||
bsp.IsSolid = false;
|
||||
brushEntity.AddComponent<TriggerZone>();
|
||||
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<Mesh>(vertices, indices, DefaultMaterial));
|
||||
else
|
||||
bsp.Meshes.push_back(CreateRef<Mesh>(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<Mesh>(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
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);
|
||||
|
||||
|
||||
};
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <src/Scene/Components/CharacterControllerComponent.h>
|
||||
#include <src/Scene/Components/WrenScriptComponent.h>
|
||||
#include <src/Scene/Components/TriggerZone.h>
|
||||
#include <src/Scene/Components/BSPBrushComponent.h>
|
||||
|
||||
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<QuakeMapComponent>();
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
if (name == "CharacterController")
|
||||
{
|
||||
bool result = ent.HasComponent<CharacterControllerComponent>();
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
if (name == "Camera")
|
||||
{
|
||||
bool result = ent.HasComponent<CameraComponent>();
|
||||
@@ -95,9 +104,14 @@ namespace ScriptAPI
|
||||
bool result = ent.HasComponent<WrenScriptComponent>();
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
if (name == "Brush") {
|
||||
bool result = ent.HasComponent<BSPBrushComponent>();
|
||||
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<Entity> 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<BSPBrushComponent>();
|
||||
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<BSPBrushComponent>();
|
||||
wrenSetSlotDouble(vm, 0, brush.Targets.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user