Compare commits
10 commits
5dc3e727e0
...
09d8936f0e
Author | SHA1 | Date | |
---|---|---|---|
09d8936f0e | |||
![]() |
05bc72eeb3 | ||
![]() |
a30ae7d0fb | ||
![]() |
2aa2097b6c | ||
![]() |
648ce1d454 | ||
![]() |
9d152e2773 | ||
![]() |
cc2a07f13d | ||
![]() |
853d3978c5 | ||
![]() |
c85a39bb0f | ||
![]() |
f945e21bbd |
10 changed files with 217 additions and 89 deletions
|
@ -9,10 +9,11 @@ IF (NOT OPENGL_FOUND)
|
||||||
MESSAGE(FATAL_ERROR "Could not find OpenGL")
|
MESSAGE(FATAL_ERROR "Could not find OpenGL")
|
||||||
ENDIF (NOT OPENGL_FOUND)
|
ENDIF (NOT OPENGL_FOUND)
|
||||||
|
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
find_package(GLPng REQUIRED)
|
find_package(GLPng REQUIRED)
|
||||||
find_package(LibXml2 REQUIRED)
|
find_package(LibXml2 REQUIRED)
|
||||||
|
|
||||||
include_directories(${Boost_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLPNG_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
|
include_directories(${Boost_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLPNG_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH} ${X11_Xi_INCLUDE_PATH})
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -14,4 +14,4 @@ add_executable(zoom
|
||||||
TriangleRecord.h
|
TriangleRecord.h
|
||||||
zoom.cpp
|
zoom.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(zoom ${Boost_LIBRARIES} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY} ${GLPNG_LIBRARY} ${LIBXML2_LIBRARIES})
|
target_link_libraries(zoom ${Boost_LIBRARIES} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY} ${GLPNG_LIBRARY} ${LIBXML2_LIBRARIES} ${X11_LIBRARIES} ${X11_Xi_LIB})
|
||||||
|
|
|
@ -18,36 +18,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Collision.h"
|
#include "Collision.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace Zoom {
|
namespace Zoom {
|
||||||
|
|
||||||
vmml::vec3f Collision::projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2) {
|
|
||||||
vmml::vec3f pVec = p - v1;
|
|
||||||
vmml::vec3f edge = v2 - v1;
|
|
||||||
|
|
||||||
float lengthSq = edge.squared_length();
|
|
||||||
float edgeProj = vmml::dot(edge, pVec);
|
|
||||||
|
|
||||||
if(edgeProj < 0) return v1;
|
|
||||||
if(edgeProj > lengthSq) return v2;
|
|
||||||
|
|
||||||
return v1 + (edgeProj/lengthSq)*edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
vmml::vec3f Collision::projectToNearestEdge(const vmml::vec3f& p, const Triangle &t) {
|
|
||||||
vmml::vec3f p1 = projectToEdge(p, t.getVertex(0), t.getVertex(1));
|
|
||||||
vmml::vec3f p2 = projectToEdge(p, t.getVertex(1), t.getVertex(2));
|
|
||||||
vmml::vec3f p3 = projectToEdge(p, t.getVertex(2), t.getVertex(0));
|
|
||||||
|
|
||||||
if(p.squared_distance(p1) < p.squared_distance(p2) && p.squared_distance(p1) < p.squared_distance(p3))
|
|
||||||
return p1;
|
|
||||||
else if(p.squared_distance(p2) < p.squared_distance(p3))
|
|
||||||
return p2;
|
|
||||||
else
|
|
||||||
return p3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Collision::test(const Triangle &t, const MathUtil::Ray &ray, float *distance) {
|
bool Collision::test(const Triangle &t, const MathUtil::Ray &ray, float *distance) {
|
||||||
vmml::vec3f edge1 = t.getVertex(1) - t.getVertex(0);
|
vmml::vec3f edge1 = t.getVertex(1) - t.getVertex(0);
|
||||||
vmml::vec3f edge2 = t.getVertex(2) - t.getVertex(0);
|
vmml::vec3f edge2 = t.getVertex(2) - t.getVertex(0);
|
||||||
|
@ -75,23 +50,157 @@ bool Collision::test(const Triangle &t, const MathUtil::Ray &ray, float *distanc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move) {
|
vmml::vec3f Collision::projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2) {
|
||||||
float distance;
|
vmml::vec3f pVec = p - v1;
|
||||||
|
vmml::vec3f edge = v2 - v1;
|
||||||
|
|
||||||
|
float lengthSq = edge.squared_length();
|
||||||
|
float edgeProj = vmml::dot(edge, pVec);
|
||||||
|
|
||||||
|
if(edgeProj < 0) return v1;
|
||||||
|
if(edgeProj > lengthSq) return v2;
|
||||||
|
|
||||||
|
return v1 + (edgeProj/lengthSq)*edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Collision::testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
||||||
|
vmml::vec3f edge = v2 - v1;
|
||||||
|
|
||||||
|
vmml::vec3f avec = vmml::dot(edge, move)*edge / edge.squared_length() - move;
|
||||||
|
vmml::vec3f cvec = v1 + vmml::dot(edge, m-v1)*edge / edge.squared_length() - m;
|
||||||
|
|
||||||
|
float a = avec.squared_length();
|
||||||
|
float b_2 = vmml::dot(avec, cvec);
|
||||||
|
float c = cvec.squared_length() - r*r;
|
||||||
|
|
||||||
|
float rootSq = b_2*b_2 - a*c;
|
||||||
|
if(rootSq < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float minRoot = -a - b_2;
|
||||||
|
float maxRoot = a*MathUtil::EPSILON - b_2;
|
||||||
|
|
||||||
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
|
if(maxRoot < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(rootSq < minRoot*minRoot || rootSq >= maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
minRoot = a*(edge.dot(m - v1) - edge.squared_length())/edge.dot(move) - b_2;
|
||||||
|
maxRoot = a*edge.dot(m - v1)/edge.dot(move) - b_2;
|
||||||
|
|
||||||
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
|
if(maxRoot < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(rootSq < minRoot*minRoot || rootSq > maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*distance = -(b_2 + std::sqrt(rootSq))/a;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Collision::testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
||||||
|
float a = move.squared_length();
|
||||||
|
float b_2 = vmml::dot(m-v, move);
|
||||||
|
float c = (m-v).squared_length() - r*r;
|
||||||
|
|
||||||
|
float rootSq = b_2*b_2 - a*c;
|
||||||
|
if(rootSq < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float minRoot = -a - b_2;
|
||||||
|
float maxRoot = a*MathUtil::EPSILON - b_2;
|
||||||
|
|
||||||
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
|
if(maxRoot < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(rootSq <= minRoot*minRoot || rootSq >= maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*distance = -(b_2 + std::sqrt(rootSq))/a;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance, vmml::vec3f *normal) {
|
||||||
|
if(move.squared_length() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float d;
|
||||||
|
|
||||||
|
vmml::vec3f triangleNormal = t.getNormal();
|
||||||
|
if(test(t, MathUtil::Ray(m - r*triangleNormal, move), &d) && d > -MathUtil::EPSILON) {
|
||||||
|
if(d < 1) {
|
||||||
|
if(distance)
|
||||||
|
*distance = d;
|
||||||
|
if(normal)
|
||||||
|
*normal = triangleNormal;
|
||||||
|
|
||||||
if(test(t, MathUtil::Ray(m - r*t.computeNormal(), move), &distance) && distance > -MathUtil::EPSILON) {
|
|
||||||
if(distance < 1)
|
|
||||||
return true;
|
return true;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmml::vec3f collisionPoint = projectToNearestEdge(m, t);
|
bool collision = false;
|
||||||
vmml::vec3f movedPoint = projectToEdge(m, collisionPoint, collisionPoint - move);
|
float minDistance;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; ++i) {
|
||||||
|
if(testEdge(t.getVertex(i), t.getVertex((i+1)%3), m, r, move, &d)) {
|
||||||
|
if(!collision || d < minDistance) {
|
||||||
|
collision = true;
|
||||||
|
minDistance = d;
|
||||||
|
|
||||||
|
if(normal) {
|
||||||
|
vmml::vec3f p = m + move*d;
|
||||||
|
|
||||||
|
*normal = (p - projectToEdge(p, t.getVertex(i), t.getVertex((i+1)%3)))/r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(collision) {
|
||||||
|
if(distance)
|
||||||
|
*distance = minDistance;
|
||||||
|
|
||||||
if(m.squared_distance(movedPoint) < r*r)
|
|
||||||
return true;
|
return true;
|
||||||
else
|
}
|
||||||
|
|
||||||
|
collision = false;
|
||||||
|
for(int i = 0; i < 3; ++i) {
|
||||||
|
if(testVertex(t.getVertex(i), m, r, move, &d)) {
|
||||||
|
if(!collision || d < minDistance) {
|
||||||
|
collision = true;
|
||||||
|
minDistance = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(normal) {
|
||||||
|
vmml::vec3f p = m + move*d;
|
||||||
|
|
||||||
|
*normal = (p - t.getVertex(i))/r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(collision) {
|
||||||
|
if(distance)
|
||||||
|
*distance = minDistance;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,15 @@ namespace Zoom {
|
||||||
class Collision {
|
class Collision {
|
||||||
public:
|
public:
|
||||||
static bool test(const Triangle &t, const MathUtil::Ray &ray, float *distance = 0);
|
static bool test(const Triangle &t, const MathUtil::Ray &ray, float *distance = 0);
|
||||||
static bool test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move);
|
static bool test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance = 0, vmml::vec3f *normal = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Collision();
|
Collision();
|
||||||
|
|
||||||
static vmml::vec3f projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2);
|
static vmml::vec3f projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2);
|
||||||
static vmml::vec3f projectToNearestEdge(const vmml::vec3f& p, const Triangle &t);
|
|
||||||
|
static bool testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance);
|
||||||
|
static bool testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
46
src/Game.cpp
46
src/Game.cpp
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
namespace Zoom {
|
namespace Zoom {
|
||||||
|
|
||||||
const float Game::PLAYER_SPEED = 10;
|
const float Game::PLAYER_SPEED = 3;
|
||||||
const float Game::PLAYER_RADIUS = 0.3;
|
const float Game::PLAYER_RADIUS = 0.3;
|
||||||
|
|
||||||
Game::Game() : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0),
|
Game::Game() : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0),
|
||||||
|
@ -131,36 +131,37 @@ void Game::run(int delta) {
|
||||||
|
|
||||||
vmml::vec3f origMove = playerMove;
|
vmml::vec3f origMove = playerMove;
|
||||||
|
|
||||||
bool ok = false;
|
bool collision = true;
|
||||||
|
|
||||||
while(!ok) {
|
while(collision) {
|
||||||
ok = true;
|
collision = false;
|
||||||
|
|
||||||
MathUtil::Plane nearestPlane;
|
float nearestDistance;
|
||||||
|
vmml::vec3f nearestNormal;
|
||||||
|
|
||||||
for(std::vector<TriangleRecord>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
|
for(std::vector<TriangleRecord>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
|
||||||
if(Collision::test(t->getTriangle(), playerPos, PLAYER_RADIUS, playerMove)) {
|
float distance;
|
||||||
vmml::vec3f normal = t->getTriangle().computeNormal();
|
vmml::vec3f normal;
|
||||||
MathUtil::Plane p(normal, vmml::dot(normal, t->getTriangle().getVertex(0)+PLAYER_RADIUS*normal));
|
|
||||||
if(p.isInFront(playerPos) || p.contains(playerPos)) {
|
|
||||||
if(ok || p.distance(playerPos) < nearestPlane.distance(playerPos)) {
|
|
||||||
ok = false;
|
|
||||||
|
|
||||||
nearestPlane = p;
|
if(Collision::test(t->getTriangle(), playerPos, PLAYER_RADIUS, playerMove, &distance, &normal)) {
|
||||||
}
|
normal.y() = 0;
|
||||||
|
|
||||||
|
if(normal.dot(playerMove) >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!collision || distance < nearestDistance) {
|
||||||
|
collision = true;
|
||||||
|
|
||||||
|
nearestDistance = distance;
|
||||||
|
nearestNormal = normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ok) {
|
if(collision) {
|
||||||
vmml::vec3f move;
|
vmml::vec3f move = playerMove*nearestDistance;
|
||||||
|
|
||||||
if(playerMove.dot(nearestPlane.getNormal()) == 0)
|
if(move.dot(origMove) <= 0 && move.squared_length() > 0) {
|
||||||
move = playerMove;
|
|
||||||
else
|
|
||||||
move = nearestPlane.intersection(MathUtil::Ray(playerPos, playerMove)) - playerPos;
|
|
||||||
|
|
||||||
if(move.dot(origMove) <= 0 && move.squared_length() > MathUtil::EPSILON) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +171,8 @@ void Game::run(int delta) {
|
||||||
playerPos += move;
|
playerPos += move;
|
||||||
|
|
||||||
vmml::vec3f restMove = playerMove - move;
|
vmml::vec3f restMove = playerMove - move;
|
||||||
playerMove = restMove - nearestPlane.getNormal() * (nearestPlane.getNormal().dot(restMove));
|
|
||||||
|
playerMove = restMove - nearestNormal * (nearestNormal.dot(restMove));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,13 +172,13 @@ TriangleRecord Level::loadWall(xmlNodePtr wallNode) {
|
||||||
if(++vertexNum > 2)
|
if(++vertexNum > 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
wall.getTriangle().setVertex(vertexNum, loadVector(node));
|
wall.getTriangle().setVertex(vertexNum, loadVector(node), false);
|
||||||
}
|
}
|
||||||
else if(!xmlStrcmp(node->name, (xmlChar*)"normal")) {
|
else if(!xmlStrcmp(node->name, (xmlChar*)"normal")) {
|
||||||
if(vertexNum < 0)
|
if(vertexNum < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wall.getTriangle().setNormal(vertexNum, loadVector(node));
|
wall.getTriangle().setVertexNormal(vertexNum, loadVector(node));
|
||||||
}
|
}
|
||||||
else if(!xmlStrcmp(node->name, (xmlChar*)"texcoords")) {
|
else if(!xmlStrcmp(node->name, (xmlChar*)"texcoords")) {
|
||||||
if(vertexNum < 0) continue;
|
if(vertexNum < 0) continue;
|
||||||
|
@ -197,18 +197,14 @@ TriangleRecord Level::loadWall(xmlNodePtr wallNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmml::vec3f normal = wall.getTriangle().computeNormal();
|
wall.getTriangle().updateNormal();
|
||||||
|
vmml::vec3f normal = wall.getTriangle().getNormal();
|
||||||
|
|
||||||
if(normal.squared_length() > 0) {
|
for(int i = 0; i < 3; ++i) {
|
||||||
normal.normalize();
|
if(wall.getTriangle().getVertexNormal(i).squared_length() == 0)
|
||||||
|
wall.getTriangle().setVertexNormal(i, normal);
|
||||||
for(int i = 0; i < 3; ++i) {
|
|
||||||
if(wall.getTriangle().getNormal(i).squared_length() == 0)
|
|
||||||
wall.getTriangle().setNormal(i, normal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return wall;
|
return wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ class MathUtil {
|
||||||
class Plane {
|
class Plane {
|
||||||
public:
|
public:
|
||||||
Plane(const vmml::vec3f &n = vmml::vec3f::ZERO, float d0 = 0) : normal(n), d(d0) {}
|
Plane(const vmml::vec3f &n = vmml::vec3f::ZERO, float d0 = 0) : normal(n), d(d0) {}
|
||||||
Plane(const Triangle &t) : normal(t.computeNormal()), d(t.getVertex(0).dot(normal)) {}
|
Plane(const Triangle &t) : normal(t.getNormal()), d(t.getVertex(0).dot(normal)) {}
|
||||||
|
|
||||||
bool contains(const vmml::vec3f &v) const {
|
bool contains(const vmml::vec3f &v) const {
|
||||||
return (fabsf(normal.dot(v) - d) < EPSILON);
|
return (fabsf(normal.dot(v) - d) < EPSILON);
|
||||||
|
|
|
@ -53,7 +53,7 @@ void Renderer::renderTriangle(const Triangle &t) {
|
||||||
|
|
||||||
for(int i = 0; i < 3; ++i) {
|
for(int i = 0; i < 3; ++i) {
|
||||||
glTexCoord2fv(t.getTexCoords(i).array);
|
glTexCoord2fv(t.getTexCoords(i).array);
|
||||||
glNormal3fv(t.getNormal(i).array);
|
glNormal3fv(t.getVertexNormal(i).array);
|
||||||
glVertex3fv(t.getVertex(i).array);
|
glVertex3fv(t.getVertex(i).array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,30 +30,44 @@ class Triangle {
|
||||||
Triangle() : color(vmml::vec4f::ONE), texture(0) {
|
Triangle() : color(vmml::vec4f::ONE), texture(0) {
|
||||||
vertices[0] = vertices[1] = vertices[2] = vmml::vec3f::ZERO;
|
vertices[0] = vertices[1] = vertices[2] = vmml::vec3f::ZERO;
|
||||||
normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
|
normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
|
||||||
|
normal = vmml::vec3f::ZERO;
|
||||||
texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
|
texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &color0) : color(color0), texture(0) {
|
Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &color0, bool update = true) : color(color0), texture(0) {
|
||||||
vertices[0] = v1;
|
vertices[0] = v1;
|
||||||
vertices[1] = v2;
|
vertices[1] = v2;
|
||||||
vertices[2] = v3;
|
vertices[2] = v3;
|
||||||
|
|
||||||
normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
|
normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
|
||||||
texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
|
texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
|
||||||
|
|
||||||
|
if(update)
|
||||||
|
updateNormal();
|
||||||
|
else
|
||||||
|
normal = vmml::vec3f::ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vmml::vec3f& getVertex(int i) const {return vertices[i];}
|
const vmml::vec3f& getVertex(int i) const {return vertices[i];}
|
||||||
vmml::vec3f& getVertex(int i) {return vertices[i];}
|
void setVertex(int i, vmml::vec3f v, bool update = true) {
|
||||||
void setVertex(int i, vmml::vec3f v) {
|
|
||||||
vertices[i] = v;
|
vertices[i] = v;
|
||||||
|
|
||||||
|
if(update)
|
||||||
|
updateNormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
const vmml::vec3f& getNormal(int i) const {return normals[i];}
|
void updateNormal() {
|
||||||
vmml::vec3f& getNormal(int i) {return normals[i];}
|
normal = vertices[0].compute_normal(vertices[1], vertices[2]);
|
||||||
void setNormal(int i, vmml::vec3f n) {
|
}
|
||||||
|
|
||||||
|
const vmml::vec3f& getVertexNormal(int i) const {return normals[i];}
|
||||||
|
vmml::vec3f& getVertexNormal(int i) {return normals[i];}
|
||||||
|
void setVertexNormal(int i, vmml::vec3f n) {
|
||||||
normals[i] = n;
|
normals[i] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vmml::vec3f& getNormal() const {return normal;}
|
||||||
|
|
||||||
const vmml::vec2f& getTexCoords(int i) const {return texcoords[i];}
|
const vmml::vec2f& getTexCoords(int i) const {return texcoords[i];}
|
||||||
vmml::vec2f& getTexCoords(int i) {return texcoords[i];}
|
vmml::vec2f& getTexCoords(int i) {return texcoords[i];}
|
||||||
void setTexCoords(int i, vmml::vec2f t) {
|
void setTexCoords(int i, vmml::vec2f t) {
|
||||||
|
@ -73,12 +87,8 @@ class Triangle {
|
||||||
color = c;
|
color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmml::vec3f computeNormal() const {
|
|
||||||
return vertices[0].compute_normal(vertices[1], vertices[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDegenerate() const {
|
bool isDegenerate() const {
|
||||||
return (computeNormal().squared_length() == 0);
|
return (normal.squared_length() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform(const vmml::mat4f &matrix) {
|
void transform(const vmml::mat4f &matrix) {
|
||||||
|
@ -94,6 +104,7 @@ class Triangle {
|
||||||
private:
|
private:
|
||||||
vmml::vec3f vertices[3];
|
vmml::vec3f vertices[3];
|
||||||
vmml::vec3f normals[3];
|
vmml::vec3f normals[3];
|
||||||
|
vmml::vec3f normal;
|
||||||
vmml::vec2f texcoords[3];
|
vmml::vec2f texcoords[3];
|
||||||
vmml::vec4f color;
|
vmml::vec4f color;
|
||||||
unsigned texture;
|
unsigned texture;
|
||||||
|
|
13
src/zoom.cpp
13
src/zoom.cpp
|
@ -26,6 +26,7 @@
|
||||||
#else
|
#else
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -233,6 +234,10 @@ bool XIInit(Display *disp, int *opcode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Bool WaitForMapNotify(Display*, XEvent *event, XPointer arg) {
|
||||||
|
return (event->type == MapNotify && event->xmap.window == (Window)arg);
|
||||||
|
}
|
||||||
|
|
||||||
bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, int *xi_opcode, int *pointer) {
|
bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, int *xi_opcode, int *pointer) {
|
||||||
static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||||
|
@ -305,7 +310,9 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, int *xi_o
|
||||||
XFreePixmap(disp, pixmap);
|
XFreePixmap(disp, pixmap);
|
||||||
|
|
||||||
XMapWindow(disp, *wnd);
|
XMapWindow(disp, *wnd);
|
||||||
XSync(disp, False);
|
|
||||||
|
XEvent event;
|
||||||
|
XIfEvent(disp, &event, WaitForMapNotify, (XPointer)*wnd);
|
||||||
|
|
||||||
XIGetClientPointer(disp, *wnd, pointer);
|
XIGetClientPointer(disp, *wnd, pointer);
|
||||||
|
|
||||||
|
@ -384,7 +391,7 @@ int main() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
switch(XKeycodeToKeysym(disp, event.xkey.keycode, 0)) {
|
switch(XkbKeycodeToKeysym(disp, event.xkey.keycode, 0, 0)) {
|
||||||
case XK_Up: case XK_w: input |= Zoom::Game::FORWARD; break;
|
case XK_Up: case XK_w: input |= Zoom::Game::FORWARD; break;
|
||||||
case XK_Down: case XK_s: input |= Zoom::Game::BACKWARD; break;
|
case XK_Down: case XK_s: input |= Zoom::Game::BACKWARD; break;
|
||||||
case XK_Left: case XK_a: input |= Zoom::Game::LEFT; break;
|
case XK_Left: case XK_a: input |= Zoom::Game::LEFT; break;
|
||||||
|
@ -394,7 +401,7 @@ int main() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
switch(XKeycodeToKeysym(disp, event.xkey.keycode, 0)) {
|
switch(XkbKeycodeToKeysym(disp, event.xkey.keycode, 0, 0)) {
|
||||||
case XK_Up: case XK_w: input &= ~Zoom::Game::FORWARD; break;
|
case XK_Up: case XK_w: input &= ~Zoom::Game::FORWARD; break;
|
||||||
case XK_Down: case XK_s: input &= ~Zoom::Game::BACKWARD; break;
|
case XK_Down: case XK_s: input &= ~Zoom::Game::BACKWARD; break;
|
||||||
case XK_Left: case XK_a: input &= ~Zoom::Game::LEFT; break;
|
case XK_Left: case XK_a: input &= ~Zoom::Game::LEFT; break;
|
||||||
|
|
Reference in a new issue