Camera support.

This commit is contained in:
Scott Duensing 2019-08-29 21:06:10 -05:00
parent 18fab39c08
commit 7f0e1974ee
2 changed files with 214 additions and 119 deletions

274
j3d/j3d.c
View file

@ -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;
}

View file

@ -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) \