Added triggers and targetting system for brushes. Added corresponding Scripting API endpoint for accessing those.

This commit is contained in:
Antoine Pilote
2021-06-27 22:27:57 -04:00
parent 8f4c5f8b08
commit fcdeff9d99
13 changed files with 454 additions and 119 deletions

View File

@@ -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
}
}

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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();

View File

@@ -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 );
}

View File

@@ -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);
}
}

View File

@@ -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>>();

View File

@@ -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)

View File

@@ -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>();

View File

@@ -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)));
}
}
}

View File

@@ -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);
};

View File

@@ -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());
}
};
}

View File

@@ -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;
}
}