Optimized object update.
This commit is contained in:
parent
63932bab34
commit
9d1a7b9087
3 changed files with 237 additions and 227 deletions
437
j3d/j3d.c
437
j3d/j3d.c
|
@ -78,8 +78,7 @@ static float _j3VarAmbientLight = 6;
|
|||
static j3Matrix4x4T _j3VarCameraMatrix;
|
||||
static j3VertexT _j3VarCameraLocation;
|
||||
static j3FacingT _j3VarCameraAngle;
|
||||
static bool _j3VarCameraLocationDirty = true;
|
||||
static bool _j3VarCameraAngleDirty = true;
|
||||
static j3DirtynessT _j3VarCameraHowDirty = DIRTYNESS_ALL;
|
||||
static j3VertexT _j3VarSunLocation;
|
||||
|
||||
|
||||
|
@ -94,7 +93,7 @@ void j3CameraMove(float x, float y, float z) {
|
|||
_j3VarCameraLocation.x += x;
|
||||
_j3VarCameraLocation.y += y;
|
||||
_j3VarCameraLocation.z += z;
|
||||
_j3VarCameraLocationDirty = true;
|
||||
_j3VarCameraHowDirty |= DIRTYNESS_TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,7 +101,7 @@ void j3CameraMoveTo(float x, float y, float z) {
|
|||
_j3VarCameraLocation.x = x;
|
||||
_j3VarCameraLocation.y = y;
|
||||
_j3VarCameraLocation.z = z;
|
||||
_j3VarCameraLocationDirty = true;
|
||||
_j3VarCameraHowDirty |= DIRTYNESS_TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +109,7 @@ void j3CameraRotate(float x, float y, float z) {
|
|||
_j3VarCameraAngle.x += x;
|
||||
_j3VarCameraAngle.y += y;
|
||||
_j3VarCameraAngle.z += z;
|
||||
_j3VarCameraAngleDirty = true;
|
||||
_j3VarCameraHowDirty |= DIRTYNESS_ROTATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,7 +117,7 @@ void j3CameraRotateTo(float x, float y, float z) {
|
|||
_j3VarCameraAngle.x = (jint16)x;
|
||||
_j3VarCameraAngle.y = (jint16)y;
|
||||
_j3VarCameraAngle.z = (jint16)z;
|
||||
_j3VarCameraAngleDirty = true;
|
||||
_j3VarCameraHowDirty |= DIRTYNESS_ROTATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -475,7 +474,7 @@ void _j3ObjectMove(j3ObjectT *o, float x, float y, float z) {
|
|||
o->position.x += x;
|
||||
o->position.y += y;
|
||||
o->position.z += z;
|
||||
o->positionDirty = true;
|
||||
o->howDirty |= DIRTYNESS_TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -483,7 +482,7 @@ void _j3ObjectMoveTo(j3ObjectT *o, float x, float y, float z) {
|
|||
o->position.x = x;
|
||||
o->position.y = y;
|
||||
o->position.z = z;
|
||||
o->positionDirty = true;
|
||||
o->howDirty |= DIRTYNESS_TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -500,9 +499,7 @@ void _j3ObjectReset(j3ObjectT *o) {
|
|||
o->scale.y = 1;
|
||||
o->scale.z = 1;
|
||||
|
||||
o->positionDirty = true;
|
||||
o->rotationDirty = true;
|
||||
o->scaleDirty = true;
|
||||
o->howDirty = DIRTYNESS_ALL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -510,7 +507,7 @@ void _j3ObjectRotate(j3ObjectT *o, float x, float y, float z) {
|
|||
o->rotation.x += x; j3MathWrapBounds(o->rotation.x, 0, 360);
|
||||
o->rotation.y += y; j3MathWrapBounds(o->rotation.y, 0, 360);
|
||||
o->rotation.z += z; j3MathWrapBounds(o->rotation.z, 0, 360);
|
||||
o->rotationDirty = true;
|
||||
o->howDirty |= DIRTYNESS_ROTATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -518,7 +515,7 @@ void _j3ObjectRotateTo(j3ObjectT *o, float x, float y, float z) {
|
|||
o->rotation.x = x; j3MathWrapBounds(o->rotation.x, 0, 360);
|
||||
o->rotation.y = y; j3MathWrapBounds(o->rotation.y, 0, 360);
|
||||
o->rotation.z = z; j3MathWrapBounds(o->rotation.z, 0, 360);
|
||||
o->rotationDirty = true;
|
||||
o->howDirty |= DIRTYNESS_ROTATE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -526,7 +523,7 @@ void _j3ObjectScale(j3ObjectT *o, float x, float y, float z) {
|
|||
o->scale.x += x;
|
||||
o->scale.y += y;
|
||||
o->scale.z += z;
|
||||
o->scaleDirty = true;
|
||||
o->howDirty |= DIRTYNESS_SCALE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -534,7 +531,7 @@ void _j3ObjectScaleTo(j3ObjectT *o, float x, float y, float z) {
|
|||
o->scale.x = x;
|
||||
o->scale.y = y;
|
||||
o->scale.z = z;
|
||||
o->scaleDirty = true;
|
||||
o->howDirty |= DIRTYNESS_SCALE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -563,220 +560,226 @@ void _j3ObjectUpdate(j3WorldT *w, jint16 index) {
|
|||
j3Matrix4x4T translate;
|
||||
j3ObjectT *o;
|
||||
|
||||
//***TODO*** Add more copies of data and make this very incremental
|
||||
// original -> scaled -> rotated -> translated -> camera
|
||||
|
||||
o = &w->objects[index];
|
||||
|
||||
// === ROTATION ===
|
||||
|
||||
x = (jint16)o->rotation.x;
|
||||
y = (jint16)o->rotation.y;
|
||||
z = (jint16)o->rotation.z;
|
||||
|
||||
j3MathMatrix4x4Identity(final);
|
||||
|
||||
// What angles are we rotating on? By knowing this we can optimize some.
|
||||
if (x) axis += 4;
|
||||
if (y) axis += 2;
|
||||
if (z) axis += 1;
|
||||
|
||||
switch (axis) {
|
||||
case 1: // Final matrix = z
|
||||
final[0][0] = cosTable[z];
|
||||
final[0][1] = sinTable[z];
|
||||
final[1][0] = -sinTable[z];
|
||||
final[1][1] = cosTable[z];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.y * final[1][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.x * final[0][1] + o->vertices[i].local.y * final[1][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Final matrix = y
|
||||
final[0][0] = cosTable[y];
|
||||
final[0][2] = -sinTable[y];
|
||||
final[2][0] = sinTable[y];
|
||||
final[2][2] = cosTable[y];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.z * final[2][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.y;
|
||||
o->vertices[i].world.z = o->vertices[i].local.x * final[0][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // Final matrix = y * z
|
||||
final[0][0] = cosTable[y] * cosTable[z];
|
||||
final[0][1] = cosTable[y] * sinTable[z];
|
||||
final[0][2] = -sinTable[y];
|
||||
|
||||
final[1][0] = -sinTable[z];
|
||||
final[1][1] = cosTable[z];
|
||||
|
||||
final[2][0] = sinTable[y] * cosTable[z];
|
||||
final[2][1] = sinTable[y] * sinTable[z];
|
||||
final[2][2] = cosTable[y];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.y * final[1][0] + o->vertices[i].local.z * final[2][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.x * final[0][1] + o->vertices[i].local.y * final[1][1] + o->vertices[i].local.z * final[2][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.x * final[0][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // Final matrix = x
|
||||
final[1][1] = cosTable[x];
|
||||
final[1][2] = sinTable[x];
|
||||
final[2][1] = -sinTable[x];
|
||||
final[2][2] = cosTable[x];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x;
|
||||
o->vertices[i].world.y = o->vertices[i].local.y * final[1][1] + o->vertices[i].local.z * final[2][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.y * final[1][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: // Final matrix = x * z
|
||||
final[0][0] = cosTable[z];
|
||||
final[0][1] = sinTable[z];
|
||||
|
||||
final[1][0] = -cosTable[x] * sinTable[z];
|
||||
final[1][1] = cosTable[x] * cosTable[z];
|
||||
final[1][2] = sinTable[x];
|
||||
|
||||
final[2][0] = sinTable[x] * sinTable[z];
|
||||
final[2][1] = -sinTable[x] * cosTable[z];
|
||||
final[2][2] = cosTable[x];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.y * final[1][0] + o->vertices[i].local.z * final[2][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.x * final[0][1] + o->vertices[i].local.y * final[1][1] + o->vertices[i].local.z * final[2][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.y * final[1][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: // Final matrix = x * y
|
||||
final[0][0] = cosTable[y];
|
||||
final[0][2] = -sinTable[y];
|
||||
|
||||
final[1][0] = sinTable[x] * sinTable[y];
|
||||
final[1][1] = cosTable[x];
|
||||
final[1][2] = sinTable[x] * cosTable[y];
|
||||
|
||||
final[2][0] = cosTable[x] * sinTable[y];
|
||||
final[2][1] = -sinTable[x];
|
||||
final[2][2] = cosTable[x] * cosTable[y];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.y * final[1][0] + o->vertices[i].local.z * final[2][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.y * final[1][1] + o->vertices[i].local.z * final[2][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.x * final[0][2] + o->vertices[i].local.y * final[1][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // Final matrix = x * y * z
|
||||
j3MathMatrix4x4Identity(rotateX);
|
||||
rotateX[1][1] = cosTable[x];
|
||||
rotateX[1][2] = sinTable[x];
|
||||
rotateX[2][1] = -sinTable[x];
|
||||
rotateX[2][2] = cosTable[x];
|
||||
|
||||
j3MathMatrix4x4Identity(rotateY);
|
||||
rotateY[0][0] = cosTable[y];
|
||||
rotateY[0][2] = -sinTable[y];
|
||||
rotateY[2][0] = sinTable[y];
|
||||
rotateY[2][2] = cosTable[y];
|
||||
|
||||
j3MathMatrix4x4Identity(rotateZ);
|
||||
rotateZ[0][0] = cosTable[z];
|
||||
rotateZ[0][1] = sinTable[z];
|
||||
rotateZ[1][0] = -sinTable[z];
|
||||
rotateZ[1][1] = cosTable[z];
|
||||
|
||||
j3MathMatrix4x4Mult(rotateX, rotateY, temp);
|
||||
j3MathMatrix4x4Mult(temp, rotateZ, final);
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].local.x * final[0][0] + o->vertices[i].local.y * final[1][0] + o->vertices[i].local.z * final[2][0];
|
||||
o->vertices[i].world.y = o->vertices[i].local.x * final[0][1] + o->vertices[i].local.y * final[1][1] + o->vertices[i].local.z * final[2][1];
|
||||
o->vertices[i].world.z = o->vertices[i].local.x * final[0][2] + o->vertices[i].local.y * final[1][2] + o->vertices[i].local.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
// === SCALE ===
|
||||
if (o->howDirty & DIRTYNESS_SCALE) {
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].scaled.x = o->vertices[i].original.x * o->scale.x;
|
||||
o->vertices[i].scaled.y = o->vertices[i].original.y * o->scale.y;
|
||||
o->vertices[i].scaled.z = o->vertices[i].original.z * o->scale.z;
|
||||
}
|
||||
}
|
||||
|
||||
// === SCALE & TRANSLATION ===
|
||||
// === ROTATION ===
|
||||
if (o->howDirty & DIRTYNESS_ROTATE) {
|
||||
x = (jint16)o->rotation.x;
|
||||
y = (jint16)o->rotation.y;
|
||||
z = (jint16)o->rotation.z;
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].world.x = o->vertices[i].world.x * o->scale.x + o->position.x;
|
||||
o->vertices[i].world.y = o->vertices[i].world.y * o->scale.y + o->position.y;
|
||||
o->vertices[i].world.z = o->vertices[i].world.z * o->scale.z + o->position.z;
|
||||
j3MathMatrix4x4Identity(final);
|
||||
|
||||
// What angles are we rotating on? By knowing this we can optimize some.
|
||||
if (x) axis += 4;
|
||||
if (y) axis += 2;
|
||||
if (z) axis += 1;
|
||||
|
||||
switch (axis) {
|
||||
case 1: // Final matrix = z
|
||||
final[0][0] = cosTable[z];
|
||||
final[0][1] = sinTable[z];
|
||||
final[1][0] = -sinTable[z];
|
||||
final[1][1] = cosTable[z];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.y * final[1][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.x * final[0][1] + o->vertices[i].scaled.y * final[1][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Final matrix = y
|
||||
final[0][0] = cosTable[y];
|
||||
final[0][2] = -sinTable[y];
|
||||
final[2][0] = sinTable[y];
|
||||
final[2][2] = cosTable[y];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.z * final[2][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.y;
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.x * final[0][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // Final matrix = y * z
|
||||
final[0][0] = cosTable[y] * cosTable[z];
|
||||
final[0][1] = cosTable[y] * sinTable[z];
|
||||
final[0][2] = -sinTable[y];
|
||||
|
||||
final[1][0] = -sinTable[z];
|
||||
final[1][1] = cosTable[z];
|
||||
|
||||
final[2][0] = sinTable[y] * cosTable[z];
|
||||
final[2][1] = sinTable[y] * sinTable[z];
|
||||
final[2][2] = cosTable[y];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.y * final[1][0] + o->vertices[i].scaled.z * final[2][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.x * final[0][1] + o->vertices[i].scaled.y * final[1][1] + o->vertices[i].scaled.z * final[2][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.x * final[0][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // Final matrix = x
|
||||
final[1][1] = cosTable[x];
|
||||
final[1][2] = sinTable[x];
|
||||
final[2][1] = -sinTable[x];
|
||||
final[2][2] = cosTable[x];
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x;
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.y * final[1][1] + o->vertices[i].scaled.z * final[2][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.y * final[1][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: // Final matrix = x * z
|
||||
final[0][0] = cosTable[z];
|
||||
final[0][1] = sinTable[z];
|
||||
|
||||
final[1][0] = -cosTable[x] * sinTable[z];
|
||||
final[1][1] = cosTable[x] * cosTable[z];
|
||||
final[1][2] = sinTable[x];
|
||||
|
||||
final[2][0] = sinTable[x] * sinTable[z];
|
||||
final[2][1] = -sinTable[x] * cosTable[z];
|
||||
final[2][2] = cosTable[x];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.y * final[1][0] + o->vertices[i].scaled.z * final[2][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.x * final[0][1] + o->vertices[i].scaled.y * final[1][1] + o->vertices[i].scaled.z * final[2][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.y * final[1][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: // Final matrix = x * y
|
||||
final[0][0] = cosTable[y];
|
||||
final[0][2] = -sinTable[y];
|
||||
|
||||
final[1][0] = sinTable[x] * sinTable[y];
|
||||
final[1][1] = cosTable[x];
|
||||
final[1][2] = sinTable[x] * cosTable[y];
|
||||
|
||||
final[2][0] = cosTable[x] * sinTable[y];
|
||||
final[2][1] = -sinTable[x];
|
||||
final[2][2] = cosTable[x] * cosTable[y];
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.y * final[1][0] + o->vertices[i].scaled.z * final[2][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.y * final[1][1] + o->vertices[i].scaled.z * final[2][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.x * final[0][2] + o->vertices[i].scaled.y * final[1][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // Final matrix = x * y * z
|
||||
j3MathMatrix4x4Identity(rotateX);
|
||||
rotateX[1][1] = cosTable[x];
|
||||
rotateX[1][2] = sinTable[x];
|
||||
rotateX[2][1] = -sinTable[x];
|
||||
rotateX[2][2] = cosTable[x];
|
||||
|
||||
j3MathMatrix4x4Identity(rotateY);
|
||||
rotateY[0][0] = cosTable[y];
|
||||
rotateY[0][2] = -sinTable[y];
|
||||
rotateY[2][0] = sinTable[y];
|
||||
rotateY[2][2] = cosTable[y];
|
||||
|
||||
j3MathMatrix4x4Identity(rotateZ);
|
||||
rotateZ[0][0] = cosTable[z];
|
||||
rotateZ[0][1] = sinTable[z];
|
||||
rotateZ[1][0] = -sinTable[z];
|
||||
rotateZ[1][1] = cosTable[z];
|
||||
|
||||
j3MathMatrix4x4Mult(rotateX, rotateY, temp);
|
||||
j3MathMatrix4x4Mult(temp, rotateZ, final);
|
||||
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].rotated.x = o->vertices[i].scaled.x * final[0][0] + o->vertices[i].scaled.y * final[1][0] + o->vertices[i].scaled.z * final[2][0];
|
||||
o->vertices[i].rotated.y = o->vertices[i].scaled.x * final[0][1] + o->vertices[i].scaled.y * final[1][1] + o->vertices[i].scaled.z * final[2][1];
|
||||
o->vertices[i].rotated.z = o->vertices[i].scaled.x * final[0][2] + o->vertices[i].scaled.y * final[1][2] + o->vertices[i].scaled.z * final[2][2];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// === TRANSLATION ===
|
||||
if (o->howDirty & DIRTYNESS_TRANSLATE) {
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].translated.x = o->vertices[i].rotated.x + o->position.x;
|
||||
o->vertices[i].translated.y = o->vertices[i].rotated.y + o->position.y;
|
||||
o->vertices[i].translated.z = o->vertices[i].rotated.z + o->position.z;
|
||||
}
|
||||
}
|
||||
|
||||
// === CAMERA SPACE ===
|
||||
if ((_j3VarCameraHowDirty & DIRTYNESS_ROTATE) || (_j3VarCameraHowDirty & DIRTYNESS_TRANSLATE)) {
|
||||
// Create the global inverse transformation matrix used to transform world coordinate to camera coordinates
|
||||
j3MathMatrix4x4Identity(translate);
|
||||
j3MathMatrix4x4Identity(rotateX);
|
||||
j3MathMatrix4x4Identity(rotateY);
|
||||
j3MathMatrix4x4Identity(rotateZ);
|
||||
|
||||
//***TODO*** Move this when we add multiple object stuff and re-do this function
|
||||
// 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;
|
||||
|
||||
translate[3][0] = -_j3VarCameraLocation.x;
|
||||
translate[3][1] = -_j3VarCameraLocation.y;
|
||||
translate[3][2] = -_j3VarCameraLocation.z;
|
||||
// X matrix
|
||||
rotateX[1][1] = ( cosTable[_j3VarCameraAngle.x]);
|
||||
rotateX[1][2] = -( sinTable[_j3VarCameraAngle.x]);
|
||||
rotateX[2][1] = -(-sinTable[_j3VarCameraAngle.x]);
|
||||
rotateX[2][2] = ( cosTable[_j3VarCameraAngle.x]);
|
||||
|
||||
// X matrix
|
||||
rotateX[1][1] = ( cosTable[_j3VarCameraAngle.x]);
|
||||
rotateX[1][2] = -( sinTable[_j3VarCameraAngle.x]);
|
||||
rotateX[2][1] = -(-sinTable[_j3VarCameraAngle.x]);
|
||||
rotateX[2][2] = ( cosTable[_j3VarCameraAngle.x]);
|
||||
// Y matrix
|
||||
rotateY[0][0] = ( cosTable[_j3VarCameraAngle.y]);
|
||||
rotateY[0][2] = -(-sinTable[_j3VarCameraAngle.y]);
|
||||
rotateY[2][0] = -( sinTable[_j3VarCameraAngle.y]);
|
||||
rotateY[2][2] = ( cosTable[_j3VarCameraAngle.y]);
|
||||
|
||||
// Y matrix
|
||||
rotateY[0][0] = ( cosTable[_j3VarCameraAngle.y]);
|
||||
rotateY[0][2] = -(-sinTable[_j3VarCameraAngle.y]);
|
||||
rotateY[2][0] = -( sinTable[_j3VarCameraAngle.y]);
|
||||
rotateY[2][2] = ( cosTable[_j3VarCameraAngle.y]);
|
||||
// Z matrix
|
||||
rotateZ[0][0] = ( cosTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[0][1] = -( sinTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][0] = -(-sinTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][1] = ( cosTable[_j3VarCameraAngle.z]);
|
||||
|
||||
// Z matrix
|
||||
rotateZ[0][0] = ( cosTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[0][1] = -( sinTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][0] = -(-sinTable[_j3VarCameraAngle.z]);
|
||||
rotateZ[1][1] = ( cosTable[_j3VarCameraAngle.z]);
|
||||
|
||||
j3MathMatrix4x4Mult(translate, rotateX, result1);
|
||||
j3MathMatrix4x4Mult(result1, rotateY, result2);
|
||||
j3MathMatrix4x4Mult(result2, rotateZ, _j3VarCameraMatrix);
|
||||
|
||||
_j3VarCameraLocationDirty = false;
|
||||
_j3VarCameraAngleDirty = false;
|
||||
j3MathMatrix4x4Mult(translate, rotateX, result1);
|
||||
j3MathMatrix4x4Mult(result1, rotateY, result2);
|
||||
j3MathMatrix4x4Mult(result2, rotateZ, _j3VarCameraMatrix);
|
||||
|
||||
_j3VarCameraHowDirty = DIRTYNESS_CLEAN;
|
||||
}
|
||||
for (i=0; i<o->vertexCount; i++) {
|
||||
o->vertices[i].camera.x =
|
||||
o->vertices[i].world.x * _j3VarCameraMatrix[0][0] +
|
||||
o->vertices[i].world.y * _j3VarCameraMatrix[1][0] +
|
||||
o->vertices[i].world.z * _j3VarCameraMatrix[2][0] +
|
||||
o->vertices[i].translated.x * _j3VarCameraMatrix[0][0] +
|
||||
o->vertices[i].translated.y * _j3VarCameraMatrix[1][0] +
|
||||
o->vertices[i].translated.z * _j3VarCameraMatrix[2][0] +
|
||||
_j3VarCameraMatrix[3][0];
|
||||
o->vertices[i].camera.y =
|
||||
o->vertices[i].world.x * _j3VarCameraMatrix[0][1] +
|
||||
o->vertices[i].world.y * _j3VarCameraMatrix[1][1] +
|
||||
o->vertices[i].world.z * _j3VarCameraMatrix[2][1] +
|
||||
o->vertices[i].translated.x * _j3VarCameraMatrix[0][1] +
|
||||
o->vertices[i].translated.y * _j3VarCameraMatrix[1][1] +
|
||||
o->vertices[i].translated.z * _j3VarCameraMatrix[2][1] +
|
||||
_j3VarCameraMatrix[3][1];
|
||||
o->vertices[i].camera.z =
|
||||
o->vertices[i].world.x * _j3VarCameraMatrix[0][2] +
|
||||
o->vertices[i].world.y * _j3VarCameraMatrix[1][2] +
|
||||
o->vertices[i].world.z * _j3VarCameraMatrix[2][2] +
|
||||
o->vertices[i].translated.x * _j3VarCameraMatrix[0][2] +
|
||||
o->vertices[i].translated.y * _j3VarCameraMatrix[1][2] +
|
||||
o->vertices[i].translated.z * _j3VarCameraMatrix[2][2] +
|
||||
_j3VarCameraMatrix[3][2];
|
||||
}
|
||||
|
||||
// === REMOVE BACKFACES & LIGHT ===
|
||||
|
||||
// === REMOVE BACKFACES & LIGHT ===
|
||||
for (i=0; i<o->triangleCount; i++) {
|
||||
// If the scale changed, we need a new normal length
|
||||
if (o->scaleDirty) {
|
||||
if (o->howDirty & DIRTYNESS_SCALE) {
|
||||
_j3ObjectUpdateNormalLength(o, (juint16)i);
|
||||
}
|
||||
// If it's two sided, there are no backfaces
|
||||
|
@ -787,16 +790,16 @@ void _j3ObjectUpdate(j3WorldT *w, jint16 index) {
|
|||
vertex1 = o->triangles[i].index[1];
|
||||
vertex2 = o->triangles[i].index[2];
|
||||
// Vector u = v0->v1
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].world, (j3VertexT *)&o->vertices[vertex1].world, (j3Vector3DT *)&u);
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].translated, (j3VertexT *)&o->vertices[vertex1].translated, (j3Vector3DT *)&u);
|
||||
// Vector v = v0->v2
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].world, (j3VertexT *)&o->vertices[vertex2].world, (j3Vector3DT *)&v);
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].translated, (j3VertexT *)&o->vertices[vertex2].translated, (j3Vector3DT *)&v);
|
||||
// Normal v x u
|
||||
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 = _j3VarCameraLocation.x - o->vertices[vertex0].world.x;
|
||||
sight.y = _j3VarCameraLocation.y - o->vertices[vertex0].world.y;
|
||||
sight.z = _j3VarCameraLocation.z - o->vertices[vertex0].world.z;
|
||||
sight.x = _j3VarCameraLocation.x - o->vertices[vertex0].translated.x;
|
||||
sight.y = _j3VarCameraLocation.y - o->vertices[vertex0].translated.y;
|
||||
sight.z = _j3VarCameraLocation.z - o->vertices[vertex0].translated.z;
|
||||
// Compute the dot product between line of sight vector and normal to surface
|
||||
dot = j3MathDotProduct3D((j3Vector3DT *)&normal, (j3Vector3DT *)&sight);
|
||||
|
||||
|
@ -843,9 +846,9 @@ void _j3ObjectUpdate(j3WorldT *w, jint16 index) {
|
|||
vertex1 = o->triangles[i].index[1];
|
||||
vertex2 = o->triangles[i].index[2];
|
||||
// Vector u = v0->v1
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].world, (j3VertexT *)&o->vertices[vertex1].world, (j3Vector3DT *)&u);
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].translated, (j3VertexT *)&o->vertices[vertex1].translated, (j3Vector3DT *)&u);
|
||||
// Vector v = v0->v2
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].world, (j3VertexT *)&o->vertices[vertex2].world, (j3Vector3DT *)&v);
|
||||
j3MathMakeVector3D((j3VertexT *)&o->vertices[vertex0].translated, (j3VertexT *)&o->vertices[vertex2].translated, (j3Vector3DT *)&v);
|
||||
// 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
|
||||
|
@ -890,9 +893,7 @@ void _j3ObjectUpdate(j3WorldT *w, jint16 index) {
|
|||
// Z Sort the visible polygon list
|
||||
qsort((void *)w->polygons, w->polygonCount, sizeof(j3PolyListT), (j3qsortCastT)_j3PolyCompare);
|
||||
|
||||
o->positionDirty = false;
|
||||
o->rotationDirty = false;
|
||||
o->scaleDirty = false;
|
||||
o->howDirty = DIRTYNESS_CLEAN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -909,8 +910,8 @@ void _j3ObjectUpdateNormalLength(j3ObjectT *object, juint16 triangle) {
|
|||
vertex1 = object->triangles[triangle].index[1];
|
||||
vertex2 = object->triangles[triangle].index[2];
|
||||
|
||||
j3MathMakeVector3D((j3VertexT *)&object->vertices[vertex0].local, (j3VertexT *)&object->vertices[vertex1].local, (j3Vector3DT *)&u);
|
||||
j3MathMakeVector3D((j3VertexT *)&object->vertices[vertex0].local, (j3VertexT *)&object->vertices[vertex2].local, (j3Vector3DT *)&v);
|
||||
j3MathMakeVector3D((j3VertexT *)&object->vertices[vertex0].scaled, (j3VertexT *)&object->vertices[vertex1].scaled, (j3Vector3DT *)&u);
|
||||
j3MathMakeVector3D((j3VertexT *)&object->vertices[vertex0].scaled, (j3VertexT *)&object->vertices[vertex2].scaled, (j3Vector3DT *)&v);
|
||||
j3MathCrossProduct3D((j3Vector3DT *)&v, (j3Vector3DT *)&u, (j3Vector3DT *)&normal);
|
||||
|
||||
// Compute magnitude of normal, take its inverse and multiply it by
|
||||
|
@ -1342,9 +1343,9 @@ jint16 _j3WorldAddProp(j3WorldT **world, j3PropT *prop) {
|
|||
|
||||
// Copy vertex data
|
||||
for (z=0; z<prop->pieces[y].vertexCount; z++) {
|
||||
(*world)->objects[x].vertices[z].local.x = prop->pieces[y].vertices[z].x;
|
||||
(*world)->objects[x].vertices[z].local.y = prop->pieces[y].vertices[z].y;
|
||||
(*world)->objects[x].vertices[z].local.z = prop->pieces[y].vertices[z].z;
|
||||
(*world)->objects[x].vertices[z].original.x = prop->pieces[y].vertices[z].x;
|
||||
(*world)->objects[x].vertices[z].original.y = prop->pieces[y].vertices[z].y;
|
||||
(*world)->objects[x].vertices[z].original.z = prop->pieces[y].vertices[z].z;
|
||||
}
|
||||
|
||||
// Triangles
|
||||
|
|
21
j3d/j3d.h
21
j3d/j3d.h
|
@ -27,6 +27,14 @@
|
|||
#include "joey.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
DIRTYNESS_CLEAN = 0x00,
|
||||
DIRTYNESS_SCALE = 0x01,
|
||||
DIRTYNESS_ROTATE = 0x03,
|
||||
DIRTYNESS_TRANSLATE = 0x07,
|
||||
DIRTYNESS_ALL = 0xFF
|
||||
} j3DirtynessT;
|
||||
|
||||
typedef float j3Matrix4x4T[4][4];
|
||||
|
||||
typedef struct {
|
||||
|
@ -42,9 +50,12 @@ typedef struct {
|
|||
} j3VertexT, j3Vector3DT;
|
||||
|
||||
typedef struct {
|
||||
j3VertexT local; // Original vertex positions
|
||||
j3VertexT world; // After rotation, scale, translation (in that order)
|
||||
j3VertexT camera; // Camera space
|
||||
// original -> scaled -> rotated -> translated -> camera
|
||||
j3VertexT original; // Original vertex positions
|
||||
j3VertexT scaled; // After scaling
|
||||
j3VertexT rotated; // After rotation (aka "local")
|
||||
j3VertexT translated; // After translation (aka "world")
|
||||
j3VertexT camera; // Camera space
|
||||
} j3CoordinatesT;
|
||||
|
||||
typedef struct {
|
||||
|
@ -74,9 +85,7 @@ typedef struct {
|
|||
j3VertexT position; // Position of object in world
|
||||
j3VertexT rotation; // Rotation of object in world
|
||||
j3VertexT scale; // Scale of object in world
|
||||
bool positionDirty; // Did the position change?
|
||||
bool rotationDirty; // Did the rotation change?
|
||||
bool scaleDirty; // Did the scale change?
|
||||
j3DirtynessT howDirty; // How much do we need to recalculate?
|
||||
} j3ObjectT;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -105,9 +105,9 @@ int main(void) {
|
|||
for (y=0; y<world->objects[x].vertexCount; y++) {
|
||||
printf(" Vertex %d: %f %f %f\n",
|
||||
y,
|
||||
(double)world->objects[x].vertices[y].local.x,
|
||||
(double)world->objects[x].vertices[y].local.y,
|
||||
(double)world->objects[x].vertices[y].local.z
|
||||
(double)world->objects[x].vertices[y].original.x,
|
||||
(double)world->objects[x].vertices[y].original.y,
|
||||
(double)world->objects[x].vertices[y].original.z
|
||||
);
|
||||
}
|
||||
printf(" Triangles: %d\n", world->objects[x].triangleCount);
|
||||
|
|
Loading…
Add table
Reference in a new issue