[Add] Initial non-accelerating collision space.

This commit is contained in:
Allanis 2018-02-20 20:09:45 +00:00
parent e644c15e07
commit 5b1a10b70b
9 changed files with 156 additions and 60 deletions

View File

@ -1,5 +1,5 @@
noinst_LIBRARIES = libcollider.a noinst_LIBRARIES = libcollider.a
libcollider_a_SOURCES = geom_tree.cpp libcollider_a_SOURCES = geom_tree.cpp geom.cpp collision_space.cpp
include_HEADERS = geom_tree.h include_HEADERS = geom_tree.h geom.h collision_space.h

View File

@ -0,0 +1,29 @@
#include "collision_space.h"
#include "geom.h"
#include "geom_tree.h"
CollisionSpace::CollisionSpace(void) {
}
void CollisionSpace::AddGeom(Geom* geom) {
m_geoms.push_back(geom);
}
void CollisionSpace::RemoveGeom(Geom* geom) {
m_geoms.remove(geom);
}
void CollisionSpace::TraceRay(const vector3d& start, const vector3d& dir, isect_t* isect) {
for(std::list<Geom*>::iterator i = m_geoms.begin(); i != m_geoms.end(); ++i) {
if((*i)->IsEnabled()) {
const matrix4x4d& invTrans = (*i)->GetInvTransform();
vector3d ms = invTrans * start;
vector3d md = invTrans.ApplyRotationOnly(dir);
vector3f modelStart = vector3f(ms.x, ms.y, ms.z);
vector3f modelDir = vector3f(md.x, md.y, md.z);
(*i)->GetGeomTree()->TraceRay(modelStart, modelDir, isect);
}
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <list>
#include "../vector3.h"
class Geom;
struct isect_t;
class CollisionSpace {
public:
CollisionSpace(void);
void AddGeom(Geom*);
void RemoveGeom(Geom*);
void TraceRay(const vector3d& start, const vector3d& dir, isect_t* isect);
private:
std::list<Geom*> m_geoms;
};

29
src/collider/geom.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "geom.h"
Geom::Geom(GeomTree* geomtree) {
m_geomtree = geomtree;
m_orient = matrix4x4d::Identity();
m_invOrient = matrix4x4d::Identity();
m_active = true;
}
void Geom::SetPosition(vector3d pos) {
m_orient[12] = pos.x;
m_orient[13] = pos.y;
m_orient[14] = pos.z;
m_invOrient = m_orient.InverseOf();
}
void Geom::SetOrientation(const matrix4x4d& rot) {
m_orient[0] = rot[0];
m_orient[1] = rot[1];
m_orient[2] = rot[2];
m_orient[4] = rot[4];
m_orient[5] = rot[5];
m_orient[6] = rot[6];
m_orient[8] = rot[8];
m_orient[9] = rot[9];
m_orient[10] = rot[10];
m_invOrient = m_orient.InverseOf();
}

22
src/collider/geom.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "../matrix4x4.h"
#include "../vector3.h"
class GeomTree;
class Geom {
public:
Geom(GeomTree*);
void SetPosition(vector3d pos);
void SetOrientation(const matrix4x4d& rot);
const matrix4x4d& GetInvTransform(void) { return m_invOrient; }
void Enable(void) { m_active = true; }
void Disable(void) {m_active = false; }
bool IsEnabled(void) { return m_active; }
GeomTree* GetGeomTree(void) { return m_geomtree; }
private:
matrix4x4d m_orient, m_invOrient;
bool m_active;
GeomTree* m_geomtree;
};

View File

@ -18,7 +18,6 @@
#include "../aabb.h" #include "../aabb.h"
#include "geom_tree.h" #include "geom_tree.h"
#define DEBUG
#define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MIN(a,b) ((a)<(b) ? (a) : (b))
#define MAX(a,b) ((a)>(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b))
@ -38,8 +37,6 @@ public:
SetList(tri); SetList(tri);
} }
float FindNiceSplitPos(int splitAxis, int* numPoints, int* numPrims);
void Dump(int depth, Aabb& box);
void SetAxis(int axis) { m_axis = axis; } void SetAxis(int axis) { m_axis = axis; }
int GetAxis(void) const { return m_axis; } int GetAxis(void) const { return m_axis; }
void SetSplitPos1(float p) { splitPos1 = p; } void SetSplitPos1(float p) { splitPos1 = p; }
@ -258,8 +255,6 @@ void GeomTree::BihTreeGhBuild(BIHNode* a_node, Aabb& a_box, Aabb& a_splitBox, in
else right->SetLeaf(true); else right->SetLeaf(true);
} }
#define SIGN_OF(f) (*((unsigned int*)(&f)) >> 31)
void GeomTree::TraceRay(vector3f& start, vector3f& dir, isect_t* isect) { void GeomTree::TraceRay(vector3f& start, vector3f& dir, isect_t* isect) {
float len = dir.Length(); float len = dir.Length();
isect->dist = len; isect->dist = len;
@ -272,9 +267,6 @@ void GeomTree::TraverseRay(vector3f& a_origin, vector3f& a_dir, isect_t* isect)
float entry_t = 0, exit_t = isect->dist; float entry_t = 0, exit_t = isect->dist;
vector3f rcpD = vector3f(1.0f/a_dir.x, 1.0f/a_dir.y, 1.0f/a_dir.z); vector3f rcpD = vector3f(1.0f/a_dir.x, 1.0f/a_dir.y, 1.0f/a_dir.z);
int Dneg[3]; int Dneg[3];
#ifdef DEBUG
int num_raytri_tests = 0;
#endif
Dneg[0] = (a_dir.x < 0 ? 1 : 0); Dneg[0] = (a_dir.x < 0 ? 1 : 0);
Dneg[1] = (a_dir.y < 0 ? 1 : 0); Dneg[1] = (a_dir.y < 0 ? 1 : 0);
@ -328,9 +320,6 @@ void GeomTree::TraverseRay(vector3f& a_origin, vector3f& a_dir, isect_t* isect)
/* Traverse bih-tree. */ /* Traverse bih-tree. */
while(currnode) { while(currnode) {
while (!currnode->IsLeaf()) { while (!currnode->IsLeaf()) {
#ifdef DEBUG
//m_stats.treeNodeTraversals++;
#endif
const int axis = currnode->GetAxis(); const int axis = currnode->GetAxis();
float d[2]; float d[2];
@ -371,9 +360,6 @@ void GeomTree::TraverseRay(vector3f& a_origin, vector3f& a_dir, isect_t* isect)
/* Woop, we are a leaf node. */ /* Woop, we are a leaf node. */
for(tri_t* p = currnode->GetList(); p != NULL; p = p->next) { for(tri_t* p = currnode->GetList(); p != NULL; p = p->next) {
#ifdef DEBUG
num_raytri_tests++;
#endif
RayTriIntersect(a_origin, a_dir, p->triIdx, isect); RayTriIntersect(a_origin, a_dir, p->triIdx, isect);
} }

View File

@ -180,7 +180,8 @@ public:
cell[14] = 0; cell[14] = 0;
} }
T& operator[] (const int i) { return cell[i]; } T& operator[] (const size_t i) { return cell[i]; }
const T& operator[] (const size_t i) const { return cell[i]; }
friend matrix4x4 operator+(const matrix4x4& a, const matrix4x4& b) { friend matrix4x4 operator+(const matrix4x4& a, const matrix4x4& b) {
matrix4x4 m; matrix4x4 m;
for(int i = 0; i < 16; i++) m.cell[i] = a.cell[i] + b.cell[i]; for(int i = 0; i < 16; i++) m.cell[i] = a.cell[i] + b.cell[i];

View File

@ -3,6 +3,8 @@
#include "glfreetype.h" #include "glfreetype.h"
#include "gui.h" #include "gui.h"
#include "collider/geom_tree.h" #include "collider/geom_tree.h"
#include "collider/collision_space.h"
#include "collider/geom.h"
static SDL_Surface* g_screen; static SDL_Surface* g_screen;
static int g_width, g_height; static int g_width, g_height;
@ -53,7 +55,7 @@ static void PollEvents(void) {
static int g_wheelMoveDir = -1; static int g_wheelMoveDir = -1;
static float g_wheelPos = 0; static float g_wheelPos = 0;
static bool g_renderCollMesh = false; static int g_renderType = 0;
static float lightCol[4] = { 1, 1, 1, 0 }; static float lightCol[4] = { 1, 1, 1, 0 };
static float lightDir[4] = { 0, 1, 0, 0 }; static float lightDir[4] = { 0, 1, 0, 0 };
static float g_frameTime; static float g_frameTime;
@ -100,11 +102,11 @@ public:
Gui::Screen::AddBaseWidget(this, 0, 0); Gui::Screen::AddBaseWidget(this, 0, 0);
SetTransparency(true); SetTransparency(true);
{ {
Gui::ToggleButton* b = new Gui::ToggleButton(); Gui::Button* b = new Gui::SolidButton();
b->SetShortcut(SDLK_c, KMOD_NONE); b->SetShortcut(SDLK_c, KMOD_NONE);
b->onChange.connect(sigc::mem_fun(*this, &Viewer::OnToggleCollMesh)); b->onClick.connect(sigc::mem_fun(*this, &Viewer::OnClickChangeView));
Add(b, 10, 10); Add(b, 10, 10);
Add(new Gui::Label("[c] Show collision mesh."), 30, 10); Add(new Gui::Label("[c] Change view (normal, collision mesh, raytraced collision mesh)"), 30, 10);
} }
{ {
Gui::Button* b = new Gui::SolidButton(); Gui::Button* b = new Gui::SolidButton();
@ -123,8 +125,9 @@ public:
else g_wheelMoveDir = -1; else g_wheelMoveDir = -1;
} }
void OnToggleCollMesh(Gui::ToggleButton* b, bool state) { void OnClickChangeView(void) {
g_renderCollMesh = state; g_renderType++;
if(g_renderType > 2) g_renderType = 0;
} }
void MainLoop(); void MainLoop();
@ -136,8 +139,8 @@ static void render_coll_mesh(const CollMesh* m) {
glBegin(GL_TRIANGLES); glBegin(GL_TRIANGLES);
glDepthRange(0.0+g_zbias, 1.0); glDepthRange(0.0+g_zbias, 1.0);
for(int i = 0; i < m->ni; i += 3) { for(int i = 0; i < m->ni; i += 3) {
glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]);
glVertex3fv(&m->pVertex[3*m->pIndex[i]]); glVertex3fv(&m->pVertex[3*m->pIndex[i]]);
glVertex3fv(&m->pVertex[3*m->pIndex[i+1]]);
glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]); glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]);
} }
glEnd(); glEnd();
@ -157,14 +160,14 @@ static void render_coll_mesh(const CollMesh* m) {
float foo[512][512]; float foo[512][512];
float aspectRatio = 1.0; float aspectRatio = 1.0;
float camera_zoom = 1.0; float camera_zoom = 1.0;
static void raytraceCollMesh(vector3f camPos, vector3f camera_up, vector3f camera_forward, GeomTree* geomtree) { static void raytraceCollMesh(vector3d camPos, vector3d camera_up, vector3d camera_forward, CollisionSpace* space) {
memset(foo, 0, sizeof(float)*512*512); memset(foo, 0, sizeof(float)*512*512);
vector3f toPoint, xMov, yMov; vector3d toPoint, xMov, yMov;
vector3f topLeft, topRight, botRight, cross; vector3d topLeft, topRight, botRight, cross;
topLeft = topRight = botRight = camera_forward + camera_zoom; topLeft = topRight = botRight = camera_forward + camera_zoom;
cross = vector3f::Cross (camera_forward, camera_up) * aspectRatio; cross = vector3d::Cross (camera_forward, camera_up) * aspectRatio;
topLeft = topLeft + camera_up - cross; topLeft = topLeft + camera_up - cross;
topRight = topRight + camera_up + cross; topRight = topRight + camera_up + cross;
botRight = botRight - camera_up + cross; botRight = botRight - camera_up + cross;
@ -185,7 +188,7 @@ static void raytraceCollMesh(vector3f camPos, vector3f camera_up, vector3f camer
toPoint *= 10000; toPoint *= 10000;
isect_t isect; isect_t isect;
geomtree->TraceRay(camPos, toPoint, &isect); space->TraceRay(camPos, toPoint, &isect);
if(isect.triIdx != -1) { if(isect.triIdx != -1) {
foo[x][y] = 10.0/isect.dist; foo[x][y] = 10.0/isect.dist;
@ -213,17 +216,19 @@ static void raytraceCollMesh(vector3f camPos, vector3f camera_up, vector3f camer
glBindTexture(GL_TEXTURE_2D, mytexture); glBindTexture(GL_TEXTURE_2D, mytexture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glTexCoord2i(1,1);
glVertex3f(1,1,0);
glTexCoord2i(0,1); glTexCoord2i(0,1);
glVertex3f(0,1,0); glVertex3f(1,1,0);
glTexCoord2i(0,0); glTexCoord2i(0,0);
glVertex3f(0,0,0); glVertex3f(0,1,0);
glTexCoord2i(1,0); glTexCoord2i(1,0);
glVertex3f(0,0,0);
glTexCoord2i(1,1);
glVertex3f(1,0,0); glVertex3f(1,0,0);
glEnd(); glEnd();
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
printf("done..\n");
} }
void Viewer::MainLoop(void) { void Viewer::MainLoop(void) {
@ -234,9 +239,18 @@ void Viewer::MainLoop(void) {
CollMesh* cmesh = (CollMesh*)calloc(1, sizeof(CollMesh)); CollMesh* cmesh = (CollMesh*)calloc(1, sizeof(CollMesh));
sbreGenCollMesh(cmesh, g_model, &params, 1.0f); sbreGenCollMesh(cmesh, g_model, &params, 1.0f);
/* TODO: Flip Z & X because sbre is in magicspace. */
for(int i = 0; i < 3*cmesh->nv; i+=3) {
cmesh->pVertex[i] = -cmesh->pVertex[i];
cmesh->pVertex[i+2] = -cmesh->pVertex[i+2];
}
Uint32 t= SDL_GetTicks(); Uint32 t= SDL_GetTicks();
GeomTree* geomtree = new GeomTree(cmesh->ni/3, cmesh->pVertex, cmesh->pIndex); GeomTree* geomtree = new GeomTree(cmesh->ni/3, cmesh->pVertex, cmesh->pIndex);
printf("Geom tree build in $dms\n", SDL_GetTicks() -t); printf("Geom tree build in $dms\n", SDL_GetTicks() -t);
Geom* geom = new Geom(geomtree);
CollisionSpace* space = new CollisionSpace();
space->AddGeom(geom);
for(;;) { for(;;) {
PollEvents(); PollEvents();
@ -248,8 +262,8 @@ void Viewer::MainLoop(void) {
if(g_keyState[SDLK_EQUALS]) distance *= pow(0.5, g_frameTime); if(g_keyState[SDLK_EQUALS]) distance *= pow(0.5, g_frameTime);
if(g_keyState[SDLK_MINUS]) distance *= pow(2.0, g_frameTime); if(g_keyState[SDLK_MINUS]) distance *= pow(2.0, g_frameTime);
if(g_mouseButton[1] || g_mouseButton[3]) { if(g_mouseButton[1] || g_mouseButton[3]) {
float rx = 0.01*g_mouseMotion[1]; float rx = -0.01*g_mouseMotion[1];
float ry = 0.01*g_mouseMotion[0]; float ry = -0.01*g_mouseMotion[0];
rot = matrix4x4d::RotateXMatrix(rx) * rot; rot = matrix4x4d::RotateXMatrix(rx) * rot;
rot = matrix4x4d::RotateYMatrix(ry) * rot; rot = matrix4x4d::RotateYMatrix(ry) * rot;
} }
@ -263,37 +277,34 @@ void Viewer::MainLoop(void) {
glClearColor(0,0,0,0); glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_ALL_ATTRIB_BITS); if(g_renderType == 0) {
if(!g_renderCollMesh) { glPushAttrib(GL_ALL_ATTRIB_BITS);
SetSbreParams(); SetSbreParams();
sbreSetViewport(g_width, g_height, g_width*0.5, 1.0f, 10000.0f, 0.0f, 1.0f); sbreSetViewport(g_width, g_height, g_width*0.5, 1.0f, 10000.0f, 0.0f, 1.0f);
sbreSetDirLight(lightCol, lightDir); sbreSetDirLight(lightCol, lightDir);
Matrix m; Matrix m;
Vector p; Vector p;
m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = rot[ 8]; m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = -rot[8];
m.y1 = rot[1]; m.y2 = rot[5]; m.y3 = rot[ 9]; m.y1 = rot[1]; m.y2 = rot[5]; m.y3 = -rot[9];
m.z1 = rot[2]; m.z2 = rot[6]; m.z3 = rot[10]; m.z1 = -rot[2]; m.z2 = -rot[6]; m.z3 = rot[10];
p.x = 0; p.y = 0; p.z = distance; p.x = 0; p.y = 0; p.z = distance;
if(g_renderCollMesh) { sbreRenderModel(&p, &m, g_model, &params);
glPopAttrib();
} else if(g_renderType == 1) {
glPushMatrix(); glPushMatrix();
glTranslatef(p.x, p.y, p.z); glTranslatef(0, 0, -distance);
glMultMatrixd(&rot[0]); glMultMatrixd(&rot[0]);
render_coll_mesh(cmesh); render_coll_mesh(cmesh);
glPopMatrix(); glPopMatrix();
//sbreRenderCollMesh(cmesh, &p, &m); //sbreRenderCollMesh(cmesh, &p, &m);
}
else sbreRenderModel(&p, &m, g_model, &params);
} else { } else {
vector3d _p = rot * vector3d(0,0,-distance); geom->SetOrientation(rot);
vector3f camPos(_p.x, _p.y, _p.z); vector3d camPos = vector3d(0, 0, distance);
vector3f forward = -vector3f::Normalize(camPos); vector3d forward = vector3d(0,0,-1);
vector3f up = vector3f::Cross(vector3f(0,1,0), forward); vector3d up = vector3d(0, 1, 0);
up.Normalize(); raytraceCollMesh(camPos, up, forward, space);
raytraceCollMesh(camPos, up, forward, geomtree);
} }
glPopAttrib();
Gui::Draw(); Gui::Draw();

View File

@ -12,7 +12,8 @@ public:
vector3(const double vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) { } vector3(const double vals[3]): x(vals[0]), y(vals[1]), z(vals[2]) { }
vector3(const float vals[3]) : x(vals[0]), y(vals[1]), z(vals[2]) { } vector3(const float vals[3]) : x(vals[0]), y(vals[1]), z(vals[2]) { }
T& operator[] (const int i) { return ((T*)this)[i]; } const T& operator[] (const size_t i) const { return ((const T*)this)[i]; }
T& operator[] (const size_t i) { return ((T*)this)[i]; }
vector3 operator+ (const vector3 a) const { return vector3 (a.x+x, a.y+y, a.z+z); } vector3 operator+ (const vector3 a) const { return vector3 (a.x+x, a.y+y, a.z+z); }
vector3& operator+= (const vector3 a) { x+=a.x; y+=a.y; z+=a.z; return *this; } vector3& operator+= (const vector3 a) { x+=a.x; y+=a.y; z+=a.z; return *this; }
vector3& operator-= (const vector3 a) { x-=a.x; y-=a.y; z-=a.z; return *this; } vector3& operator-= (const vector3 a) { x-=a.x; y-=a.y; z-=a.z; return *this; }