From: Cirilo B. <pin...@us...> - 2004-11-20 23:54:12
|
Update of /cvsroot/once/oncecode/src/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26746/client Modified Files: occltbehave.cpp occltbehave.h ocdisplay.cpp Log Message: Beginnings of the camera system - use a and z to zoom Index: occltbehave.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/client/occltbehave.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** occltbehave.cpp 20 Nov 2004 08:20:10 -0000 1.8 --- occltbehave.cpp 20 Nov 2004 23:52:51 -0000 1.9 *************** *** 62,65 **** --- 62,73 ---- csStringID ocPlayerBehaviour::rot_right_rep; csStringID ocPlayerBehaviour::timer_wakeupframe; + csStringID ocPlayerBehaviour::zoomIn0; + csStringID ocPlayerBehaviour::zoomIn1; + csStringID ocPlayerBehaviour::zoomOut0; + csStringID ocPlayerBehaviour::zoomOut1; + csStringID ocPlayerBehaviour::run_rep; + csStringID ocPlayerBehaviour::zoomIn_rep; + csStringID ocPlayerBehaviour::zoomOut_rep; + void ocPlayerBehaviour::RegisterStringIDs(iCelPlLayer *pl) *************** *** 80,84 **** --- 88,99 ---- rot_left_rep = pl->FetchStringID("pckeyinput_rot_left_"); rot_right_rep = pl->FetchStringID("pckeyinput_rot_right_"); + run_rep = pl->FetchStringID("pckeyinput_run_"); + zoomIn_rep = pl->FetchStringID("pckeyinput_zoomIn_"); + zoomOut_rep = pl->FetchStringID("pckeyinput_zoomOut_"); timer_wakeupframe = pl->FetchStringID("pctimer_wakeupframe"); + zoomIn0 = pl->FetchStringID("pckeyinput_zoomIn0"); + zoomIn1 = pl->FetchStringID("pckeyinput_zoomIn1"); + zoomOut0 = pl->FetchStringID("pckeyinput_zoomOut0"); + zoomOut1 = pl->FetchStringID("pckeyinput_zoomOut1"); } *************** *** 93,96 **** --- 108,122 ---- } move_time = 0; + zoomIn = false; + zoomOut = false; + /// \todo This camera initialization should be moved to a specialised cam class + camstat.maxy = 20; + camstat.miny = 0.1f; + camstat.ratio = 2.0f/5.0f; + camstat.speed = 5.0f; + camstat.init = false; + camstat.x = 1.0; + camstat.y = camstat.ratio/camstat.x; + camstat.pitch = 0; } *************** *** 138,141 **** --- 164,188 ---- UpdateServerPosition(); } + + /// \todo This really doesn't belong here; it needs to be moved into a + /// specialised camera class + if (camstat.init == false) + { + if (pccamera == 0) + { + pccamera = CEL_QUERY_PROPCLASS_ENT (entity, iPcCamera); + } + if (pccamera != 0) + { + camstat.init = true; + camstat.mode = "thirdperson"; + pccamera->SetModeName(camstat.mode); + pccamera->SetFirstPersonOffset(camstat.GetOffset()); + pccamera->SetPitch(camstat.pitch); + } + } + + // Act on the zoom + if (((zoomIn)&&(!zoomOut))||((!zoomIn)&&(zoomOut))) CameraZoom(elapsed_time); return true; } *************** *** 204,212 **** (msg == backward_rep)|| (msg == rot_left_rep)|| ! (msg == rot_right_rep)) { // We sink but do not process these messages return true; } else { --- 251,278 ---- (msg == backward_rep)|| (msg == rot_left_rep)|| ! (msg == rot_right_rep)|| ! (msg == run_rep)|| ! (msg == zoomIn_rep)|| ! (msg == zoomOut_rep)) { // We sink but do not process these messages return true; } + else if (msg == zoomIn0) + { + zoomIn = false; + } + else if (msg == zoomIn1) + { + zoomIn = true; + } + else if (msg == zoomOut0) + { + zoomOut = false; + } + else if (msg == zoomOut1) + { + zoomOut = true; + } else { *************** *** 220,223 **** --- 286,376 ---- } + void ocPlayerBehaviour::CameraZoom(csTicks etime) + { + // Calculate the change in position along the hyperbola + float delZ = camstat.speed*etime/1000; + if (zoomOut) delZ*= -1; + + float acc = 0; + float dZ = 0; + + /// \todo Refine the DELTA calculations; the condition + /// should not be dZ/10 but some other value... + /// as we approach the asypmtotes there is no point + /// in fine calculations because either X or Y + /// will not vary significantly. + while (true) + { + // Calculate dZ + if(camstat.x < 1) + { + dZ = sqrt(1 + camstat.ratio*camstat.ratio/ + camstat.y*camstat.y*camstat.y*camstat.y); + // Move a max of dZ/10 + if ((delZ - acc) < dZ/10) + { + // Adjust y, recalculate x and exit + camstat.y -= (delZ - acc)/dZ; + camstat.x = camstat.ratio/camstat.y; + break; + } + if (delZ > 0) + camstat.y -= 1/(10*dZ); + else + camstat.y += 1/(10*dZ); + camstat.x = camstat.ratio/camstat.y; + acc += dZ/10; + } + else + { + dZ = sqrt(1 + camstat.ratio*camstat.ratio/ + camstat.x*camstat.x*camstat.x*camstat.x); + // Move a max of dZ/10 + if ((delZ - acc) < dZ/10) + { + // Adjust x, recalculate y and exit + camstat.x += (delZ - acc)/dZ; + camstat.y = camstat.ratio/camstat.x; + break; + } + if (delZ > 0) + camstat.x += 1/(10*dZ); + else + camstat.y -= 1/(10*dZ); + camstat.y = camstat.ratio/camstat.x; + acc += dZ/10; + } + } + + /// \todo Do we reach a limit for switching views or limiting + /// movement? We need to implement the change-of-view + if (camstat.y < camstat.miny) + { + camstat.y = camstat.miny; + camstat.x = camstat.ratio/camstat.y; + } + if (camstat.y > camstat.maxy) + { + camstat.y = camstat.maxy; + camstat.x = camstat.ratio/camstat.y; + } + + /// \todo The pitch is not calculated correctly + // Calculate the pitch + float tx = camstat.ratio/(camstat.miny) - camstat.x + 0.01; + if (camstat.x < 1) + { + camstat.pitch = atan(tx/camstat.y) - 3.14159/4; + } + else + { + camstat.pitch = -atan(camstat.y/tx); + } + + //fprintf(stderr, "pitch: %f (deg)\n", camstat.pitch/3.14159*180); + pccamera->SetFirstPersonOffset(camstat.GetOffset()); + //pccamera->SetPitch(camstat.pitch); + } + bool ocPlayerBehaviour::Load() { Index: occltbehave.h =================================================================== RCS file: /cvsroot/once/oncecode/src/client/occltbehave.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** occltbehave.h 20 Nov 2004 08:20:10 -0000 1.5 --- occltbehave.h 20 Nov 2004 23:52:51 -0000 1.6 *************** *** 21,24 **** --- 21,25 ---- #include "csutil/scf.h" + #include "csgeom/vector3.h" #include "common/ocplayer.h" *************** *** 71,74 **** --- 72,76 ---- csRef<iPcActorMove> pcactor; csRef<iPcLinearMovement> pclinmove; + csRef<iPcCamera> pccamera; /// These are the IDs for the messages to be processed: *************** *** 85,88 **** --- 87,95 ---- static csStringID rot_right0; static csStringID rot_right1; + /// Zoom + static csStringID zoomIn0; + static csStringID zoomIn1; + static csStringID zoomOut0; + static csStringID zoomOut1; /// Messages which we sink but don't process (key_repeat messages) static csStringID forward_rep; *************** *** 90,94 **** --- 97,135 ---- static csStringID rot_left_rep; static csStringID rot_right_rep; + static csStringID run_rep; + static csStringID zoomIn_rep; + static csStringID zoomOut_rep; + /// Per frame trigger static csStringID timer_wakeupframe; + + /// Zoom flags + bool zoomIn, zoomOut; + void CameraZoom(csTicks etime); + /// Camera params + struct _camstat + { + /// Maximum camera height + float maxy; + /// Point at which we switch to 1st person mode + float miny; + /// Ratio of X to Y - the aspect ratio of the camera's movement + float ratio; + /// Rate at which we move along the hyperbola + float speed; + bool init; + float x; + float y; + /// The distance of the camera behind the player + csVector3 GetOffset(void) + { + csVector3 off; + /// \todo Replace 1.5 with the 'eye height' of the character mesh + off.y = y + 1.5; + off.z = ratio/miny - x; + return off; + } + float pitch; + csString mode; + } camstat; /// Update the server-side player position Index: ocdisplay.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/client/ocdisplay.cpp,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** ocdisplay.cpp 20 Nov 2004 08:20:10 -0000 1.60 --- ocdisplay.cpp 20 Nov 2004 23:52:51 -0000 1.61 *************** *** 61,64 **** --- 61,65 ---- // it affects all cameras which support a variable view offset. pccamera->SetFirstPersonOffset(csVector3 (0, 2, 1)); + //pccamera->SetPitch(-3.14/2); pccamera->SetAutoDraw(false); *************** *** 83,86 **** --- 84,89 ---- pcinp->Bind ("left", "rot_left"); pcinp->Bind ("right", "rot_right"); + pcinp->Bind ("z", "zoomIn"); + pcinp->Bind ("a", "zoomOut"); } |