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