Move camera/render funcs to functions, fix camera stutter

This commit is contained in:
ABelliqueux 2021-07-12 13:00:19 +02:00
parent a3126738c8
commit 25b5c61633
8 changed files with 308 additions and 306 deletions

View File

@ -28,3 +28,5 @@ void getCameraXZY(int * x, int * z, int * y, int actorX, int actorZ, int actorY,
void getCameraZY( int * z, int * y, int actorZ, int actorY, int angleX, int distance);
void applyCamera(CAMERA * cam);
void setCameraPos(CAMERA * camera, SVECTOR * pos, SVECTOR * rot);
void setCameraMode(LEVEL * curLvl, CAMERA * camera, VECTOR * camAngleToAct, VECTOR * posToActor, VECTOR * angle, VECTOR * angleCam, short curCamAngle, int camMode, int * lerping);

View File

@ -4,6 +4,7 @@
#include "../include/defines.h"
// Drawing
void updateLight(void);
void transformMesh(CAMERA * camera, MESH * meshes);
void enlightMesh(LEVEL * curLvl, MESH * actorPtr, SVECTOR * lgtang);
void drawPoly(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw);
@ -22,3 +23,5 @@ int set4Subdiv(MESH * mesh, POLY_GT4 * poly4, u_long * ot, long t, int i, char *
long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t);
//2D drawing
void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db);
// Rendering
void renderScene(LEVEL * curLvl, CAMERA * camera, int * camMode, char ** nextpri, u_long * ot, u_long * otdisc, char * db, DRAWENV * draw, short curCamAngle, int atime);

View File

@ -1,6 +1,7 @@
#pragma once
#include <sys/types.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include "../include/defines.h"
#include "../include/macros.h"
@ -14,4 +15,4 @@ void checkBodyCol(BODY * one, BODY * two);
void applyAngMom(LEVEL curLvl );
void ResolveCollision( BODY * one, BODY * two );
VECTOR angularMom(BODY body);
void applyAcceleration(BODY * actor);
void applyAcceleration(BODY * actor, ulong oldTime);

View File

@ -1,6 +1,8 @@
#include "../include/psx.h"
#include "../include/camera.h"
#include "../include/math.h"
#include "../include/physics.h"
#include "../include/space.h"
void getCameraXZ(int * x, int * z, int actorX, int actorZ, int angle, int distance) {
// Using Nic's Costable : https://github.com/grumpycoders/Balau/blob/master/tests/test-Handles.cc#L20-L102
@ -32,3 +34,171 @@ void setCameraPos( CAMERA * camera, SVECTOR * pos, SVECTOR * rot ) {
copyVector(camera->pos, pos);
copyVector(camera->rot, rot);
};
void setCameraMode(LEVEL * curLvl, CAMERA * camera, VECTOR * camAngleToAct, VECTOR * posToActor, VECTOR * angle, VECTOR * angleCam, short curCamAngle, int camMode, int * lerping){
int dist = 0;
short cameraSpeed = 40;
//~ if(camMode != 2) {
//~ camera->rot->vy = camAngleToAct->vy;
//~ // using csin/ccos, no need for theta
//~ camera->rot->vx = camAngleToAct->vx;
//~ }
if(camMode < 4 ) {
*lerping = 0;
}
switch (camMode){
// Camera follows actor
case 0 :
dist = 200;
setVector(camera->pos, -(camera->x/ONE), -(camera->y/ONE), -(camera->z/ONE));
angle->vy = -(curLvl->actorPtr->rot.vy / 2) + angleCam->vy;
// Camera horizontal and vertical position
getCameraZY(&camera->z, &camera->y, curLvl->actorPtr->pos.vz, curLvl->actorPtr->pos.vy, angle->vx, dist);
getCameraXZ(&camera->x, &camera->z, curLvl->actorPtr->pos.vx, curLvl->actorPtr->pos.vz, angle->vy, dist);
break;
// Camera rotates continuously around actor
case 1 :
// Set distance between cam and actor
dist = 150;
// Set camera position
setVector(camera->pos, -(camera->x/ONE), 100, -(camera->z/ONE));
// Find new camera position
getCameraXZ(&camera->x, &camera->z, curLvl->actorPtr->pos.vx, curLvl->actorPtr->pos.vz, angle->vy, dist);
// Set rotation amount
angle->vy += 10;
break;
// Fixed Camera angle
case 2 :
// If BG images exist
if (curLvl->camPtr->tim_data){
checkLineW( &curLvl->camAngles[ curCamAngle ]->fw.v3, &curLvl->camAngles[ curCamAngle ]->fw.v2, curLvl->actorPtr);
if ( curLvl->camAngles[ curCamAngle ]->fw.v0.vx ) {
// If actor in camAngle->fw area of screen
if ( checkLineW( &curLvl->camAngles[ curCamAngle ]->fw.v3, &curLvl->camAngles[ curCamAngle ]->fw.v2, curLvl->actorPtr) == -1 &&
( checkLineW( &curLvl->camAngles[ curCamAngle ]->bw.v2, &curLvl->camAngles[ curCamAngle ]->bw.v3, curLvl->actorPtr) >= 0
)
) {
if (curCamAngle < 5) {
curCamAngle++;
curLvl->camPtr = curLvl->camAngles[ curCamAngle ];
LoadTexture(curLvl->camPtr->tim_data, curLvl->camPtr->BGtim);
}
}
}
if ( curLvl->camAngles[ curCamAngle ]->bw.v0.vx ) {
// If actor in camAngle->bw area of screen
if ( checkLineW( &curLvl->camAngles[ curCamAngle ]->fw.v3, &curLvl->camAngles[ curCamAngle ]->fw.v2, curLvl->actorPtr) >= 0 &&
checkLineW( &curLvl->camAngles[ curCamAngle ]->bw.v2, &curLvl->camAngles[ curCamAngle ]->bw.v3, curLvl->actorPtr) == -1
) {
if (curCamAngle > 0) {
curCamAngle--;
curLvl->camPtr = curLvl->camAngles[ curCamAngle ];
LoadTexture(curLvl->camPtr->tim_data, curLvl->camPtr->BGtim);
}
}
}
worldToScreen( &curLvl->actorPtr->pos, &curLvl->actorPtr->pos2D );
}
setCameraPos(camera, &curLvl->camPtr->campos->pos, &curLvl->camPtr->campos->rot);
break;
// Fixed Camera with actor tracking
case 3 :
// Using precalc sqrt
dist = psqrt( (posToActor->vx * posToActor->vx ) + (posToActor->vz * posToActor->vz) );
// Set camera position
setVector(camera->pos, 190, 100, 180);
break;
// Flyby mode with LERP from camStart to camEnd
case 4 :
// If key pos exist for camera
if (curLvl->camPath->len) {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(camera->pos, &curLvl->camPath->points[curLvl->camPath->cursor]);
// Lerping sequence is starting
*lerping = 1;
// Set cam pos index to 0
curLvl->camPath->pos = 0;
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor->vx * posToActor->vx ) + (posToActor->vz * posToActor->vz));
// Fixed point precision 2^12 == 4096
int precision = 12;
setVector( camera->pos,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vx << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vx << precision, curLvl->camPath->pos << precision) >> precision,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vy << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vy << precision, curLvl->camPath->pos << precision) >> precision,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vz << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vz << precision, curLvl->camPath->pos << precision) >> precision
);
// Linearly increment the lerp factor
curLvl->camPath->pos += 20;
// If camera has reached next key pos, reset pos index, move cursor to next key pos
if (curLvl->camPath->pos > (1 << precision) ){
curLvl->camPath->pos = 0;
curLvl->camPath->cursor ++;
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
if ( curLvl->camPath->cursor == curLvl->camPath->len - 1 ){
lerping = 0;
curLvl->camPath->cursor = 0;
}
} else {
// if no key pos exists, switch to next camMode
camMode ++;
}
break;
// Camera "on a rail" - cam is tracking actor, and moving with constraints on all axis
case 5 :
// track actor. If theta (actor/cam rotation angle) is above or below an arbitrary angle,
// move cam so that the angle doesn't increase/decrease anymore.
if (curLvl->camPath->len) {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(camera->pos, &curLvl->camPath->points[curLvl->camPath->cursor]);
// Lerping sequence is starting
*lerping = 1;
// Set cam pos index to 0
curLvl->camPath->pos = 0;
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor->vx * posToActor->vx ) + (posToActor->vz * posToActor->vz));
// Fixed point precision 2^12 == 4096
short precision = 12;
setVector( camera->pos,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vx << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vx << precision, curLvl->camPath->pos << precision) >> precision,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vy << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vy << precision, curLvl->camPath->pos << precision) >> precision,
lerpD(curLvl->camPath->points[curLvl->camPath->cursor].vz << precision, curLvl->camPath->points[curLvl->camPath->cursor+1].vz << precision, curLvl->camPath->pos << precision) >> precision
);
// Ony move cam if position is between first curLvl->camPath->vx and last curLvl->camPath->vx
if ( camAngleToAct->vy < -50 && camera->pos->vx > curLvl->camPath->points[curLvl->camPath->len - 1].vx ) {
// Clamp curLvl->camPath position to cameraSpeed
curLvl->camPath->pos += dist < cameraSpeed ? 0 : cameraSpeed ;
}
if ( camAngleToAct->vy > 50 && camera->pos->vx > curLvl->camPath->points[curLvl->camPath->cursor].vx ) {
curLvl->camPath->pos -= dist < cameraSpeed ? 0 : cameraSpeed;
}
// If camera has reached next key pos, reset pos index, move cursor to next key pos
if (curLvl->camPath->pos > (1 << precision) ){
curLvl->camPath->pos = 0;
curLvl->camPath->cursor ++;
}
if (curLvl->camPath->pos < -100 ){
curLvl->camPath->pos = 1 << precision;
curLvl->camPath->cursor --;
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
if ( curLvl->camPath->cursor == curLvl->camPath->len - 1 || curLvl->camPath->cursor < 0 ){
*lerping = 0;
curLvl->camPath->cursor = 0;
}
} else {
// if no key pos exists, switch to next camMode
camMode ++;
}
break;
}
};

View File

@ -3,14 +3,11 @@
#include "../include/math.h"
#include "../include/CPUMAC.H"
// Declare registers 16 19 23
//~ register ulong ur0 asm("$16");
//~ register ulong ur1 asm("$19");
//~ register ulong ur2 asm("$20");
//~ register ulong ur3 asm("$23");
//~ register ulong ur4 asm("$21");
//~ register ulong ur5 asm("$22");
void updateLight(void){
RotMatrix_gte(dc_lgtangp, dc_lgtmatp);
gte_MulMatrix0(dc_lvllgtmatp, dc_lgtmatp, dc_lgtmatp);
gte_SetLightMatrix(dc_lgtmatp);
}
void enlightMesh(LEVEL * curLvl, MESH * mesh, SVECTOR * lgtang){
// Update light rotation on actor
//~ MATRIX rotlgt, rotmesh, light;
@ -29,23 +26,6 @@ void transformMesh(CAMERA * camera, MESH * mesh){
TransMatrix(dc_wrkmatp, &mesh->pos);
// Compose matrix with cam
gte_CompMatrix(dc_camMat, dc_wrkmatp, dc_wrkmatp);
//gte_MulMatrix0(&camera->mat, &mat, &mat);
//~ gte_SetRotMatrix(&camera->mat);
//~ gte_ldclmv(&mat);
//~ gte_rtir();
//~ gte_stclmv(&mat);
//~ gte_ldclmv((char*)&mat+2);
//~ gte_rtir();
//~ gte_stclmv((char*)&mat+2);
//~ gte_ldclmv((char*)&mat+4);
//~ gte_rtir();
//~ gte_stclmv((char*)&mat+4);
//~ //
//~ gte_SetTransMatrix(&camera->mat);
//~ gte_ldlv0((char*)&mat+20);
//~ gte_rt();
//~ gte_stlvnl((char*)&mat+20);
// Set default rotation and translation matrices
gte_SetRotMatrix(dc_wrkmatp);
gte_SetTransMatrix(dc_wrkmatp);
//~ }
@ -545,3 +525,44 @@ void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db) {
addPrim( otdisc[ OT2LEN-1 ], tpage );
*nextpri += sizeof( DR_TPAGE );
};
void renderScene(LEVEL * curLvl, CAMERA * camera, int * camMode, char ** nextpri, u_long * ot, u_long * otdisc, char * db, DRAWENV * draw, short curCamAngle, int atime){
if ( (*camMode == 2) && (curLvl->camPtr->tim_data ) ) {
drawBG(curLvl->camPtr, nextpri, otdisc, db);
// Loop on camAngles
for ( int mesh = 0 ; mesh < curLvl->camAngles[ curCamAngle ]->index; mesh ++ ) {
enlightMesh(curLvl, curLvl->camAngles[curCamAngle]->objects[mesh], dc_lgtangp);
transformMesh(camera, curLvl->camAngles[curCamAngle]->objects[mesh]);
drawPoly(curLvl->camAngles[curCamAngle]->objects[mesh], atime, camMode, nextpri, ot, db, draw);
}
}
else {
// Draw current node's plane
drawPoly( curLvl->curNode->plane, atime, camMode, nextpri, &ot[*db], db, &draw[*db]);
// Draw surrounding planes
for ( int sibling = 0; sibling < curLvl->curNode->siblings->index; sibling++ ) {
drawPoly(curLvl->curNode->siblings->list[ sibling ]->plane, atime, camMode, nextpri, &ot[*db], db, &draw[*db]);
}
// Draw adjacent planes's children
for ( int sibling = 0; sibling < curLvl->curNode->siblings->index; sibling++ ) {
for ( int object = 0; object < curLvl->curNode->siblings->list[ sibling ]->objects->index; object++ ) {
long t = 0;
enlightMesh(curLvl, curLvl->curNode->siblings->list[ sibling ]->objects->list[ object ], dc_lgtangp);
transformMesh(camera, curLvl->curNode->siblings->list[ sibling ]->objects->list[ object ]);
drawPoly( curLvl->curNode->siblings->list[ sibling ]->objects->list[ object ], atime, camMode, nextpri, &ot[*db], db, &draw[*db]);
}
}
// Draw current plane children
for ( int object = 0; object < curLvl->curNode->objects->index; object++ ) {
enlightMesh(curLvl, curLvl->curNode->objects->list[ object ], dc_lgtangp);
transformMesh(camera, curLvl->curNode->objects->list[ object ]);
drawPoly( curLvl->curNode->objects->list[ object ], atime, camMode, nextpri, &ot[*db], db, &draw[*db]);
}
// Draw rigidbodies
for ( int object = 0; object < curLvl->curNode->rigidbodies->index; object++ ) {
enlightMesh(curLvl, curLvl->curNode->rigidbodies->list[ object ], dc_lgtangp);
transformMesh(camera, curLvl->curNode->rigidbodies->list[ object ]);
drawPoly( curLvl->curNode->rigidbodies->list[ object ], atime, camMode, nextpri, &ot[*db], db, &draw[*db]);
}
}
updateLight();
};

View File

@ -25,7 +25,7 @@
#include "../include/graphics.h"
#include "../include/space.h"
#define USECD
//~ #define USECD
// START OVERLAY
extern u_long load_all_overlays_here;
@ -73,6 +73,8 @@ u_short timer = 0;
int camMode = ACTOR; // Cam mode, see defines.h, l.6
VECTOR angle = {250,0,0,0};
VECTOR angleCam = {0,0,0,0};
VECTOR posToActor = {0, 0, 0, 0}; // position of camera relative to actor
VECTOR camAngleToAct = {0, 0, 0, 0}; // rotation angles for the camera to point at actor
int dist = 150;
int lerping = 0;
short curCamAngle = 0;
@ -89,6 +91,17 @@ short angleCamTimer = 0;
short forceApplied = 0;
// Callback function is used for pads
void callback();
// variable FPS
ulong oldTime = 0;
// Physics/collisions
short physics = 1;
VECTOR col = {0};
// Animation timing
// time % timediv == animation time
// Time divisor
short timediv = 1;
// Animation time, see l.206
int atime = 0;
int main() {
// Set matrices pointers to scratchpad
camera.mat = dc_camMat;
@ -139,18 +152,6 @@ int main() {
if (curLvl.camPtr->tim_data){
LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim);
}
// Physics/collisions
short physics = 1;
VECTOR col = {0};
// Cam stuff
VECTOR posToActor = {0, 0, 0, 0}; // position of camera relative to actor
VECTOR camAngleToAct = {0, 0, 0, 0}; // rotation angles for the camera to point at actor
// Animation timing
// time % timediv == animation time
// Time divisor
short timediv = 1;
// Animation time, see l.206
int atime = 0;
// Polycount
for (int k = 0; k < *curLvl.meshes_length; k++){
triCount += curLvl.meshes[k]->tmesh->len;
@ -165,6 +166,7 @@ int main() {
}
// Main loop
while ( VSync(VSYNC) ) {
oldTime = VSync(-1);
//~ timeS = VSync(-1) / 60;
// Check if level has changed
// TODO : Proper level system / loader
@ -197,185 +199,12 @@ int main() {
levelWas = level;
}
FntPrint("Ovl:%s\nLvl : %x\nLvl: %d %d \n%x", overlayFile, &level, level, levelWas, loadLvl);
// Clear the main OT
ClearOTagR(otdisc[db], OT2LEN);
// Clear Secondary OT
ClearOTagR(ot[db], OTLEN);
time ++;
// atime is used for animations timing
timediv = 1;
// If timediv is > 1, animation time will be slower
if (time % timediv == 0){
atime ++;
}
// Angle between camera and actor
// using atantable (faster)
camAngleToAct.vy = (patan(-posToActor.vx, -posToActor.vz) / 16) - 3076 ;
camAngleToAct.vx = patan(dist, posToActor.vy) >> 4;
// Find Actor's forward vector
setVector( &fVecActor,
curLvl.actorPtr->pos.vx + (nsin(curLvl.actorPtr->rot.vy/2)),
curLvl.actorPtr->pos.vy,
curLvl.actorPtr->pos.vz - (ncos(curLvl.actorPtr->rot.vy/2))
);
// Camera modes
if(camMode != 2) {
camera.rot->vy = camAngleToAct.vy;
// using csin/ccos, no need for theta
camera.rot->vx = camAngleToAct.vx;
}
if(camMode < 4 ) {
lerping = 0;
}
// Camera follows actor
if(camMode == 0) {
dist = 200;
setVector(camera.pos, -(camera.x/ONE), -(camera.y/ONE), -(camera.z/ONE));
angle.vy = -(curLvl.actorPtr->rot.vy / 2) + angleCam.vy;
// Camera horizontal and vertical position
getCameraZY(&camera.z, &camera.y, curLvl.actorPtr->pos.vz, curLvl.actorPtr->pos.vy, angle.vx, dist);
getCameraXZ(&camera.x, &camera.z, curLvl.actorPtr->pos.vx, curLvl.actorPtr->pos.vz, angle.vy, dist);
}
// Camera rotates continuously around actor
if (camMode == 1) {
// Set distance between cam and actor
dist = 150;
// Set camera position
setVector(camera.pos, -(camera.x/ONE), 100, -(camera.z/ONE));
// Find new camera position
getCameraXZ(&camera.x, &camera.z, curLvl.actorPtr->pos.vx, curLvl.actorPtr->pos.vz, angle.vy, dist);
// Set rotation amount
angle.vy += 10;
}
// Fixed Camera with actor tracking
if (camMode == 3) {
// Using precalc sqrt
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz) );
// Set camera position
setVector(camera.pos, 190, 100, 180);
}
// Fixed Camera angle
if (camMode == 2) {
// If BG images exist
if (curLvl.camPtr->tim_data){
checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr);
if ( curLvl.camAngles[ curCamAngle ]->fw.v0.vx ) {
// If actor in camAngle->fw area of screen
if ( checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr) == -1 &&
( checkLineW( &curLvl.camAngles[ curCamAngle ]->bw.v2, &curLvl.camAngles[ curCamAngle ]->bw.v3, curLvl.actorPtr) >= 0
)
) {
if (curCamAngle < 5) {
curCamAngle++;
curLvl.camPtr = curLvl.camAngles[ curCamAngle ];
LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim);
}
}
}
if ( curLvl.camAngles[ curCamAngle ]->bw.v0.vx ) {
// If actor in camAngle->bw area of screen
if ( checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr) >= 0 &&
checkLineW( &curLvl.camAngles[ curCamAngle ]->bw.v2, &curLvl.camAngles[ curCamAngle ]->bw.v3, curLvl.actorPtr) == -1
) {
if (curCamAngle > 0) {
curCamAngle--;
curLvl.camPtr = curLvl.camAngles[ curCamAngle ];
LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim);
}
}
}
}
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
}
// Flyby mode with LERP from camStart to camEnd
if (camMode == 4) {
// If key pos exist for camera
if (curLvl.camPath->len) {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
curLvl.camPath->pos = 0;
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
int precision = 12;
setVector( camera.pos,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vx << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vx << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vy << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vy << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vz << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vz << precision, curLvl.camPath->pos << precision) >> precision
);
// Linearly increment the lerp factor
curLvl.camPath->pos += 20;
// If camera has reached next key pos, reset pos index, move cursor to next key pos
if (curLvl.camPath->pos > (1 << precision) ){
curLvl.camPath->pos = 0;
curLvl.camPath->cursor ++;
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
if ( curLvl.camPath->cursor == curLvl.camPath->len - 1 ){
lerping = 0;
curLvl.camPath->cursor = 0;
}
} else {
// if no key pos exists, switch to next camMode
camMode ++; }
}
// Camera "on a rail" - cam is tracking actor, and moving with constraints on all axis
if (camMode == 5) {
// track actor. If theta (actor/cam rotation angle) is above or below an arbitrary angle,
// move cam so that the angle doesn't increase/decrease anymore.
short cameraSpeed = 40;
if (curLvl.camPath->len) {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
curLvl.camPath->pos = 0;
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
short precision = 12;
setVector( camera.pos,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vx << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vx << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vy << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vy << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vz << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vz << precision, curLvl.camPath->pos << precision) >> precision
);
// Ony move cam if position is between first curLvl.camPath->vx and last curLvl.camPath->vx
if ( camAngleToAct.vy < -50 && camera.pos->vx > curLvl.camPath->points[curLvl.camPath->len - 1].vx ) {
// Clamp curLvl.camPath position to cameraSpeed
curLvl.camPath->pos += dist < cameraSpeed ? 0 : cameraSpeed ;
}
if ( camAngleToAct.vy > 50 && camera.pos->vx > curLvl.camPath->points[curLvl.camPath->cursor].vx ) {
curLvl.camPath->pos -= dist < cameraSpeed ? 0 : cameraSpeed;
}
// If camera has reached next key pos, reset pos index, move cursor to next key pos
if (curLvl.camPath->pos > (1 << precision) ){
curLvl.camPath->pos = 0;
curLvl.camPath->cursor ++;
}
if (curLvl.camPath->pos < -100 ){
curLvl.camPath->pos = 1 << precision;
curLvl.camPath->cursor --;
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
if ( curLvl.camPath->cursor == curLvl.camPath->len - 1 || curLvl.camPath->cursor < 0 ){
lerping = 0;
curLvl.camPath->cursor = 0;
}
} else {
// if no key pos exists, switch to next camMode
camMode ++;
}
}
// Spatial partitioning
if (curLvl.curNode){
for ( int msh = 0; msh < curLvl.curNode->siblings->index; msh ++ ) {
@ -397,98 +226,73 @@ int main() {
// Physics
if ( physics ) {
// if(time%1 == 0){
for ( int k = 0; k < *curLvl.meshes_length; k ++ ) {
if ( curLvl.meshes[k]->isRigidBody == 1 ) {
applyAcceleration( curLvl.meshes[k]->body );
// Get col between actor and level
if ( curLvl.meshes[k]->isActor ){
checkBodyCol( curLvl.meshes[k]->body , curLvl.levelPtr->body );
}
// Get col between props and level
if ( curLvl.meshes[k]->isProp ){
checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body );
}
// Only evaluate collision if actor is on same plane as prop
if ( curLvl.curNode == curLvl.propPtr->node ){
// Get col between actor and props
col = getExtCollision( *curLvl.meshes[k]->body, *curLvl.propPtr->body );
if (col.vx && col.vz ) {
setVector( &curLvl.propPtr->body->velocity,
curLvl.meshes[k]->body->velocity.vx,
0,
curLvl.meshes[k]->body->velocity.vz
);
// If prop is spherical, make it roll
applyAngMom(curLvl);
}
}
// Synchronize mesh to body position
copyVector(&curLvl.meshes[k]->pos, &curLvl.meshes[k]->body->position);
for ( int k = 0; k < *curLvl.meshes_length; k ++ ) {
if ( curLvl.meshes[k]->isRigidBody == 1 ) {
applyAcceleration( curLvl.meshes[k]->body , oldTime);
// Get col between actor and level
if ( curLvl.meshes[k]->isActor ){
checkBodyCol( curLvl.meshes[k]->body , curLvl.levelPtr->body );
}
setVector(&curLvl.meshes[k]->body->velocity, 0, 0, 0);
// Get col between props and level
if ( curLvl.meshes[k]->isProp ){
checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body );
}
// Only evaluate collision if actor is on same plane as prop
if ( curLvl.curNode == curLvl.propPtr->node ){
// Get col between actor and props
col = getExtCollision( *curLvl.meshes[k]->body, *curLvl.propPtr->body );
if (col.vx && col.vz ) {
setVector( &curLvl.propPtr->body->velocity,
curLvl.meshes[k]->body->velocity.vx,
0,
curLvl.meshes[k]->body->velocity.vz
);
// If prop is spherical, make it roll
applyAngMom(curLvl);
}
}
// Synchronize mesh to body position
copyVector(&curLvl.meshes[k]->pos, &curLvl.meshes[k]->body->position);
}
setVector(&curLvl.meshes[k]->body->velocity, 0, 0, 0);
}
}
// Get actor's screen coordinates (used with fixed BGs)
if ( (camMode == 2) && (curLvl.camPtr->tim_data ) ) {
worldToScreen( &curLvl.actorPtr->pos, &curLvl.actorPtr->pos2D );
}
// Camera setup
// Clear the main OT
ClearOTagR(otdisc[db], OT2LEN);
// Clear Secondary OT
ClearOTagR(ot[db], OTLEN);
// Set camera according to mode
setCameraMode(&curLvl, &camera, &camAngleToAct, &posToActor, &angle, &angleCam, curCamAngle, camMode, &lerping);
// Render scene
renderScene(&curLvl, &camera, &camMode, &nextpri, ot[db], otdisc[db], &db, &draw[db], curCamAngle, atime);
// Set camera
// Get position of cam relative to actor
addVector2(&curLvl.actorPtr->pos, camera.pos, &posToActor);
// Polygon drawing
if (curLvl.curNode){
if ( (camMode == 2) && (curLvl.camPtr->tim_data ) ) {
drawBG(curLvl.camPtr, &nextpri, otdisc[db], &db);
// Loop on camAngles
for ( int mesh = 0 ; mesh < curLvl.camAngles[ curCamAngle ]->index; mesh ++ ) {
enlightMesh(&curLvl, curLvl.camAngles[curCamAngle]->objects[mesh], dc_lgtangp);
transformMesh(&camera, curLvl.camAngles[curCamAngle]->objects[mesh]);
drawPoly(curLvl.camAngles[curCamAngle]->objects[mesh], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
else {
// Draw current node's plane
drawPoly( curLvl.curNode->plane, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
// Draw surrounding planes
for ( int sibling = 0; sibling < curLvl.curNode->siblings->index; sibling++ ) {
drawPoly(curLvl.curNode->siblings->list[ sibling ]->plane, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
// Draw adjacent planes's children
for ( int sibling = 0; sibling < curLvl.curNode->siblings->index; sibling++ ) {
for ( int object = 0; object < curLvl.curNode->siblings->list[ sibling ]->objects->index; object++ ) {
long t = 0;
enlightMesh(&curLvl, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ]);
drawPoly( curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
// Draw current plane children
for ( int object = 0; object < curLvl.curNode->objects->index; object++ ) {
enlightMesh(&curLvl, curLvl.curNode->objects->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->objects->list[ object ]);
drawPoly( curLvl.curNode->objects->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
// Draw rigidbodies
for ( int object = 0; object < curLvl.curNode->rigidbodies->index; object++ ) {
enlightMesh(&curLvl, curLvl.curNode->rigidbodies->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->rigidbodies->list[ object ]);
drawPoly( curLvl.curNode->rigidbodies->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
}
// Update global light matrix - use scratchpad
RotMatrix_gte(dc_lgtangp, dc_lgtmatp);
gte_MulMatrix0(dc_lvllgtmatp, dc_lgtmatp, dc_lgtmatp);
gte_SetLightMatrix(dc_lgtmatp);
// Set camera
// Angle between camera and actor
// using atantable (faster)
camAngleToAct.vy = (patan(-posToActor.vx, -posToActor.vz) / 16) - 3076 ;
camAngleToAct.vx = (patan(dist, posToActor.vy) >> 4 ) - 256;
camera.rot->vy = camAngleToAct.vy;
// using csin/ccos, no need for theta
camera.rot->vx = camAngleToAct.vx;
applyCamera(&camera);
// Add secondary OT to main OT
// Find Actor's forward vector
setVector( &fVecActor,
curLvl.actorPtr->pos.vx + (nsin(curLvl.actorPtr->rot.vy/2)),
curLvl.actorPtr->pos.vy,
curLvl.actorPtr->pos.vz - (ncos(curLvl.actorPtr->rot.vy/2))
);
// Add secondary OT to main OT
AddPrims(otdisc[db], ot[db] + OTLEN - 1, ot[db]);
FntPrint("Time : %d\n", time);
FntPrint("\nTime : %d\n", time);
//~ FntPrint("Ticks : %d %d \n", oldTime, VSync(-1)-oldTime);
FntPrint("cam : %d \n", camMode);
FntPrint("#Tri : %d\n", triCount);
FntPrint("# : %d %d\n", sizeof(VECTOR), sizeof(CAMERA) );
FntFlush(-1);
display( &disp[db], &draw[db], otdisc[db], primbuff[db], &nextpri, &db);
}
@ -524,7 +328,7 @@ void callback() {
}
if ( PADR & PadShldR1 && !timer ) {
if (!curLvl.camPtr->tim_data){
if(camMode < 6){
if(camMode < 5){
camMode ++;
lerping = 0;
} else {

View File

@ -126,17 +126,19 @@ void applyAngMom(LEVEL curLvl ){
}
}
};
void applyAcceleration(BODY * actor){
short dt = 1;
void applyAcceleration(BODY * actor, ulong oldTime){
short dt = VSync(-1) - oldTime ;
//~ short dt = 3;
if (dt < 1) { dt = 1; }
VECTOR acceleration = {actor->invMass * actor->gForce.vx , (actor->invMass * actor->gForce.vy) + (GRAVITY * ONE), actor->invMass * actor->gForce.vz};
//~ FntPrint("acc: %d %d %d\n", acceleration.vx, acceleration.vy, acceleration.vz );
actor->velocity.vx += (acceleration.vx * dt) >> 12;
actor->velocity.vy += (acceleration.vy * dt) >> 12;
actor->velocity.vz += (acceleration.vz * dt) >> 12;
actor->velocity.vx += (acceleration.vx * (ONE / dt) ) >> 24;
actor->velocity.vy += (acceleration.vy * (ONE / dt) ) >> 24;
actor->velocity.vz += (acceleration.vz * (ONE / dt) ) >> 24;
//~ FntPrint("acc: %d %d %d\n", acceleration.vx / ONE, acceleration.vy / ONE, acceleration.vz / ONE );
actor->position.vx += (actor->velocity.vx * dt);
actor->position.vy += (actor->velocity.vy * dt);
actor->position.vz += (actor->velocity.vz * dt);
actor->position.vx += (actor->velocity.vx * (ONE / dt) ) >> 12;
actor->position.vy += (actor->velocity.vy * (ONE / dt) ) >> 12;
actor->position.vz += (actor->velocity.vz * (ONE / dt) ) >> 12;
//~ FntPrint("vel: %d %d %d\n", actor->velocity.vx, actor->velocity.vy, actor->velocity.vz );
};
//~ // https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331

View File

@ -31,7 +31,6 @@ void init(DISPENV disp[2], DRAWENV draw[2], short db, CVECTOR * BGc, VECTOR * BK
InitGeom();
SetGeomOffset( CENTERX, CENTERY ); // x, y offset
SetGeomScreen( FOV ); // Distance between eye and screen - Camera FOV
SetDispMask(1);
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);