Camera support.
This commit is contained in:
parent
18fab39c08
commit
7f0e1974ee
2 changed files with 214 additions and 119 deletions
274
j3d/j3d.c
274
j3d/j3d.c
|
@ -28,6 +28,8 @@
|
|||
//***TODO***
|
||||
// Allow multiple objects to be loaded into a world
|
||||
// Store original vertex data so we can do local rotations and save them
|
||||
// Rename verticies to vertices
|
||||
// Remove _ from sin_table and cos_table
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
@ -54,17 +56,20 @@ segment "j3d";
|
|||
|
||||
|
||||
// Module global data
|
||||
static jint16 clipMinX = 0;
|
||||
static jint16 clipMinY = 0;
|
||||
static jint16 clipMinZ = 100;
|
||||
static jint16 clipMaxX = 319;
|
||||
static jint16 clipMaxY = 199;
|
||||
static jint16 clipMaxZ = 3000;
|
||||
static jint16 viewDistance = 250;
|
||||
static float ambientLight = 6;
|
||||
static j3VertexT cameraLocation;
|
||||
static j3FacingT cameraAngle;
|
||||
static j3VertexT sunLocation;
|
||||
jint16 _j3VarClipMinX = 0;
|
||||
jint16 _j3VarClipMinY = 0;
|
||||
jint16 _j3VarClipMinZ = 100;
|
||||
jint16 _j3VarClipMaxX = 319;
|
||||
jint16 _j3VarClipMaxY = 199;
|
||||
jint16 _j3VarClipMaxZ = 3000;
|
||||
jint16 _j3VarViewDistance = 250;
|
||||
float _j3VarAmbientLight = 6;
|
||||
j3Matrix4x4T _j3VarCameraMatrix;
|
||||
j3VertexT _j3VarCameraLocation;
|
||||
j3FacingT _j3VarCameraAngle;
|
||||
bool _j3VarCameraLocationDirty = true;
|
||||
bool _j3VarCameraAngleDirty = true;
|
||||
j3VertexT _j3VarSunLocation;
|
||||
|
||||
|
||||
#define ASPECT_RATIO (float)0.8
|
||||
|
@ -105,7 +110,7 @@ void _j3DrawSolid(j3ObjectT *o) {
|
|||
z3 = o->verticies[vertex3].camera.z;
|
||||
|
||||
// Perform z clipping
|
||||
if ((z1 < clipMinZ && z2 < clipMinZ && z3 < clipMinZ) || (z1 > clipMaxZ && z2 > clipMaxZ && z3 > clipMaxZ)) {
|
||||
if ((z1 < _j3VarClipMinZ && z2 < _j3VarClipMinZ && z3 < _j3VarClipMinZ) || (z1 > _j3VarClipMaxZ && z2 > _j3VarClipMaxZ && z3 > _j3VarClipMaxZ)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -118,12 +123,12 @@ void _j3DrawSolid(j3ObjectT *o) {
|
|||
y3 = o->verticies[vertex3].camera.y;
|
||||
|
||||
// Screen position of points
|
||||
x1 = HALF_SCREEN_WIDTH + x1 * viewDistance / z1;
|
||||
y1 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y1 * viewDistance / z1;
|
||||
x2 = HALF_SCREEN_WIDTH + x2 * viewDistance / z2;
|
||||
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * viewDistance / z2;
|
||||
x3 = HALF_SCREEN_WIDTH + x3 * viewDistance / z3;
|
||||
y3 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y3 * viewDistance / z3;
|
||||
x1 = HALF_SCREEN_WIDTH + x1 * _j3VarViewDistance / z1;
|
||||
y1 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y1 * _j3VarViewDistance / z1;
|
||||
x2 = HALF_SCREEN_WIDTH + x2 * _j3VarViewDistance / z2;
|
||||
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * _j3VarViewDistance / z2;
|
||||
x3 = HALF_SCREEN_WIDTH + x3 * _j3VarViewDistance / z3;
|
||||
y3 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y3 * _j3VarViewDistance / z3;
|
||||
|
||||
j3DrawTriangle2D((jint16)x1, (jint16)y1, (jint16)x2, (jint16)y2, (jint16)x3, (jint16)y3, o->triangles[t].shade);
|
||||
}
|
||||
|
@ -169,7 +174,7 @@ void j3DrawTriangle2D(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint
|
|||
} // end if
|
||||
|
||||
// Trivial rejection tests
|
||||
if (y3 < clipMinY || y1 > clipMaxY || (x1 < clipMinX && x2 < clipMinX && x3 < clipMinX) || (x1 > clipMaxX && x2 > clipMaxX && x3 > clipMaxX)) {
|
||||
if (y3 < _j3VarClipMinY || y1 > _j3VarClipMaxY || (x1 < _j3VarClipMinX && x2 < _j3VarClipMinX && x3 < _j3VarClipMinX) || (x1 > _j3VarClipMaxX && x2 > _j3VarClipMaxX && x3 > _j3VarClipMaxX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -220,19 +225,19 @@ void _j3DrawTriangleBottom(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3,
|
|||
xe = (float)x1 + (float)0.5;
|
||||
|
||||
// Perform y clipping
|
||||
if (y1 < clipMinY) {
|
||||
if (y1 < _j3VarClipMinY) {
|
||||
// Compute new xs and ys
|
||||
xs = xs + dxLeft * (float)(-y1 + clipMinY);
|
||||
xe = xe + dxRight * (float)(-y1 + clipMinY);
|
||||
xs = xs + dxLeft * (float)(-y1 + _j3VarClipMinY);
|
||||
xe = xe + dxRight * (float)(-y1 + _j3VarClipMinY);
|
||||
// Reset y1
|
||||
y1 = clipMinY;
|
||||
y1 = _j3VarClipMinY;
|
||||
}
|
||||
if (y3 > clipMaxY) {
|
||||
y3 = clipMaxY;
|
||||
if (y3 > _j3VarClipMaxY) {
|
||||
y3 = _j3VarClipMaxY;
|
||||
}
|
||||
|
||||
// Test if x clipping is needed
|
||||
if (x1 >= clipMinX && x1 <= clipMaxX && x2 >= clipMinX && x2 <= clipMaxX && x3 >= clipMinX && x3 <= clipMaxX) {
|
||||
if (x1 >= _j3VarClipMinX && x1 <= _j3VarClipMaxX && x2 >= _j3VarClipMinX && x2 <= _j3VarClipMaxX && x3 >= _j3VarClipMinX && x3 <= _j3VarClipMaxX) {
|
||||
// Draw the triangle
|
||||
for (tempY=y1; tempY<=y3; tempY++) {
|
||||
jlDrawLine((jint16)xs, tempY, (jint16)xe, tempY);
|
||||
|
@ -250,15 +255,15 @@ void _j3DrawTriangleBottom(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3,
|
|||
xs += dxLeft;
|
||||
xe += dxRight;
|
||||
// Clip line
|
||||
if (left < clipMinX) {
|
||||
left = clipMinX;
|
||||
if (right < clipMinX) {
|
||||
if (left < _j3VarClipMinX) {
|
||||
left = _j3VarClipMinX;
|
||||
if (right < _j3VarClipMinX) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (right > clipMaxX) {
|
||||
right = clipMaxX;
|
||||
if (left > clipMaxX) {
|
||||
if (right > _j3VarClipMaxX) {
|
||||
right = _j3VarClipMaxX;
|
||||
if (left > _j3VarClipMaxX) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -299,19 +304,19 @@ void _j3DrawTriangleTop(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, ji
|
|||
xe = (float)x2 + (float)0.5;
|
||||
|
||||
// Perform y clipping
|
||||
if (y1 < clipMinY) {
|
||||
if (y1 < _j3VarClipMinY) {
|
||||
// Compute new xs and ys
|
||||
xs = xs + dxLeft * (float)(-y1 + clipMinY);
|
||||
xe = xe + dxRight * (float)(-y1 + clipMinY);
|
||||
xs = xs + dxLeft * (float)(-y1 + _j3VarClipMinY);
|
||||
xe = xe + dxRight * (float)(-y1 + _j3VarClipMinY);
|
||||
// Reset y1
|
||||
y1 = clipMinY;
|
||||
y1 = _j3VarClipMinY;
|
||||
}
|
||||
if (y3 > clipMaxY) {
|
||||
y3=clipMaxY;
|
||||
if (y3 > _j3VarClipMaxY) {
|
||||
y3=_j3VarClipMaxY;
|
||||
}
|
||||
|
||||
// Test if x clipping is needed
|
||||
if (x1 >= clipMinX && x1 <= clipMaxX && x2 >= clipMinX && x2 <= clipMaxX && x3 >= clipMinX && x3 <= clipMaxX) {
|
||||
if (x1 >= _j3VarClipMinX && x1 <= _j3VarClipMaxX && x2 >= _j3VarClipMinX && x2 <= _j3VarClipMaxX && x3 >= _j3VarClipMinX && x3 <= _j3VarClipMaxX) {
|
||||
// Draw the triangle
|
||||
for (tempY=y1; tempY<=y3; tempY++) {
|
||||
jlDrawLine((jint16)xs, tempY, (jint16)xe, tempY);
|
||||
|
@ -329,15 +334,15 @@ void _j3DrawTriangleTop(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, ji
|
|||
xs += dxLeft;
|
||||
xe += dxRight;
|
||||
// Clip line
|
||||
if (left < clipMinX) {
|
||||
left = clipMinX;
|
||||
if (right < clipMinX) {
|
||||
if (left < _j3VarClipMinX) {
|
||||
left = _j3VarClipMinX;
|
||||
if (right < _j3VarClipMinX) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (right > clipMaxX) {
|
||||
right = clipMaxX;
|
||||
if (left > clipMaxX) {
|
||||
if (right > _j3VarClipMaxX) {
|
||||
right = _j3VarClipMaxX;
|
||||
if (left > _j3VarClipMaxX) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -371,11 +376,11 @@ void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2) {
|
|||
y2 = v.y;
|
||||
z2 = v.z;
|
||||
|
||||
x1 = HALF_SCREEN_WIDTH + x1 * viewDistance / z1;
|
||||
y1 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y1 * viewDistance / z1;
|
||||
x1 = HALF_SCREEN_WIDTH + x1 * _j3VarViewDistance / z1;
|
||||
y1 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y1 * _j3VarViewDistance / z1;
|
||||
|
||||
x2 = HALF_SCREEN_WIDTH + x2 * viewDistance / z2;
|
||||
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * viewDistance / z2;
|
||||
x2 = HALF_SCREEN_WIDTH + x2 * _j3VarViewDistance / z2;
|
||||
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * _j3VarViewDistance / z2;
|
||||
|
||||
ix1 = (jint16)x1;
|
||||
iy1 = (jint16)y1;
|
||||
|
@ -497,6 +502,9 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
j3Matrix4x4T rotateZ;
|
||||
j3Matrix4x4T final;
|
||||
j3Matrix4x4T temp;
|
||||
j3Matrix4x4T result1;
|
||||
j3Matrix4x4T result2;
|
||||
j3Matrix4x4T translate;
|
||||
|
||||
// === ROTATION ===
|
||||
|
||||
|
@ -655,10 +663,60 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
}
|
||||
|
||||
// === CAMERA SPACE ===
|
||||
//***TODO*** Move this?
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->verticies[i].camera = o->verticies[i].world;
|
||||
//***TODO*** Move this when we add multiple object stuff and re-do this function
|
||||
if (_j3VarCameraLocationDirty || _j3VarCameraAngleDirty) {
|
||||
// Create the global inverse transformation matrix used to transform world coordinate to camera coordinates
|
||||
j3MathMatrix4x4Identity(translate);
|
||||
j3MathMatrix4x4Identity(rotateX);
|
||||
j3MathMatrix4x4Identity(rotateY);
|
||||
j3MathMatrix4x4Identity(rotateZ);
|
||||
|
||||
translate[3][0] = -_j3VarCameraLocation.x;
|
||||
translate[3][1] = -_j3VarCameraLocation.y;
|
||||
translate[3][2] = -_j3VarCameraLocation.z;
|
||||
|
||||
// Z matrix
|
||||
rotateX[1][1] = ( cos_table[_j3VarCameraAngle.x]);
|
||||
rotateX[1][2] = -( sin_table[_j3VarCameraAngle.x]);
|
||||
rotateX[2][1] = -(-sin_table[_j3VarCameraAngle.x]);
|
||||
rotateX[2][2] = ( cos_table[_j3VarCameraAngle.x]);
|
||||
|
||||
// Y matrix
|
||||
rotateY[0][0] = ( cos_table[_j3VarCameraAngle.y]);
|
||||
rotateY[0][2] = -(-sin_table[_j3VarCameraAngle.y]);
|
||||
rotateY[2][0] = -( sin_table[_j3VarCameraAngle.y]);
|
||||
rotateY[2][2] = ( cos_table[_j3VarCameraAngle.y]);
|
||||
|
||||
// Z matrix
|
||||
rotateZ[0][0] = ( cos_table[_j3VarCameraAngle.z]);
|
||||
rotateZ[0][1] = -( sin_table[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][0] = -(-sin_table[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][1] = ( cos_table[_j3VarCameraAngle.z]);
|
||||
|
||||
j3MathMatrix4x4Mult(translate, rotateX, result1);
|
||||
j3MathMatrix4x4Mult(result1, rotateY, result2);
|
||||
j3MathMatrix4x4Mult(result2, rotateZ, _j3VarCameraMatrix);
|
||||
|
||||
_j3VarCameraLocationDirty = false;
|
||||
_j3VarCameraAngleDirty = false;
|
||||
}
|
||||
|
||||
if (o->positionDirty || o->rotationDirty) {
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->verticies[i].camera.x =
|
||||
o->verticies[i].world.x * _j3VarCameraMatrix[0][0] +
|
||||
o->verticies[i].world.y * _j3VarCameraMatrix[1][0] +
|
||||
o->verticies[i].world.z * _j3VarCameraMatrix[2][0] + _j3VarCameraMatrix[3][0];
|
||||
o->verticies[i].camera.y =
|
||||
o->verticies[i].world.x * _j3VarCameraMatrix[0][1] +
|
||||
o->verticies[i].world.y * _j3VarCameraMatrix[1][1] +
|
||||
o->verticies[i].world.z * _j3VarCameraMatrix[2][1] + _j3VarCameraMatrix[3][1];
|
||||
o->verticies[i].camera.z =
|
||||
o->verticies[i].world.x * _j3VarCameraMatrix[0][2] +
|
||||
o->verticies[i].world.y * _j3VarCameraMatrix[1][2] +
|
||||
o->verticies[i].world.z * _j3VarCameraMatrix[2][2] + _j3VarCameraMatrix[3][2];
|
||||
}
|
||||
}
|
||||
|
||||
// === REMOVE BACKFACES & LIGHT ===
|
||||
|
@ -683,9 +741,9 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
j3MathCrossProduct3D((j3Vector3DT *)&v, (j3Vector3DT *)&u, (j3Vector3DT *)&normal);
|
||||
// Compute the line of sight vector, since all coordinates are world all
|
||||
// object vertices are already relative to (0,0,0), thus
|
||||
sight.x = cameraLocation.x - o->verticies[vertex0].world.x;
|
||||
sight.y = cameraLocation.y - o->verticies[vertex0].world.y;
|
||||
sight.z = cameraLocation.z - o->verticies[vertex0].world.z;
|
||||
sight.x = _j3VarCameraLocation.x - o->verticies[vertex0].world.x;
|
||||
sight.y = _j3VarCameraLocation.y - o->verticies[vertex0].world.y;
|
||||
sight.z = _j3VarCameraLocation.z - o->verticies[vertex0].world.z;
|
||||
// Compute the dot product between line of sight vector and normal to surface
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&sight);
|
||||
|
||||
|
@ -697,10 +755,10 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
// Compute light intensity if needed
|
||||
if (o->triangles[i].lit) {
|
||||
// Compute the dot product between the light source vector and normal vector to surface
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&sunLocation);
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&_j3VarSunLocation);
|
||||
// Test if light ray is reflecting off surface
|
||||
if (dot > 0) {
|
||||
intensity = ambientLight + (dot * (o->triangles[i].normalLength));
|
||||
intensity = _j3VarAmbientLight + (dot * (o->triangles[i].normalLength));
|
||||
// Test if intensity has overflowed
|
||||
if (intensity > 15) {
|
||||
intensity = 15;
|
||||
|
@ -709,7 +767,7 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
// totally illuminated. use the value to index into color table
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)intensity;
|
||||
} else {
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)ambientLight;
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)_j3VarAmbientLight;
|
||||
}
|
||||
} else {
|
||||
// Constant shading - simply assign color to shade
|
||||
|
@ -738,12 +796,12 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
// Normal v x u
|
||||
j3MathCrossProduct3D((j3Vector3DT *)&v, (j3Vector3DT *)&u, (j3Vector3DT *)&normal);
|
||||
// Compute the dot product between the light source vector and normal vector to surface
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&sunLocation);
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&_j3VarSunLocation);
|
||||
|
||||
// Is light ray is reflecting off surface
|
||||
if (dot > 0) {
|
||||
// cos 0 = (u.v)/|u||v| or
|
||||
intensity = ambientLight + (dot * (o->triangles[i].normalLength));
|
||||
intensity = _j3VarAmbientLight + (dot * (o->triangles[i].normalLength));
|
||||
// test if intensity has overflowed
|
||||
if (intensity > 15) {
|
||||
intensity = 15;
|
||||
|
@ -752,7 +810,7 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
// totally illuminated. use the value to index into color table
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)intensity;
|
||||
} else {
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)ambientLight;
|
||||
o->triangles[i].shade = o->triangles[i].color - (jint16)_j3VarAmbientLight;
|
||||
}
|
||||
} else {
|
||||
// Constant shading and simply assign color to shade
|
||||
|
@ -808,8 +866,8 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
bool success = false; // Did we successfully clip this line?
|
||||
|
||||
// Is the line completely visible?
|
||||
point1 = ((*x1 >= clipMinX) && (*x1 <= clipMaxX) && (*y1 >= clipMinY) && (*y1 <= clipMaxY));
|
||||
point2 = ((*x2 >= clipMinX) && (*x2 <= clipMaxX) && (*y2 >= clipMinY) && (*y2 <= clipMaxY));
|
||||
point1 = ((*x1 >= _j3VarClipMinX) && (*x1 <= _j3VarClipMaxX) && (*y1 >= _j3VarClipMinY) && (*y1 <= _j3VarClipMaxY));
|
||||
point2 = ((*x2 >= _j3VarClipMinX) && (*x2 <= _j3VarClipMaxX) && (*y2 >= _j3VarClipMinY) && (*y2 <= _j3VarClipMaxY));
|
||||
if (point1 && point2) {
|
||||
return(true);
|
||||
}
|
||||
|
@ -818,10 +876,10 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
if (!point1 && !point2) {
|
||||
// Test to see if each endpoint is on the same side of one of
|
||||
// the bounding planes created by each clipping region boundary
|
||||
if (((*x1<clipMinX) && (*x2<clipMinX)) || // left
|
||||
((*x1>clipMaxX) && (*x2>clipMaxX)) || // right
|
||||
((*y1<clipMinY) && (*y2<clipMinY)) || // above
|
||||
((*y1>clipMaxY) && (*y2>clipMaxY))) { // below
|
||||
if (((*x1<_j3VarClipMinX) && (*x2<_j3VarClipMinX)) || // left
|
||||
((*x1>_j3VarClipMaxX) && (*x2>_j3VarClipMaxX)) || // right
|
||||
((*y1<_j3VarClipMinY) && (*y2<_j3VarClipMinY)) || // above
|
||||
((*y1>_j3VarClipMaxY) && (*y2>_j3VarClipMaxY))) { // below
|
||||
// No need to draw line
|
||||
return(false);
|
||||
}
|
||||
|
@ -837,41 +895,41 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
dy = *y2 - *y1;
|
||||
|
||||
// Find which boundary line needs to be clipped against
|
||||
if (*x2 > clipMaxX) {
|
||||
if (*x2 > _j3VarClipMaxX) {
|
||||
// Flag right edge
|
||||
rightEdge = true;
|
||||
// Find intersection with right edge
|
||||
if (fabsf(dx) > FLT_EPSILON) { // dx != 0
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (clipMaxX - *x1) + *y1);
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (_j3VarClipMaxX - *x1) + *y1);
|
||||
} else {
|
||||
yi = -1; // Invalidate intersection
|
||||
}
|
||||
} else if (*x2 < clipMinX) {
|
||||
} else if (*x2 < _j3VarClipMinX) {
|
||||
// Flag left edge
|
||||
leftEdge = true;
|
||||
// Find intersection with left edge
|
||||
if (fabsf(dx) > FLT_EPSILON) { // dx != 0
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (clipMinX - *x1) + *y1);
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (_j3VarClipMinX - *x1) + *y1);
|
||||
} else {
|
||||
yi = -1; // Invalidate intersection
|
||||
}
|
||||
}
|
||||
|
||||
if (*y2 > clipMaxY) {
|
||||
if (*y2 > _j3VarClipMaxY) {
|
||||
// Flag bottom edge
|
||||
bottomEdge = true;
|
||||
// Find intersection with right edge
|
||||
if (fabsf(dy) > FLT_EPSILON) { // dy != 0
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (clipMaxY - *y1) + *x1);
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (_j3VarClipMaxY - *y1) + *x1);
|
||||
} else {
|
||||
xi = -1; // Invalidate inntersection
|
||||
}
|
||||
} else if (*y2 < clipMinY) {
|
||||
} else if (*y2 < _j3VarClipMinY) {
|
||||
// Flag top edge
|
||||
topEdge = true;
|
||||
// Find intersection with top edge
|
||||
if (fabsf(dy) > FLT_EPSILON) { // dy != 0
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (clipMinY - *y1) + *x1);
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (_j3VarClipMinY - *y1) + *x1);
|
||||
} else {
|
||||
xi = -1; // Invalidate intersection
|
||||
}
|
||||
|
@ -880,23 +938,23 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
// We know where the line passed through
|
||||
// FInd which edge is the proper intersection
|
||||
|
||||
if (rightEdge && (yi >= clipMinY && yi <= clipMaxY)) {
|
||||
*x2 = clipMaxX;
|
||||
if (rightEdge && (yi >= _j3VarClipMinY && yi <= _j3VarClipMaxY)) {
|
||||
*x2 = _j3VarClipMaxX;
|
||||
*y2 = yi;
|
||||
success = true;
|
||||
} else if (leftEdge && (yi >= clipMinY && yi <= clipMaxY)) {
|
||||
*x2 = clipMinX;
|
||||
} else if (leftEdge && (yi >= _j3VarClipMinY && yi <= _j3VarClipMaxY)) {
|
||||
*x2 = _j3VarClipMinX;
|
||||
*y2 = yi;
|
||||
success = true;
|
||||
}
|
||||
|
||||
if (bottomEdge && (xi >= clipMinX && xi <= clipMaxX)) {
|
||||
if (bottomEdge && (xi >= _j3VarClipMinX && xi <= _j3VarClipMaxX)) {
|
||||
*x2 = xi;
|
||||
*y2 = clipMaxY;
|
||||
*y2 = _j3VarClipMaxY;
|
||||
success = true;
|
||||
} else if (topEdge && (xi >= clipMinX && xi <= clipMaxX)) {
|
||||
} else if (topEdge && (xi >= _j3VarClipMinX && xi <= _j3VarClipMaxX)) {
|
||||
*x2 = xi;
|
||||
*y2 = clipMinY;
|
||||
*y2 = _j3VarClipMinY;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
@ -915,41 +973,41 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
dy = *y1 - *y2;
|
||||
|
||||
// Find which boundary line needs to be clipped against
|
||||
if (*x1 > clipMaxX) {
|
||||
if (*x1 > _j3VarClipMaxX) {
|
||||
// Flag right edge
|
||||
rightEdge = true;
|
||||
// Find intersection with right edge
|
||||
if (fabsf(dx) > FLT_EPSILON) { // dx != 0
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (clipMaxX - *x2) + *y2);
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (_j3VarClipMaxX - *x2) + *y2);
|
||||
} else {
|
||||
yi = -1; // Invalidate inntersection
|
||||
}
|
||||
} else if (*x1 < clipMinX) {
|
||||
} else if (*x1 < _j3VarClipMinX) {
|
||||
// Flag left edge
|
||||
leftEdge = true;
|
||||
// Find intersection with left edge
|
||||
if (fabsf(dx) > FLT_EPSILON) { // dx != 0
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (clipMinX - *x2) + *y2);
|
||||
yi = (jint16)((float)0.5 + (dy / dx) * (_j3VarClipMinX - *x2) + *y2);
|
||||
} else {
|
||||
yi = -1; // Invalidate intersection
|
||||
}
|
||||
}
|
||||
|
||||
if (*y1 > clipMaxY) {
|
||||
if (*y1 > _j3VarClipMaxY) {
|
||||
// Flag bottom edge
|
||||
bottomEdge = true;
|
||||
// Find intersection with right edge
|
||||
if (fabsf(dy) > FLT_EPSILON) { // dy != 0
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (clipMaxY - *y2) + *x2);
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (_j3VarClipMaxY - *y2) + *x2);
|
||||
} else {
|
||||
xi = -1; // invalidate inntersection
|
||||
}
|
||||
} else if (*y1 < clipMinY) {
|
||||
} else if (*y1 < _j3VarClipMinY) {
|
||||
// Flag top edge
|
||||
topEdge = true;
|
||||
// Find intersection with top edge
|
||||
if (fabsf(dy) > FLT_EPSILON) { // dy != 0
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (clipMinY - *y2) + *x2);
|
||||
xi = (jint16)((float)0.5 + (dx / dy) * (_j3VarClipMinY - *y2) + *x2);
|
||||
} else {
|
||||
xi = -1; // invalidate inntersection
|
||||
}
|
||||
|
@ -958,23 +1016,23 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
// We know where the line passed through
|
||||
// Find which edge is the proper intersection
|
||||
|
||||
if (rightEdge && (yi >= clipMinY && yi <= clipMaxY)) {
|
||||
*x1 = clipMaxX;
|
||||
if (rightEdge && (yi >= _j3VarClipMinY && yi <= _j3VarClipMaxY)) {
|
||||
*x1 = _j3VarClipMaxX;
|
||||
*y1 = yi;
|
||||
success = true;
|
||||
} else if (leftEdge && (yi >= clipMinY && yi <= clipMaxY)) {
|
||||
*x1 = clipMinX;
|
||||
} else if (leftEdge && (yi >= _j3VarClipMinY && yi <= _j3VarClipMaxY)) {
|
||||
*x1 = _j3VarClipMinX;
|
||||
*y1 = yi;
|
||||
success = true;
|
||||
}
|
||||
|
||||
if (bottomEdge && (xi >= clipMinX && xi <= clipMaxX)) {
|
||||
if (bottomEdge && (xi >= _j3VarClipMinX && xi <= _j3VarClipMaxX)) {
|
||||
*x1 = xi;
|
||||
*y1 = clipMaxY;
|
||||
*y1 = _j3VarClipMaxY;
|
||||
success = true;
|
||||
} else if (topEdge && (xi >= clipMinX && xi <= clipMaxX)) {
|
||||
} else if (topEdge && (xi >= _j3VarClipMinX && xi <= _j3VarClipMaxX)) {
|
||||
*x1 = xi;
|
||||
*y1 = clipMinY;
|
||||
*y1 = _j3VarClipMinY;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
@ -989,17 +1047,17 @@ void j3UtilShutdown(void) {
|
|||
|
||||
|
||||
void j3UtilStartup(void) {
|
||||
cameraLocation.x = 0;
|
||||
cameraLocation.y = 0;
|
||||
cameraLocation.z = 0;
|
||||
_j3VarCameraLocation.x = 0;
|
||||
_j3VarCameraLocation.y = 0;
|
||||
_j3VarCameraLocation.z = 0;
|
||||
|
||||
cameraAngle.x = 0;
|
||||
cameraAngle.y = 0;
|
||||
cameraAngle.z = 0;
|
||||
_j3VarCameraAngle.x = 0;
|
||||
_j3VarCameraAngle.y = 0;
|
||||
_j3VarCameraAngle.z = 0;
|
||||
|
||||
sunLocation.x = (float)-0.913913;
|
||||
sunLocation.y = (float) 0.389759;
|
||||
sunLocation.z = (float)-0.113369;
|
||||
_j3VarSunLocation.x = (float)-0.913913;
|
||||
_j3VarSunLocation.y = (float) 0.389759;
|
||||
_j3VarSunLocation.z = (float)-0.113369;
|
||||
}
|
||||
|
||||
|
||||
|
|
59
j3d/j3d.h
59
j3d/j3d.h
|
@ -27,9 +27,6 @@
|
|||
#include "joey.h"
|
||||
|
||||
|
||||
//***TODO*** verticies is vertices
|
||||
|
||||
|
||||
typedef float j3Matrix4x4T[4][4];
|
||||
|
||||
typedef struct {
|
||||
|
@ -79,11 +76,51 @@ typedef struct {
|
|||
} j3WorldT;
|
||||
|
||||
|
||||
#define jtCameraSetClippingBounds(x1, y1, x2, y2) \
|
||||
clipMinX = (x1); j3MathCheckBounds(clipMinX, 0, 319); \
|
||||
clipMinY = (y1); j3MathCheckBounds(clipMiny, 0, 199); \
|
||||
clipMaxX = (x2); j3MathCheckBounds(clipMaxX, 0, 319); \
|
||||
clipMaxY = (y2); j3MathCheckBounds(clipMaxy, 0, 199)
|
||||
extern jint16 _j3VarClipMinX;
|
||||
extern jint16 _j3VarClipMinY;
|
||||
extern jint16 _j3VarClipMinZ;
|
||||
extern jint16 _j3VarClipMaxX;
|
||||
extern jint16 _j3VarClipMaxY;
|
||||
extern jint16 _j3VarClipMaxZ;
|
||||
extern jint16 _j3VarViewDistance;
|
||||
extern float _j3VarAmbientLight;
|
||||
extern j3Matrix4x4T _j3VarCameraMatrix;
|
||||
extern j3VertexT _j3VarCameraLocation;
|
||||
extern j3FacingT _j3VarCameraAngle;
|
||||
extern bool _j3VarCameraLocationDirty;
|
||||
extern bool _j3VarCameraAngleDirty;
|
||||
extern j3VertexT _j3VarSunLocation;
|
||||
|
||||
|
||||
#define j3CameraMove(ob, px, py, pz) \
|
||||
_j3VarCameraLocation.x += (px); \
|
||||
_j3VarCameraLocation.y += (py); \
|
||||
_j3VarCameraLocation.z += (pz); \
|
||||
_j3VarCameraLocationDirty = true
|
||||
|
||||
#define j3CameraMoveTo(ob, px, py, pz) \
|
||||
_j3VarCameraLocation.x = (px); \
|
||||
_j3VarCameraLocation.y = (py); \
|
||||
_j3VarCameraLocation.z = (pz); \
|
||||
_j3VarCameraLocationDirty = true
|
||||
|
||||
#define j3CameraRotate(ob, px, py, pz) \
|
||||
_j3VarCameraAngle.x += (px); j3MathWrapBounds(_j3VarCameraAngle.x, 0, 360); \
|
||||
_j3VarCameraAngle.y += (py); j3MathWrapBounds(_j3VarCameraAngle.y, 0, 360); \
|
||||
_j3VarCameraAngle.z += (pz); j3MathWrapBounds(_j3VarCameraAngle.z, 0, 360); \
|
||||
_j3VarCameraAngleDirty = true
|
||||
|
||||
#define j3CameraRotateTo(ob, px, py, pz) \
|
||||
_j3VarCameraAngle.x = (px); j3MathWrapBounds(_j3VarCameraAngle.x, 0, 360); \
|
||||
_j3VarCameraAngle.y = (py); j3MathWrapBounds(_j3VarCameraAngle.y, 0, 360); \
|
||||
_j3VarCameraAngle.z = (pz); j3MathWrapBounds(_j3VarCameraAngle.z, 0, 360); \
|
||||
_j3VarCameraAngleDirty = true
|
||||
|
||||
#define j3CameraSetClippingBounds(x1, y1, x2, y2) \
|
||||
_j3VarClipMinX = (x1); j3MathCheckBounds(_j3VarClipMinX, 0, 319); \
|
||||
_j3VarClipMinY = (y1); j3MathCheckBounds(_j3VarClipMiny, 0, 199); \
|
||||
_j3VarClipMaxX = (x2); j3MathCheckBounds(_j3VarClipMaxX, 0, 319); \
|
||||
_j3VarClipMaxY = (y2); j3MathCheckBounds(_j3VarClipMaxy, 0, 199)
|
||||
|
||||
#define j3MathCheckBounds(value, min, max) \
|
||||
if (value < (min)) value = (min); \
|
||||
|
@ -100,9 +137,9 @@ typedef struct {
|
|||
ob.positionDirty = true
|
||||
|
||||
#define j3ObjectMoveTo(ob, px, py, pz) \
|
||||
ob.position.x = (px); \
|
||||
ob.position.y = (py); \
|
||||
ob.position.z = (pz); \
|
||||
ob.position.x = (px); \
|
||||
ob.position.y = (py); \
|
||||
ob.position.z = (pz); \
|
||||
ob.positionDirty = true
|
||||
|
||||
#define j3ObjectRotate(ob, px, py, pz) \
|
||||
|
|
Loading…
Add table
Reference in a new issue