prepared to add BulletDino, and made ForkLiftDemo compile (no functionality yet)
This commit is contained in:
882
Demos/BulletDinoDemo/BulletDino.cpp
Normal file
882
Demos/BulletDinoDemo/BulletDino.cpp
Normal file
@@ -0,0 +1,882 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||||
|
|
||||||
|
/* This program is freely distributable without licensing fees
|
||||||
|
and is provided without guarantee or warrantee expressed or
|
||||||
|
implied. This program is -not- in the public domain. */
|
||||||
|
|
||||||
|
/* Example for PC game developers to show how to *combine* texturing,
|
||||||
|
reflections, and projected shadows all in real-time with OpenGL.
|
||||||
|
Robust reflections use stenciling. Robust projected shadows
|
||||||
|
use both stenciling and polygon offset. PC game programmers
|
||||||
|
should realize that neither stenciling nor polygon offset are
|
||||||
|
supported by Direct3D, so these real-time rendering algorithms
|
||||||
|
are only really viable with OpenGL.
|
||||||
|
|
||||||
|
The program has modes for disabling the stenciling and polygon
|
||||||
|
offset uses. It is worth running this example with these features
|
||||||
|
toggled off so you can see the sort of artifacts that result.
|
||||||
|
|
||||||
|
Notice that the floor texturing, reflections, and shadowing
|
||||||
|
all co-exist properly. */
|
||||||
|
|
||||||
|
/* When you run this program: Left mouse button controls the
|
||||||
|
view. Middle mouse button controls light position (left &
|
||||||
|
right rotates light around dino; up & down moves light
|
||||||
|
position up and down). Right mouse button pops up menu. */
|
||||||
|
|
||||||
|
/* Check out the comments in the "redraw" routine to see how the
|
||||||
|
reflection blending and surface stenciling is done. You can
|
||||||
|
also see in "redraw" how the projected shadows are rendered,
|
||||||
|
including the use of stenciling and polygon offset. */
|
||||||
|
|
||||||
|
/* This program is derived from glutdino.c */
|
||||||
|
|
||||||
|
/* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h> /* for cos(), sin(), and sqrt() */
|
||||||
|
#include <GL/glut.h> /* OpenGL Utility Toolkit header */
|
||||||
|
#include <GL/glext.h>
|
||||||
|
|
||||||
|
/* Some <math.h> files do not define M_PI... */
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#ifndef CALLBACK
|
||||||
|
#define CALLBACK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Variable controlling various rendering modes. */
|
||||||
|
static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1;
|
||||||
|
static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1;
|
||||||
|
static int linearFiltering = 0, useMipmaps = 0, useTexture = 1;
|
||||||
|
static int reportSpeed = 0;
|
||||||
|
static int animation = 1;
|
||||||
|
static GLboolean lightSwitch = GL_TRUE;
|
||||||
|
static int directionalLight = 1;
|
||||||
|
static int forceExtension = 0;
|
||||||
|
|
||||||
|
/* Time varying or user-controled variables. */
|
||||||
|
static float jump = 0.0;
|
||||||
|
static float lightAngle = 0.0, lightHeight = 20;
|
||||||
|
GLfloat angle = -150; /* in degrees */
|
||||||
|
GLfloat angle2 = 30; /* in degrees */
|
||||||
|
|
||||||
|
int moving, startx, starty;
|
||||||
|
int lightMoving = 0, lightStartX, lightStartY;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MISSING, EXTENSION, ONE_DOT_ONE
|
||||||
|
};
|
||||||
|
int polygonOffsetVersion;
|
||||||
|
|
||||||
|
static GLdouble bodyWidth = 3.0;
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5},
|
||||||
|
{11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16},
|
||||||
|
{8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2},
|
||||||
|
{1, 2} };
|
||||||
|
static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9},
|
||||||
|
{15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10},
|
||||||
|
{13, 9}, {11, 11}, {9, 11} };
|
||||||
|
static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0},
|
||||||
|
{12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} };
|
||||||
|
static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15},
|
||||||
|
{9.6, 15.25}, {9, 15.25} };
|
||||||
|
static GLfloat lightPosition[4];
|
||||||
|
static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */
|
||||||
|
static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/* Nice floor texture tiling pattern. */
|
||||||
|
static char *circles[] = {
|
||||||
|
"....xxxx........",
|
||||||
|
"..xxxxxxxx......",
|
||||||
|
".xxxxxxxxxx.....",
|
||||||
|
".xxx....xxx.....",
|
||||||
|
"xxx......xxx....",
|
||||||
|
"xxx......xxx....",
|
||||||
|
"xxx......xxx....",
|
||||||
|
"xxx......xxx....",
|
||||||
|
".xxx....xxx.....",
|
||||||
|
".xxxxxxxxxx.....",
|
||||||
|
"..xxxxxxxx......",
|
||||||
|
"....xxxx........",
|
||||||
|
"................",
|
||||||
|
"................",
|
||||||
|
"................",
|
||||||
|
"................",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
makeFloorTexture(void)
|
||||||
|
{
|
||||||
|
GLubyte floorTexture[16][16][3];
|
||||||
|
GLubyte *loc;
|
||||||
|
int s, t;
|
||||||
|
|
||||||
|
/* Setup RGB image for the texture. */
|
||||||
|
loc = (GLubyte*) floorTexture;
|
||||||
|
for (t = 0; t < 16; t++) {
|
||||||
|
for (s = 0; s < 16; s++) {
|
||||||
|
if (circles[t][s] == 'x') {
|
||||||
|
/* Nice green. */
|
||||||
|
loc[0] = 0x1f;
|
||||||
|
loc[1] = 0x8f;
|
||||||
|
loc[2] = 0x1f;
|
||||||
|
} else {
|
||||||
|
/* Light gray. */
|
||||||
|
loc[0] = 0xaa;
|
||||||
|
loc[1] = 0xaa;
|
||||||
|
loc[2] = 0xaa;
|
||||||
|
}
|
||||||
|
loc += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
if (useMipmaps) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
|
||||||
|
} else {
|
||||||
|
if (linearFiltering) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
X, Y, Z, W
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
A, B, C, D
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create a matrix that will project the desired shadow. */
|
||||||
|
void
|
||||||
|
shadowMatrix(GLfloat shadowMat[4][4],
|
||||||
|
GLfloat groundplane[4],
|
||||||
|
GLfloat lightpos[4])
|
||||||
|
{
|
||||||
|
GLfloat dot;
|
||||||
|
|
||||||
|
/* Find dot product between light position vector and ground plane normal. */
|
||||||
|
dot = groundplane[X] * lightpos[X] +
|
||||||
|
groundplane[Y] * lightpos[Y] +
|
||||||
|
groundplane[Z] * lightpos[Z] +
|
||||||
|
groundplane[W] * lightpos[W];
|
||||||
|
|
||||||
|
shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
|
||||||
|
shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
|
||||||
|
shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
|
||||||
|
shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
|
||||||
|
|
||||||
|
shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
|
||||||
|
shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
|
||||||
|
shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
|
||||||
|
shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
|
||||||
|
|
||||||
|
shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
|
||||||
|
shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
|
||||||
|
shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
|
||||||
|
shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
|
||||||
|
|
||||||
|
shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
|
||||||
|
shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
|
||||||
|
shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
|
||||||
|
shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the plane equation given 3 points. */
|
||||||
|
void
|
||||||
|
findPlane(GLfloat plane[4],
|
||||||
|
GLfloat v0[3], GLfloat v1[3], GLfloat v2[3])
|
||||||
|
{
|
||||||
|
GLfloat vec0[3], vec1[3];
|
||||||
|
|
||||||
|
/* Need 2 vectors to find cross product. */
|
||||||
|
vec0[X] = v1[X] - v0[X];
|
||||||
|
vec0[Y] = v1[Y] - v0[Y];
|
||||||
|
vec0[Z] = v1[Z] - v0[Z];
|
||||||
|
|
||||||
|
vec1[X] = v2[X] - v0[X];
|
||||||
|
vec1[Y] = v2[Y] - v0[Y];
|
||||||
|
vec1[Z] = v2[Z] - v0[Z];
|
||||||
|
|
||||||
|
/* find cross product to get A, B, and C of plane equation */
|
||||||
|
plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
|
||||||
|
plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]);
|
||||||
|
plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
|
||||||
|
|
||||||
|
plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
|
||||||
|
GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
|
||||||
|
{
|
||||||
|
static GLUtriangulatorObj *tobj = NULL;
|
||||||
|
GLdouble vertex[3], dx, dy, len;
|
||||||
|
int i;
|
||||||
|
int count = dataSize / (2 * sizeof(GLfloat));
|
||||||
|
|
||||||
|
if (tobj == NULL) {
|
||||||
|
tobj = gluNewTess(); /* create and initialize a GLU
|
||||||
|
polygon * * tesselation object */
|
||||||
|
gluTessCallback(tobj, (GLenum)GLU_BEGIN, (void(CALLBACK*)())glBegin);
|
||||||
|
gluTessCallback(tobj, (GLenum)GLU_VERTEX, (void(CALLBACK*)())glVertex2fv); /* semi-tricky */
|
||||||
|
gluTessCallback(tobj, (GLenum)GLU_END, (void(CALLBACK*)())glEnd);
|
||||||
|
}
|
||||||
|
glNewList(side, GL_COMPILE);
|
||||||
|
glShadeModel(GL_SMOOTH); /* smooth minimizes seeing
|
||||||
|
tessellation */
|
||||||
|
gluBeginPolygon(tobj);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
vertex[0] = data[i][0];
|
||||||
|
vertex[1] = data[i][1];
|
||||||
|
vertex[2] = 0;
|
||||||
|
gluTessVertex(tobj, vertex, data[i]);
|
||||||
|
}
|
||||||
|
gluEndPolygon(tobj);
|
||||||
|
glEndList();
|
||||||
|
glNewList(edge, GL_COMPILE);
|
||||||
|
glShadeModel(GL_FLAT); /* flat shade keeps angular hands
|
||||||
|
from being "smoothed" */
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i <= count; i++) {
|
||||||
|
/* mod function handles closing the edge */
|
||||||
|
glVertex3f(data[i % count][0], data[i % count][1], 0.0);
|
||||||
|
glVertex3f(data[i % count][0], data[i % count][1], thickness);
|
||||||
|
/* Calculate a unit normal by dividing by Euclidean
|
||||||
|
distance. We * could be lazy and use
|
||||||
|
glEnable(GL_NORMALIZE) so we could pass in * arbitrary
|
||||||
|
normals for a very slight performance hit. */
|
||||||
|
dx = data[(i + 1) % count][1] - data[i % count][1];
|
||||||
|
dy = data[i % count][0] - data[(i + 1) % count][0];
|
||||||
|
len = sqrt(dx * dx + dy * dy);
|
||||||
|
glNormal3f(dx / len, dy / len, 0.0);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
glEndList();
|
||||||
|
glNewList(whole, GL_COMPILE);
|
||||||
|
glFrontFace(GL_CW);
|
||||||
|
glCallList(edge);
|
||||||
|
glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */
|
||||||
|
glCallList(side);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(0.0, 0.0, thickness);
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */
|
||||||
|
glCallList(side);
|
||||||
|
glPopMatrix();
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enumerants for refering to display lists. */
|
||||||
|
typedef enum {
|
||||||
|
RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
|
||||||
|
LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE
|
||||||
|
} displayLists;
|
||||||
|
|
||||||
|
static void
|
||||||
|
makeDinosaur(void)
|
||||||
|
{
|
||||||
|
extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
|
||||||
|
BODY_SIDE, BODY_EDGE, BODY_WHOLE);
|
||||||
|
extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
|
||||||
|
ARM_SIDE, ARM_EDGE, ARM_WHOLE);
|
||||||
|
extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
|
||||||
|
LEG_SIDE, LEG_EDGE, LEG_WHOLE);
|
||||||
|
extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
|
||||||
|
EYE_SIDE, EYE_EDGE, EYE_WHOLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drawDinosaur(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
glPushMatrix();
|
||||||
|
/* Translate the dinosaur to be at (0,8,0). */
|
||||||
|
glTranslatef(-8, 0, -bodyWidth / 2);
|
||||||
|
glTranslatef(0.0, jump, 0.0);
|
||||||
|
glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
|
||||||
|
glCallList(BODY_WHOLE);
|
||||||
|
glTranslatef(0.0, 0.0, bodyWidth);
|
||||||
|
glCallList(ARM_WHOLE);
|
||||||
|
glCallList(LEG_WHOLE);
|
||||||
|
glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
|
||||||
|
glCallList(ARM_WHOLE);
|
||||||
|
glTranslatef(0.0, 0.0, -bodyWidth / 4);
|
||||||
|
glCallList(LEG_WHOLE);
|
||||||
|
glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
|
||||||
|
glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
|
||||||
|
glCallList(EYE_WHOLE);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLfloat floorVertices[4][3] = {
|
||||||
|
{ -20.0, 0.0, 20.0 },
|
||||||
|
{ 20.0, 0.0, 20.0 },
|
||||||
|
{ 20.0, 0.0, -20.0 },
|
||||||
|
{ -20.0, 0.0, -20.0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Draw a floor (possibly textured). */
|
||||||
|
static void
|
||||||
|
drawFloor(void)
|
||||||
|
{
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
if (useTexture) {
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(0.0, 0.0);
|
||||||
|
glVertex3fv(floorVertices[0]);
|
||||||
|
glTexCoord2f(0.0, 16.0);
|
||||||
|
glVertex3fv(floorVertices[1]);
|
||||||
|
glTexCoord2f(16.0, 16.0);
|
||||||
|
glVertex3fv(floorVertices[2]);
|
||||||
|
glTexCoord2f(16.0, 0.0);
|
||||||
|
glVertex3fv(floorVertices[3]);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
if (useTexture) {
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLfloat floorPlane[4];
|
||||||
|
static GLfloat floorShadow[4][4];
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw(void)
|
||||||
|
{
|
||||||
|
int start, end;
|
||||||
|
|
||||||
|
if (reportSpeed) {
|
||||||
|
start = glutGet(GLUT_ELAPSED_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear; default stencil clears to zero. */
|
||||||
|
if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) {
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
} else {
|
||||||
|
/* Avoid clearing stencil when not using it. */
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reposition the light source. */
|
||||||
|
lightPosition[0] = 12*cos(lightAngle);
|
||||||
|
lightPosition[1] = lightHeight;
|
||||||
|
lightPosition[2] = 12*sin(lightAngle);
|
||||||
|
if (directionalLight) {
|
||||||
|
lightPosition[3] = 0.0;
|
||||||
|
} else {
|
||||||
|
lightPosition[3] = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowMatrix(floorShadow, floorPlane, lightPosition);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
/* Perform scene rotations based on user mouse input. */
|
||||||
|
glRotatef(angle2, 1.0, 0.0, 0.0);
|
||||||
|
glRotatef(angle, 0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
/* Tell GL new light source position. */
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
|
||||||
|
|
||||||
|
if (renderReflection) {
|
||||||
|
if (stencilReflection) {
|
||||||
|
/* We can eliminate the visual "artifact" of seeing the "flipped"
|
||||||
|
dinosaur underneath the floor by using stencil. The idea is
|
||||||
|
draw the floor without color or depth update but so that
|
||||||
|
a stencil value of one is where the floor will be. Later when
|
||||||
|
rendering the dinosaur reflection, we will only update pixels
|
||||||
|
with a stencil value of 1 to make sure the reflection only
|
||||||
|
lives on the floor, not below the floor. */
|
||||||
|
|
||||||
|
/* Don't update color or depth. */
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
|
/* Draw 1 into the stencil buffer. */
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||||
|
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
|
||||||
|
|
||||||
|
/* Now render floor; floor pixels just get their stencil set to 1. */
|
||||||
|
drawFloor();
|
||||||
|
|
||||||
|
/* Re-enable update of color and depth. */
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
/* Now, only render where stencil is set to 1. */
|
||||||
|
glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
|
||||||
|
/* The critical reflection step: Reflect dinosaur through the floor
|
||||||
|
(the Y=0 plane) to make a relection. */
|
||||||
|
glScalef(1.0, -1.0, 1.0);
|
||||||
|
|
||||||
|
/* Reflect the light position. */
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
|
||||||
|
|
||||||
|
/* To avoid our normals getting reversed and hence botched lighting
|
||||||
|
on the reflection, turn on normalize. */
|
||||||
|
glEnable(GL_NORMALIZE);
|
||||||
|
glCullFace(GL_FRONT);
|
||||||
|
|
||||||
|
/* Draw the reflected dinosaur. */
|
||||||
|
drawDinosaur();
|
||||||
|
|
||||||
|
/* Disable noramlize again and re-enable back face culling. */
|
||||||
|
glDisable(GL_NORMALIZE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
/* Switch back to the unreflected light position. */
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
|
||||||
|
|
||||||
|
if (stencilReflection) {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Back face culling will get used to only draw either the top or the
|
||||||
|
bottom floor. This let's us get a floor with two distinct
|
||||||
|
appearances. The top floor surface is reflective and kind of red.
|
||||||
|
The bottom floor surface is not reflective and blue. */
|
||||||
|
|
||||||
|
/* Draw "bottom" of floor in blue. */
|
||||||
|
glFrontFace(GL_CW); /* Switch face orientation. */
|
||||||
|
glColor4f(0.1, 0.1, 0.7, 1.0);
|
||||||
|
drawFloor();
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
|
||||||
|
if (renderShadow) {
|
||||||
|
if (stencilShadow) {
|
||||||
|
/* Draw the floor with stencil value 3. This helps us only
|
||||||
|
draw the shadow once per floor pixel (and only on the
|
||||||
|
floor pixels). */
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(GL_ALWAYS, 3, 0xffffffff);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw "top" of floor. Use blending to blend in reflection. */
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glColor4f(0.7, 0.0, 0.0, 0.3);
|
||||||
|
glColor4f(1.0, 1.0, 1.0, 0.3);
|
||||||
|
drawFloor();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
if (renderDinosaur) {
|
||||||
|
/* Draw "actual" dinosaur, not its reflection. */
|
||||||
|
drawDinosaur();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderShadow) {
|
||||||
|
|
||||||
|
/* Render the projected shadow. */
|
||||||
|
|
||||||
|
if (stencilShadow) {
|
||||||
|
|
||||||
|
/* Now, only render where stencil is set above 2 (ie, 3 where
|
||||||
|
the top floor is). Update stencil with 2 where the shadow
|
||||||
|
gets drawn so we don't redraw (and accidently reblend) the
|
||||||
|
shadow). */
|
||||||
|
glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */
|
||||||
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To eliminate depth buffer artifacts, we use polygon offset
|
||||||
|
to raise the depth of the projected shadow slightly so
|
||||||
|
that it does not depth buffer alias with the floor. */
|
||||||
|
if (offsetShadow) {
|
||||||
|
switch (polygonOffsetVersion) {
|
||||||
|
case EXTENSION:
|
||||||
|
#ifdef GL_VERSION_1_1
|
||||||
|
case ONE_DOT_ONE:
|
||||||
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case MISSING:
|
||||||
|
/* Oh well. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render 50% black shadow color on top of whatever the
|
||||||
|
floor appareance is. */
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDisable(GL_LIGHTING); /* Force the 50% black. */
|
||||||
|
glColor4f(0.0, 0.0, 0.0, 0.5);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
/* Project the shadow. */
|
||||||
|
glMultMatrixf((GLfloat *) floorShadow);
|
||||||
|
drawDinosaur();
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
if (offsetShadow) {
|
||||||
|
switch (polygonOffsetVersion) {
|
||||||
|
#ifdef GL_VERSION_1_1
|
||||||
|
case ONE_DOT_ONE:
|
||||||
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case MISSING:
|
||||||
|
/* Oh well. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stencilShadow) {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glColor3f(1.0, 1.0, 0.0);
|
||||||
|
if (directionalLight) {
|
||||||
|
/* Draw an arrowhead. */
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
|
||||||
|
glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0);
|
||||||
|
glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1);
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
|
glVertex3f(0, 0, 0);
|
||||||
|
glVertex3f(2, 1, 1);
|
||||||
|
glVertex3f(2, -1, 1);
|
||||||
|
glVertex3f(2, -1, -1);
|
||||||
|
glVertex3f(2, 1, -1);
|
||||||
|
glVertex3f(2, 1, 1);
|
||||||
|
glEnd();
|
||||||
|
/* Draw a white line from light direction. */
|
||||||
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3f(0, 0, 0);
|
||||||
|
glVertex3f(5, 0, 0);
|
||||||
|
glEnd();
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
} else {
|
||||||
|
/* Draw a yellow ball at the light source. */
|
||||||
|
glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
|
||||||
|
glutSolidSphere(1.0, 5, 5);
|
||||||
|
}
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
if (reportSpeed) {
|
||||||
|
glFinish();
|
||||||
|
end = glutGet(GLUT_ELAPSED_TIME);
|
||||||
|
printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
glutSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED2 */
|
||||||
|
static void
|
||||||
|
mouse(int button, int state, int x, int y)
|
||||||
|
{
|
||||||
|
if (button == GLUT_LEFT_BUTTON) {
|
||||||
|
if (state == GLUT_DOWN) {
|
||||||
|
moving = 1;
|
||||||
|
startx = x;
|
||||||
|
starty = y;
|
||||||
|
}
|
||||||
|
if (state == GLUT_UP) {
|
||||||
|
moving = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (button == GLUT_MIDDLE_BUTTON) {
|
||||||
|
if (state == GLUT_DOWN) {
|
||||||
|
lightMoving = 1;
|
||||||
|
lightStartX = x;
|
||||||
|
lightStartY = y;
|
||||||
|
}
|
||||||
|
if (state == GLUT_UP) {
|
||||||
|
lightMoving = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED1 */
|
||||||
|
static void
|
||||||
|
motion(int x, int y)
|
||||||
|
{
|
||||||
|
if (moving) {
|
||||||
|
angle = angle + (x - startx);
|
||||||
|
angle2 = angle2 + (y - starty);
|
||||||
|
startx = x;
|
||||||
|
starty = y;
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
if (lightMoving) {
|
||||||
|
lightAngle += (x - lightStartX)/40.0;
|
||||||
|
lightHeight += (lightStartY - y)/20.0;
|
||||||
|
lightStartX = x;
|
||||||
|
lightStartY = y;
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance time varying state when idle callback registered. */
|
||||||
|
static void
|
||||||
|
idle(void)
|
||||||
|
{
|
||||||
|
static float time = 0.0;
|
||||||
|
|
||||||
|
time = glutGet(GLUT_ELAPSED_TIME) / 500.0;
|
||||||
|
|
||||||
|
jump = 4.0 * fabs(sin(time)*0.5);
|
||||||
|
if (!lightMoving) {
|
||||||
|
lightAngle += 0.03;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR,
|
||||||
|
M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW,
|
||||||
|
M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
controlLights(int value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case M_NONE:
|
||||||
|
return;
|
||||||
|
case M_MOTION:
|
||||||
|
animation = 1 - animation;
|
||||||
|
if (animation) {
|
||||||
|
glutIdleFunc(idle);
|
||||||
|
} else {
|
||||||
|
glutIdleFunc(NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case M_LIGHT:
|
||||||
|
lightSwitch = !lightSwitch;
|
||||||
|
if (lightSwitch) {
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_LIGHT0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case M_TEXTURE:
|
||||||
|
useTexture = !useTexture;
|
||||||
|
break;
|
||||||
|
case M_SHADOWS:
|
||||||
|
renderShadow = 1 - renderShadow;
|
||||||
|
break;
|
||||||
|
case M_REFLECTION:
|
||||||
|
renderReflection = 1 - renderReflection;
|
||||||
|
break;
|
||||||
|
case M_DINOSAUR:
|
||||||
|
renderDinosaur = 1 - renderDinosaur;
|
||||||
|
break;
|
||||||
|
case M_STENCIL_REFLECTION:
|
||||||
|
stencilReflection = 1 - stencilReflection;
|
||||||
|
break;
|
||||||
|
case M_STENCIL_SHADOW:
|
||||||
|
stencilShadow = 1 - stencilShadow;
|
||||||
|
break;
|
||||||
|
case M_OFFSET_SHADOW:
|
||||||
|
offsetShadow = 1 - offsetShadow;
|
||||||
|
break;
|
||||||
|
case M_POSITIONAL:
|
||||||
|
directionalLight = 0;
|
||||||
|
break;
|
||||||
|
case M_DIRECTIONAL:
|
||||||
|
directionalLight = 1;
|
||||||
|
break;
|
||||||
|
case M_PERFORMANCE:
|
||||||
|
reportSpeed = 1 - reportSpeed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When not visible, stop animating. Restart when visible again. */
|
||||||
|
static void
|
||||||
|
visible(int vis)
|
||||||
|
{
|
||||||
|
if (vis == GLUT_VISIBLE) {
|
||||||
|
if (animation)
|
||||||
|
glutIdleFunc(idle);
|
||||||
|
} else {
|
||||||
|
if (!animation)
|
||||||
|
glutIdleFunc(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Press any key to redraw; good when motion stopped and
|
||||||
|
performance reporting on. */
|
||||||
|
/* ARGSUSED */
|
||||||
|
static void
|
||||||
|
key(unsigned char c, int x, int y)
|
||||||
|
{
|
||||||
|
if (c == 27) {
|
||||||
|
exit(0); /* IRIS GLism, Escape quits. */
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Press any key to redraw; good when motion stopped and
|
||||||
|
performance reporting on. */
|
||||||
|
/* ARGSUSED */
|
||||||
|
static void
|
||||||
|
special(int k, int x, int y)
|
||||||
|
{
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
supportsOneDotOne(void)
|
||||||
|
{
|
||||||
|
const char *version;
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
version = (char *) glGetString(GL_VERSION);
|
||||||
|
if (sscanf(version, "%d.%d", &major, &minor) == 2)
|
||||||
|
return ((major > 1) || (major >= 1 && minor >= 1));
|
||||||
|
return 0; /* OpenGL version string malformed! */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
glutInit(&argc, argv);
|
||||||
|
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
if (!strcmp("-linear", argv[i])) {
|
||||||
|
linearFiltering = 1;
|
||||||
|
} else if (!strcmp("-mipmap", argv[i])) {
|
||||||
|
useMipmaps = 1;
|
||||||
|
} else if (!strcmp("-ext", argv[i])) {
|
||||||
|
forceExtension = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* In GLUT 4.0, you'll be able to do this an be sure to
|
||||||
|
get 2 bits of stencil if the machine has it for you. */
|
||||||
|
glutInitDisplayString("samples stencil>=2 rgb double depth");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glutCreateWindow("Shadowy Leapin' Lizards");
|
||||||
|
|
||||||
|
if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) {
|
||||||
|
printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register GLUT callbacks. */
|
||||||
|
glutDisplayFunc(redraw);
|
||||||
|
glutMouseFunc(mouse);
|
||||||
|
glutMotionFunc(motion);
|
||||||
|
glutVisibilityFunc(visible);
|
||||||
|
glutKeyboardFunc(key);
|
||||||
|
glutSpecialFunc(special);
|
||||||
|
|
||||||
|
glutCreateMenu(controlLights);
|
||||||
|
|
||||||
|
glutAddMenuEntry("Toggle motion", M_MOTION);
|
||||||
|
glutAddMenuEntry("-----------------------", M_NONE);
|
||||||
|
glutAddMenuEntry("Toggle light", M_LIGHT);
|
||||||
|
glutAddMenuEntry("Toggle texture", M_TEXTURE);
|
||||||
|
glutAddMenuEntry("Toggle shadows", M_SHADOWS);
|
||||||
|
glutAddMenuEntry("Toggle reflection", M_REFLECTION);
|
||||||
|
glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR);
|
||||||
|
glutAddMenuEntry("-----------------------", M_NONE);
|
||||||
|
glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION);
|
||||||
|
glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW);
|
||||||
|
glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW);
|
||||||
|
glutAddMenuEntry("----------------------", M_NONE);
|
||||||
|
glutAddMenuEntry("Positional light", M_POSITIONAL);
|
||||||
|
glutAddMenuEntry("Directional light", M_DIRECTIONAL);
|
||||||
|
glutAddMenuEntry("-----------------------", M_NONE);
|
||||||
|
glutAddMenuEntry("Toggle performance", M_PERFORMANCE);
|
||||||
|
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||||
|
makeDinosaur();
|
||||||
|
|
||||||
|
#ifdef GL_VERSION_1_1
|
||||||
|
if (supportsOneDotOne() && !forceExtension) {
|
||||||
|
polygonOffsetVersion = ONE_DOT_ONE;
|
||||||
|
glPolygonOffset(-2.0, -1.0);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
{
|
||||||
|
polygonOffsetVersion = MISSING;
|
||||||
|
printf("\ndinoshine: Missing polygon offset.\n");
|
||||||
|
printf(" Expect shadow depth aliasing artifacts.\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glLineWidth(3.0);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
gluPerspective( /* field of view in degree */ 40.0,
|
||||||
|
/* aspect ratio */ 1.0,
|
||||||
|
/* Z near */ 20.0, /* Z far */ 100.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
gluLookAt(0.0, 8.0, 60.0, /* eye is at (0,0,30) */
|
||||||
|
0.0, 8.0, 0.0, /* center is at (0,0,0) */
|
||||||
|
0.0, 1.0, 0.); /* up is in postivie Y direction */
|
||||||
|
|
||||||
|
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
|
||||||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
|
||||||
|
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
|
||||||
|
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
makeFloorTexture();
|
||||||
|
|
||||||
|
/* Setup floor plane for projected shadow calculations. */
|
||||||
|
findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]);
|
||||||
|
|
||||||
|
glutMainLoop();
|
||||||
|
return 0; /* ANSI C requires main to return int. */
|
||||||
|
}
|
||||||
61
Demos/BulletDinoDemo/CMakeLists.txt
Normal file
61
Demos/BulletDinoDemo/CMakeLists.txt
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# This is basically the overall name of the project in Visual Studio this is the name of the Solution File
|
||||||
|
|
||||||
|
|
||||||
|
# For every executable you have with a main method you should have an add_executable line below.
|
||||||
|
# For every add executable line you should list every .cpp and .h file you have associated with that executable.
|
||||||
|
|
||||||
|
|
||||||
|
# This is the variable for Windows. I use this to define the root of my directory structure.
|
||||||
|
SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut)
|
||||||
|
|
||||||
|
# You shouldn't have to modify anything below this line
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
|
||||||
|
# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system
|
||||||
|
# This should be the case.
|
||||||
|
INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake)
|
||||||
|
INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake)
|
||||||
|
INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake)
|
||||||
|
|
||||||
|
|
||||||
|
IF (WIN32)
|
||||||
|
# This is the Windows code for which Opengl, and Glut are not properly installed
|
||||||
|
# since I can't install them I must cheat and copy libraries around
|
||||||
|
INCLUDE_DIRECTORIES(${GLUT_ROOT})
|
||||||
|
# LINK_DIRECTORIES(${GLUT_ROOT}\\lib)
|
||||||
|
IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND")
|
||||||
|
SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib)
|
||||||
|
# LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
|
||||||
|
# TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32)
|
||||||
|
#
|
||||||
|
# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug
|
||||||
|
# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug
|
||||||
|
# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug)
|
||||||
|
ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND")
|
||||||
|
# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
|
||||||
|
# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY})
|
||||||
|
ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND")
|
||||||
|
# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY})
|
||||||
|
# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY})
|
||||||
|
ELSE (WIN32)
|
||||||
|
# This is the lines for linux. This should always work if everything is installed and working fine.
|
||||||
|
# SET(CMAKE_BUILD_TYPE Debug)
|
||||||
|
# SET(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||||
|
INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR})
|
||||||
|
# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
|
||||||
|
# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
|
||||||
|
ENDIF (WIN32)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL }
|
||||||
|
)
|
||||||
|
|
||||||
|
LINK_LIBRARIES(
|
||||||
|
LibOpenGLSupport LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(BulletDino
|
||||||
|
BulletDino.cpp
|
||||||
|
)
|
||||||
|
|
||||||
3
Demos/BulletDinoDemo/Jamfile
Normal file
3
Demos/BulletDinoDemo/Jamfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
SubDir TOP Demos BulletDino ;
|
||||||
|
|
||||||
|
ExtraDemo BulletDino : [ Wildcard *.h *.cpp ] ;
|
||||||
@@ -13,32 +13,16 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Ignore this USE_PARALLEL_DISPATCHER define, it is for future optimizations
|
|
||||||
//#define USE_PARALLEL_DISPATCHER 1
|
|
||||||
|
|
||||||
/// September 2006: ForkLiftDemo is work in progress, this file is mostly just a placeholder
|
/// September 2006: ForkLiftDemo is work in progress, this file is mostly just a placeholder
|
||||||
/// This ForkLiftDemo file is very early in development, please check it later
|
/// This ForkLiftDemo file is very early in development, please check it later
|
||||||
|
|
||||||
#include "CcdPhysicsEnvironment.h"
|
|
||||||
#include "ParallelPhysicsEnvironment.h"
|
|
||||||
|
|
||||||
#include "CcdPhysicsController.h"
|
|
||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
|
||||||
#include "PHY_IVehicle.h"
|
|
||||||
#include "ParallelIslandDispatcher.h"
|
|
||||||
#include "LinearMath/btQuickprof.h"
|
|
||||||
#include "LinearMath/btIDebugDraw.h"
|
|
||||||
|
|
||||||
#include "GLDebugDrawer.h"
|
#include "GLDebugDrawer.h"
|
||||||
|
|
||||||
#include "PHY_Pro.h"
|
|
||||||
#include "BMF_Api.h"
|
|
||||||
#include <stdio.h> //printf debugging
|
#include <stdio.h> //printf debugging
|
||||||
|
|
||||||
float deltaTime = 1.f/60.f;
|
|
||||||
|
|
||||||
|
|
||||||
#include "GL_ShapeDrawer.h"
|
#include "GL_ShapeDrawer.h"
|
||||||
|
|
||||||
#include "GlutStuff.h"
|
#include "GlutStuff.h"
|
||||||
@@ -48,14 +32,9 @@ const int maxProxies = 32766;
|
|||||||
const int maxOverlap = 65535;
|
const int maxOverlap = 65535;
|
||||||
|
|
||||||
|
|
||||||
DefaultMotionState wheelMotionState[4];
|
|
||||||
|
|
||||||
///PHY_IVehicle is the interface behind the constraint that implements the raycast vehicle (WrapperVehicle which holds a btRaycastVehicle)
|
|
||||||
///notice that for higher-quality slow-moving vehicles, another approach might be better
|
|
||||||
///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts
|
|
||||||
PHY_IVehicle* gVehicleConstraint=0;
|
|
||||||
float gEngineForce = 0.f;
|
float gEngineForce = 0.f;
|
||||||
float maxEngineForce = 1000.f;
|
float maxEngineForce = 100.f;
|
||||||
float gVehicleSteering = 0.f;
|
float gVehicleSteering = 0.f;
|
||||||
float steeringIncrement = 0.1f;
|
float steeringIncrement = 0.1f;
|
||||||
float steeringClamp = 0.3f;
|
float steeringClamp = 0.3f;
|
||||||
@@ -103,32 +82,15 @@ m_maxCameraDistance(10.f)
|
|||||||
void ForkLiftDemo::setupPhysics()
|
void ForkLiftDemo::setupPhysics()
|
||||||
{
|
{
|
||||||
|
|
||||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
|
|
||||||
//ParallelIslandDispatcher* dispatcher2 = new ParallelIslandDispatcher();
|
|
||||||
|
|
||||||
btVector3 worldAabbMin(-30000,-30000,-30000);
|
|
||||||
btVector3 worldAabbMax(30000,30000,30000);
|
|
||||||
|
|
||||||
btOverlappingPairCache* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
|
|
||||||
//OverlappingPairCache* broadphase = new btSimpleBroadphase(maxProxies,maxOverlap);
|
|
||||||
|
|
||||||
#ifdef USE_PARALLEL_DISPATCHER
|
|
||||||
m_physicsEnvironmentPtr = new ParallelPhysicsEnvironment(dispatcher2,broadphase);
|
|
||||||
#else
|
|
||||||
m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
|
|
||||||
#endif
|
|
||||||
m_physicsEnvironmentPtr->setDeactivationTime(2.f);
|
|
||||||
|
|
||||||
m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);
|
|
||||||
|
|
||||||
m_physicsEnvironmentPtr->setGravity(0,-10,0);//0,0);//-10,0);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
|
btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
|
||||||
|
m_dynamicsWorld = new btDiscreteDynamicsWorld();
|
||||||
|
|
||||||
|
|
||||||
#define USE_TRIMESH_GROUND 1
|
#define USE_TRIMESH_GROUND 1
|
||||||
#ifdef USE_TRIMESH_GROUND
|
#ifdef USE_TRIMESH_GROUND
|
||||||
|
int i;
|
||||||
|
|
||||||
const float TRIANGLE_SIZE=20.f;
|
const float TRIANGLE_SIZE=20.f;
|
||||||
|
|
||||||
@@ -151,7 +113,7 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
{
|
{
|
||||||
for (int j=0;j<NUM_VERTS_Y;j++)
|
for (int j=0;j<NUM_VERTS_Y;j++)
|
||||||
{
|
{
|
||||||
gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,2.f*sinf((float)i)*cosf((float)j)+10.f,(j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
|
gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,2.f*sinf((float)i)*cosf((float)j),(j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,86 +144,32 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
btTransform tr;
|
btTransform tr;
|
||||||
tr.setIdentity();
|
tr.setIdentity();
|
||||||
|
|
||||||
tr.setOrigin(btVector3(0,-20.f,0));
|
tr.setOrigin(btVector3(0,-4.5f,0));
|
||||||
|
|
||||||
//create ground object
|
//create ground object
|
||||||
localCreatePhysicsObject(false,0,tr,groundShape);
|
localCreateRigidBody(0,tr,groundShape);
|
||||||
|
|
||||||
btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f));
|
btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f));
|
||||||
tr.setOrigin(btVector3(0,0.f,0));
|
tr.setOrigin(btVector3(0,0.f,0));
|
||||||
|
|
||||||
m_carChassis = localCreatePhysicsObject(true,800,tr,chassisShape);
|
m_carChassis = localCreateRigidBody(800,tr,chassisShape);
|
||||||
|
|
||||||
clientResetScene();
|
clientResetScene();
|
||||||
|
|
||||||
m_physicsEnvironmentPtr->SyncMotionStates(0.f);
|
|
||||||
|
|
||||||
/// create vehicle
|
/// create vehicle
|
||||||
{
|
{
|
||||||
int constraintId;
|
|
||||||
|
|
||||||
constraintId =m_physicsEnvironmentPtr->createConstraint(
|
|
||||||
m_carChassis,0,
|
|
||||||
PHY_VEHICLE_CONSTRAINT,
|
|
||||||
0,0,0,
|
|
||||||
0,0,0);
|
|
||||||
|
|
||||||
///never deactivate the vehicle
|
|
||||||
m_carChassis->getRigidBody()->SetActivationState(DISABLE_DEACTIVATION);
|
|
||||||
|
|
||||||
gVehicleConstraint = m_physicsEnvironmentPtr->getVehicleConstraint(constraintId);
|
///never deactivate the vehicle
|
||||||
|
m_carChassis->SetActivationState(DISABLE_DEACTIVATION);
|
||||||
|
|
||||||
btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),0,2*CUBE_HALF_EXTENTS-wheelRadius);
|
btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),0,2*CUBE_HALF_EXTENTS-wheelRadius);
|
||||||
btRaycastVehicle::btVehicleTuning tuning;
|
// m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);
|
||||||
bool isFrontWheel=true;
|
|
||||||
int rightIndex = 0;
|
|
||||||
int upIndex = 1;
|
|
||||||
int forwardIndex = 2;
|
|
||||||
|
|
||||||
gVehicleConstraint->setCoordinateSystem(rightIndex,upIndex,forwardIndex);
|
|
||||||
|
|
||||||
gVehicleConstraint->addWheel(&wheelMotionState[0],
|
|
||||||
(PHY__Vector3&)connectionPointCS0,
|
|
||||||
(PHY__Vector3&)wheelDirectionCS0,(PHY__Vector3&)wheelAxleCS,suspensionRestLength,wheelRadius,isFrontWheel);
|
|
||||||
|
|
||||||
connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),0,2*CUBE_HALF_EXTENTS-wheelRadius);
|
connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),0,2*CUBE_HALF_EXTENTS-wheelRadius);
|
||||||
gVehicleConstraint->addWheel(&wheelMotionState[1],
|
// m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);
|
||||||
(PHY__Vector3&)connectionPointCS0,
|
|
||||||
(PHY__Vector3&)wheelDirectionCS0,(PHY__Vector3&)wheelAxleCS,suspensionRestLength,wheelRadius,isFrontWheel);
|
|
||||||
|
|
||||||
connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),0,-2*CUBE_HALF_EXTENTS+wheelRadius);
|
connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),0,-2*CUBE_HALF_EXTENTS+wheelRadius);
|
||||||
isFrontWheel = false;
|
// m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);
|
||||||
gVehicleConstraint->addWheel(&wheelMotionState[2],
|
|
||||||
(PHY__Vector3&)connectionPointCS0,
|
|
||||||
(PHY__Vector3&)wheelDirectionCS0,(PHY__Vector3&)wheelAxleCS,suspensionRestLength,wheelRadius,isFrontWheel);
|
|
||||||
|
|
||||||
connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),0,-2*CUBE_HALF_EXTENTS+wheelRadius);
|
connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),0,-2*CUBE_HALF_EXTENTS+wheelRadius);
|
||||||
gVehicleConstraint->addWheel(&wheelMotionState[3],
|
// m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);
|
||||||
(PHY__Vector3&)connectionPointCS0,
|
|
||||||
(PHY__Vector3&)wheelDirectionCS0,(PHY__Vector3&)wheelAxleCS,suspensionRestLength,wheelRadius,isFrontWheel);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gVehicleConstraint->SetSuspensionStiffness(suspensionStiffness,0);
|
|
||||||
gVehicleConstraint->SetSuspensionStiffness(suspensionStiffness,1);
|
|
||||||
gVehicleConstraint->SetSuspensionStiffness(suspensionStiffness,2);
|
|
||||||
gVehicleConstraint->SetSuspensionStiffness(suspensionStiffness,3);
|
|
||||||
|
|
||||||
gVehicleConstraint->SetSuspensionDamping(suspensionDamping,0);
|
|
||||||
gVehicleConstraint->SetSuspensionDamping(suspensionDamping,1);
|
|
||||||
gVehicleConstraint->SetSuspensionDamping(suspensionDamping,2);
|
|
||||||
gVehicleConstraint->SetSuspensionDamping(suspensionDamping,3);
|
|
||||||
|
|
||||||
gVehicleConstraint->SetSuspensionCompression(suspensionCompression,0);
|
|
||||||
gVehicleConstraint->SetSuspensionCompression(suspensionCompression,1);
|
|
||||||
gVehicleConstraint->SetSuspensionCompression(suspensionCompression,2);
|
|
||||||
gVehicleConstraint->SetSuspensionCompression(suspensionCompression,3);
|
|
||||||
|
|
||||||
gVehicleConstraint->SetWheelFriction(wheelFriction,0);
|
|
||||||
gVehicleConstraint->SetWheelFriction(wheelFriction,1);
|
|
||||||
gVehicleConstraint->SetWheelFriction(wheelFriction,2);
|
|
||||||
gVehicleConstraint->SetWheelFriction(wheelFriction,3);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,46 +182,49 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
//to be implemented by the demo
|
//to be implemented by the demo
|
||||||
void ForkLiftDemo::renderme()
|
void ForkLiftDemo::renderme()
|
||||||
{
|
{
|
||||||
|
|
||||||
updateCamera();
|
updateCamera();
|
||||||
|
|
||||||
debugDrawer.setDebugMode(getDebugMode());
|
debugDrawer.setDebugMode(getDebugMode());
|
||||||
float m[16];
|
float m[16];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
btCylinderShapeX wheelShape(btVector3(wheelWidth,wheelRadius,wheelRadius));
|
|
||||||
btVector3 wheelColor(1,0,0);
|
|
||||||
|
|
||||||
for (i=0;i<4;i++)
|
|
||||||
{
|
|
||||||
//draw wheels (cylinders)
|
|
||||||
wheelMotionState[i].m_worldTransform.getOpenGLMatrix(m);
|
|
||||||
GL_ShapeDrawer::drawOpenGL(m,&wheelShape,wheelColor,getDebugMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
DemoApplication::renderme();
|
DemoApplication::renderme();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForkLiftDemo::clientMoveAndDisplay()
|
void ForkLiftDemo::clientMoveAndDisplay()
|
||||||
{
|
{
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
float dt = m_clock.getTimeMilliseconds() * 0.001f;
|
||||||
|
m_clock.reset();
|
||||||
|
|
||||||
|
if (m_dynamicsWorld)
|
||||||
|
{
|
||||||
|
//during idle mode, just run 1 simulation step maximum
|
||||||
|
int maxSimSubSteps = m_idle ? 1 : 1;
|
||||||
|
if (m_idle)
|
||||||
|
dt = 1.0/420.f;
|
||||||
|
|
||||||
{
|
int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
|
||||||
int steerWheelIndex = 2;
|
if (!numSimSteps)
|
||||||
gVehicleConstraint->applyEngineForce(gEngineForce,steerWheelIndex);
|
printf("Interpolated transforms\n");
|
||||||
steerWheelIndex = 3;
|
else
|
||||||
gVehicleConstraint->applyEngineForce(gEngineForce,steerWheelIndex);
|
{
|
||||||
|
if (numSimSteps > maxSimSubSteps)
|
||||||
steerWheelIndex = 0;
|
{
|
||||||
gVehicleConstraint->setSteeringValue(gVehicleSteering,steerWheelIndex);
|
//detect dropping frames
|
||||||
steerWheelIndex = 1;
|
printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps);
|
||||||
gVehicleConstraint->setSteeringValue(gVehicleSteering,steerWheelIndex);
|
} else
|
||||||
|
{
|
||||||
|
printf("Simulated (%i) steps\n",numSimSteps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -327,6 +238,8 @@ void ForkLiftDemo::clientMoveAndDisplay()
|
|||||||
#ifdef USE_QUICKPROF
|
#ifdef USE_QUICKPROF
|
||||||
btProfiler::endBlock("render");
|
btProfiler::endBlock("render");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
|
|
||||||
@@ -340,9 +253,10 @@ void ForkLiftDemo::displayCallback(void)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
m_physicsEnvironmentPtr->UpdateAabbs(deltaTime);
|
|
||||||
|
m_dynamicsWorld->updateAabbs();
|
||||||
//draw contactpoints
|
//draw contactpoints
|
||||||
m_physicsEnvironmentPtr->CallbackTriggers();
|
//m_physicsEnvironmentPtr->CallbackTriggers();
|
||||||
|
|
||||||
|
|
||||||
renderme();
|
renderme();
|
||||||
@@ -354,18 +268,13 @@ void ForkLiftDemo::displayCallback(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ForkLiftDemo::clientResetScene()
|
|
||||||
{
|
|
||||||
gEngineForce = 0.f;
|
|
||||||
gVehicleSteering = 0.f;
|
|
||||||
m_carChassis->setPosition(0,0,0);
|
|
||||||
m_carChassis->setOrientation(0,0,0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ForkLiftDemo::specialKeyboard(int key, int x, int y)
|
void ForkLiftDemo::specialKeyboard(int key, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("key = %i x=%i y=%i\n",key,x,y);
|
printf("key = %i x=%i y=%i\n",key,x,y);
|
||||||
|
|
||||||
switch (key)
|
switch (key)
|
||||||
@@ -403,6 +312,7 @@ void ForkLiftDemo::specialKeyboard(int key, int x, int y)
|
|||||||
|
|
||||||
// glutPostRedisplay();
|
// glutPostRedisplay();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -413,8 +323,11 @@ void ForkLiftDemo::updateCamera()
|
|||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
|
btTransform chassisWorldTrans;
|
||||||
|
|
||||||
//look at the vehicle
|
//look at the vehicle
|
||||||
m_cameraTargetPosition = m_carChassis->getRigidBody()->m_worldTransform.getOrigin();
|
m_carChassis->getMotionState()->getWorldTransform(chassisWorldTrans);
|
||||||
|
m_cameraTargetPosition = chassisWorldTrans.getOrigin();
|
||||||
|
|
||||||
//interpolate the camera height
|
//interpolate the camera height
|
||||||
m_cameraPosition[1] = (15.0*m_cameraPosition[1] + m_cameraTargetPosition[1] + m_cameraHeight)/16.0;
|
m_cameraPosition[1] = (15.0*m_cameraPosition[1] + m_cameraTargetPosition[1] + m_cameraHeight)/16.0;
|
||||||
@@ -442,5 +355,6 @@ void ForkLiftDemo::updateCamera()
|
|||||||
m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
|
m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,18 @@ subject to the following restrictions:
|
|||||||
#ifndef FORKLIFT_DEMO_H
|
#ifndef FORKLIFT_DEMO_H
|
||||||
#define FORKLIFT_DEMO_H
|
#define FORKLIFT_DEMO_H
|
||||||
|
|
||||||
|
class btVehicleTuning;
|
||||||
|
struct btVehicleRaycaster;
|
||||||
|
#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
|
||||||
|
|
||||||
#include "DemoApplication.h"
|
#include "DemoApplication.h"
|
||||||
|
|
||||||
///ForkLiftDemo shows how to use constraint for a cylinder-wheels vehicle
|
///ForkLiftDemo shows how to setup and use the built-in raycast vehicle
|
||||||
class ForkLiftDemo : public DemoApplication
|
class ForkLiftDemo : public DemoApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CcdPhysicsController* m_carChassis;
|
btRigidBody* m_carChassis;
|
||||||
|
|
||||||
float m_cameraHeight;
|
float m_cameraHeight;
|
||||||
|
|
||||||
@@ -34,7 +38,6 @@ class ForkLiftDemo : public DemoApplication
|
|||||||
|
|
||||||
virtual void clientMoveAndDisplay();
|
virtual void clientMoveAndDisplay();
|
||||||
|
|
||||||
virtual void clientResetScene();
|
|
||||||
|
|
||||||
virtual void displayCallback();
|
virtual void displayCallback();
|
||||||
|
|
||||||
@@ -50,3 +53,4 @@ class ForkLiftDemo : public DemoApplication
|
|||||||
|
|
||||||
#endif //FORKLIFT_DEMO_H
|
#endif //FORKLIFT_DEMO_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,13 +31,9 @@ subject to the following restrictions:
|
|||||||
const int maxProxies = 32766;
|
const int maxProxies = 32766;
|
||||||
const int maxOverlap = 65535;
|
const int maxOverlap = 65535;
|
||||||
|
|
||||||
|
///btRaycastVehicle is the interface for the constraint that implements the raycast vehicle
|
||||||
btDefaultMotionState wheelMotionState[4];
|
|
||||||
|
|
||||||
///PHY_IVehicle is the interface behind the constraint that implements the raycast vehicle (WrapperVehicle which holds a btRaycastVehicle)
|
|
||||||
///notice that for higher-quality slow-moving vehicles, another approach might be better
|
///notice that for higher-quality slow-moving vehicles, another approach might be better
|
||||||
///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts
|
///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts
|
||||||
//PHY_IVehicle* gVehicleConstraint=0;
|
|
||||||
float gEngineForce = 0.f;
|
float gEngineForce = 0.f;
|
||||||
float maxEngineForce = 100.f;
|
float maxEngineForce = 100.f;
|
||||||
float gVehicleSteering = 0.f;
|
float gVehicleSteering = 0.f;
|
||||||
|
|||||||
Reference in New Issue
Block a user