[Add] Initial non-accelerating collision space.
This commit is contained in:
parent
e644c15e07
commit
5b1a10b70b
@ -1,5 +1,5 @@
|
||||
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
|
||||
|
||||
|
29
src/collider/collision_space.cpp
Normal file
29
src/collider/collision_space.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
src/collider/collision_space.h
Normal file
17
src/collider/collision_space.h
Normal 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
29
src/collider/geom.cpp
Normal 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
22
src/collider/geom.h
Normal 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;
|
||||
};
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "../aabb.h"
|
||||
#include "geom_tree.h"
|
||||
|
||||
#define DEBUG
|
||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
|
||||
@ -38,8 +37,6 @@ public:
|
||||
SetList(tri);
|
||||
}
|
||||
|
||||
float FindNiceSplitPos(int splitAxis, int* numPoints, int* numPrims);
|
||||
void Dump(int depth, Aabb& box);
|
||||
void SetAxis(int axis) { m_axis = axis; }
|
||||
int GetAxis(void) const { return m_axis; }
|
||||
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);
|
||||
}
|
||||
|
||||
#define SIGN_OF(f) (*((unsigned int*)(&f)) >> 31)
|
||||
|
||||
void GeomTree::TraceRay(vector3f& start, vector3f& dir, isect_t* isect) {
|
||||
float len = dir.Length();
|
||||
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;
|
||||
vector3f rcpD = vector3f(1.0f/a_dir.x, 1.0f/a_dir.y, 1.0f/a_dir.z);
|
||||
int Dneg[3];
|
||||
#ifdef DEBUG
|
||||
int num_raytri_tests = 0;
|
||||
#endif
|
||||
|
||||
Dneg[0] = (a_dir.x < 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. */
|
||||
while(currnode) {
|
||||
while (!currnode->IsLeaf()) {
|
||||
#ifdef DEBUG
|
||||
//m_stats.treeNodeTraversals++;
|
||||
#endif
|
||||
const int axis = currnode->GetAxis();
|
||||
|
||||
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. */
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,8 @@ public:
|
||||
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) {
|
||||
matrix4x4 m;
|
||||
for(int i = 0; i < 16; i++) m.cell[i] = a.cell[i] + b.cell[i];
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "glfreetype.h"
|
||||
#include "gui.h"
|
||||
#include "collider/geom_tree.h"
|
||||
#include "collider/collision_space.h"
|
||||
#include "collider/geom.h"
|
||||
|
||||
static SDL_Surface* g_screen;
|
||||
static int g_width, g_height;
|
||||
@ -53,7 +55,7 @@ static void PollEvents(void) {
|
||||
|
||||
static int g_wheelMoveDir = -1;
|
||||
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 lightDir[4] = { 0, 1, 0, 0 };
|
||||
static float g_frameTime;
|
||||
@ -100,11 +102,11 @@ public:
|
||||
Gui::Screen::AddBaseWidget(this, 0, 0);
|
||||
SetTransparency(true);
|
||||
{
|
||||
Gui::ToggleButton* b = new Gui::ToggleButton();
|
||||
Gui::Button* b = new Gui::SolidButton();
|
||||
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(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();
|
||||
@ -123,8 +125,9 @@ public:
|
||||
else g_wheelMoveDir = -1;
|
||||
}
|
||||
|
||||
void OnToggleCollMesh(Gui::ToggleButton* b, bool state) {
|
||||
g_renderCollMesh = state;
|
||||
void OnClickChangeView(void) {
|
||||
g_renderType++;
|
||||
if(g_renderType > 2) g_renderType = 0;
|
||||
}
|
||||
|
||||
void MainLoop();
|
||||
@ -136,8 +139,8 @@ static void render_coll_mesh(const CollMesh* m) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
glDepthRange(0.0+g_zbias, 1.0);
|
||||
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+1]]);
|
||||
glVertex3fv(&m->pVertex[3*m->pIndex[i+2]]);
|
||||
}
|
||||
glEnd();
|
||||
@ -157,14 +160,14 @@ static void render_coll_mesh(const CollMesh* m) {
|
||||
float foo[512][512];
|
||||
float aspectRatio = 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);
|
||||
|
||||
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;
|
||||
cross = vector3f::Cross (camera_forward, camera_up) * aspectRatio;
|
||||
cross = vector3d::Cross (camera_forward, camera_up) * aspectRatio;
|
||||
topLeft = topLeft + camera_up - cross;
|
||||
topRight = topRight + camera_up + cross;
|
||||
botRight = botRight - camera_up + cross;
|
||||
@ -185,7 +188,7 @@ static void raytraceCollMesh(vector3f camPos, vector3f camera_up, vector3f camer
|
||||
toPoint *= 10000;
|
||||
|
||||
isect_t isect;
|
||||
geomtree->TraceRay(camPos, toPoint, &isect);
|
||||
space->TraceRay(camPos, toPoint, &isect);
|
||||
|
||||
if(isect.triIdx != -1) {
|
||||
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);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2i(1,1);
|
||||
glVertex3f(1,1,0);
|
||||
glTexCoord2i(0,1);
|
||||
glVertex3f(0,1,0);
|
||||
glVertex3f(1,1,0);
|
||||
|
||||
glTexCoord2i(0,0);
|
||||
glVertex3f(0,0,0);
|
||||
glVertex3f(0,1,0);
|
||||
|
||||
glTexCoord2i(1,0);
|
||||
glVertex3f(0,0,0);
|
||||
|
||||
glTexCoord2i(1,1);
|
||||
glVertex3f(1,0,0);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
printf("done..\n");
|
||||
}
|
||||
|
||||
void Viewer::MainLoop(void) {
|
||||
@ -234,9 +239,18 @@ void Viewer::MainLoop(void) {
|
||||
CollMesh* cmesh = (CollMesh*)calloc(1, sizeof(CollMesh));
|
||||
sbreGenCollMesh(cmesh, g_model, ¶ms, 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();
|
||||
GeomTree* geomtree = new GeomTree(cmesh->ni/3, cmesh->pVertex, cmesh->pIndex);
|
||||
printf("Geom tree build in $dms\n", SDL_GetTicks() -t);
|
||||
Geom* geom = new Geom(geomtree);
|
||||
CollisionSpace* space = new CollisionSpace();
|
||||
space->AddGeom(geom);
|
||||
|
||||
for(;;) {
|
||||
PollEvents();
|
||||
@ -248,8 +262,8 @@ void Viewer::MainLoop(void) {
|
||||
if(g_keyState[SDLK_EQUALS]) distance *= pow(0.5, g_frameTime);
|
||||
if(g_keyState[SDLK_MINUS]) distance *= pow(2.0, g_frameTime);
|
||||
if(g_mouseButton[1] || g_mouseButton[3]) {
|
||||
float rx = 0.01*g_mouseMotion[1];
|
||||
float ry = 0.01*g_mouseMotion[0];
|
||||
float rx = -0.01*g_mouseMotion[1];
|
||||
float ry = -0.01*g_mouseMotion[0];
|
||||
rot = matrix4x4d::RotateXMatrix(rx) * rot;
|
||||
rot = matrix4x4d::RotateYMatrix(ry) * rot;
|
||||
}
|
||||
@ -263,37 +277,34 @@ void Viewer::MainLoop(void) {
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
if(!g_renderCollMesh) {
|
||||
SetSbreParams();
|
||||
sbreSetViewport(g_width, g_height, g_width*0.5, 1.0f, 10000.0f, 0.0f, 1.0f);
|
||||
sbreSetDirLight(lightCol, lightDir);
|
||||
if(g_renderType == 0) {
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
SetSbreParams();
|
||||
sbreSetViewport(g_width, g_height, g_width*0.5, 1.0f, 10000.0f, 0.0f, 1.0f);
|
||||
sbreSetDirLight(lightCol, lightDir);
|
||||
|
||||
Matrix m;
|
||||
Vector p;
|
||||
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.z1 = rot[2]; m.z2 = rot[6]; m.z3 = rot[10];
|
||||
p.x = 0; p.y = 0; p.z = distance;
|
||||
if(g_renderCollMesh) {
|
||||
Matrix m;
|
||||
Vector p;
|
||||
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.z1 = -rot[2]; m.z2 = -rot[6]; m.z3 = rot[10];
|
||||
p.x = 0; p.y = 0; p.z = distance;
|
||||
sbreRenderModel(&p, &m, g_model, ¶ms);
|
||||
glPopAttrib();
|
||||
} else if(g_renderType == 1) {
|
||||
glPushMatrix();
|
||||
glTranslatef(p.x, p.y, p.z);
|
||||
glTranslatef(0, 0, -distance);
|
||||
glMultMatrixd(&rot[0]);
|
||||
render_coll_mesh(cmesh);
|
||||
glPopMatrix();
|
||||
//sbreRenderCollMesh(cmesh, &p, &m);
|
||||
}
|
||||
else sbreRenderModel(&p, &m, g_model, ¶ms);
|
||||
|
||||
} else {
|
||||
vector3d _p = rot * vector3d(0,0,-distance);
|
||||
vector3f camPos(_p.x, _p.y, _p.z);
|
||||
vector3f forward = -vector3f::Normalize(camPos);
|
||||
vector3f up = vector3f::Cross(vector3f(0,1,0), forward);
|
||||
up.Normalize();
|
||||
raytraceCollMesh(camPos, up, forward, geomtree);
|
||||
geom->SetOrientation(rot);
|
||||
vector3d camPos = vector3d(0, 0, distance);
|
||||
vector3d forward = vector3d(0,0,-1);
|
||||
vector3d up = vector3d(0, 1, 0);
|
||||
raytraceCollMesh(camPos, up, forward, space);
|
||||
}
|
||||
glPopAttrib();
|
||||
|
||||
Gui::Draw();
|
||||
|
||||
|
@ -12,7 +12,8 @@ public:
|
||||
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]) { }
|
||||
|
||||
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) { 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; }
|
||||
|
Loading…
Reference in New Issue
Block a user