From f34d409d6ef620e58cfdef7216e8cf7af4566052 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sat, 7 Jun 2003 22:20:39 +0000 Subject: [PATCH] DDR-like camera motions for DancingCharacters --- stepmania/src/DancingCharacters.cpp | 131 +++++++++++++++++++--------- stepmania/src/DancingCharacters.h | 14 +-- stepmania/src/RageMath.cpp | 20 +++++ stepmania/src/RageMath.h | 3 + 4 files changed, 118 insertions(+), 50 deletions(-) diff --git a/stepmania/src/DancingCharacters.cpp b/stepmania/src/DancingCharacters.cpp index d5b185f15b..17e6303fab 100644 --- a/stepmania/src/DancingCharacters.cpp +++ b/stepmania/src/DancingCharacters.cpp @@ -16,14 +16,20 @@ #include "RageUtil.h" #include "RageMath.h" #include "PrefsManager.h" +#include "GameState.h" +#include "song.h" -const float CAMERA_SWEEP_SECONDS = 2.f; -const float CAMERA_SWEEP_SECONDS_VARIANCE = 1.f; -const float CAMERA_DISTANCE = 16.f; -const float CAMERA_DISTANCE_VARIANCE = 3.f; -const float CAMERA_HEIGHT = -9.f; -const float CAMERA_HEIGHT_VARIANCE = 3.f; + +const float CAMERA_REST_DISTANCE = 32.f; +const float CAMERA_SWEEP_DISTANCE = 26.f; +const float CAMERA_SWEEP_HEIGHT_VARIANCE = 28.f; +const float CAMERA_SWEEP_PAN_Y_RANGE_DEGREES = 80.f; +const float CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES = 20.f; +const float CAMERA_STILL_DISTANCE = 20.f; +const float CAMERA_STILL_PAN_Y_RANGE_DEGREES = 45.f; +const float CAMERA_STILL_HEIGHT_VARIANCE = 6.f; +const float LOOK_AT_HEIGHT = -9.f; const float MODEL_X[NUM_PLAYERS] = { -8, 8 }; @@ -36,7 +42,7 @@ DancingCharacters::DancingCharacters() m_Character[PLAYER_1].LoadMilkshapeAscii( "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\char0000\\model.txt" ); m_Character[PLAYER_1].LoadMilkshapeAsciiBones( "rest", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\rest.bones.txt" ); m_Character[PLAYER_1].LoadMilkshapeAsciiBones( "warmup", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\warmup.bones.txt" ); - m_Character[PLAYER_1].LoadMilkshapeAsciiBones( "default", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\dance0001.bones.txt" ); + m_Character[PLAYER_1].LoadMilkshapeAsciiBones( "dance", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\dance0001.bones.txt" ); m_Character[PLAYER_1].PlayAnimation( "rest" ); this->AddChild( &m_Character[PLAYER_1] ); @@ -44,38 +50,97 @@ DancingCharacters::DancingCharacters() m_Character[PLAYER_2].LoadMilkshapeAscii( "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\char0011\\model.txt" ); m_Character[PLAYER_2].LoadMilkshapeAsciiBones( "rest", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\rest.bones.txt" ); m_Character[PLAYER_2].LoadMilkshapeAsciiBones( "warmup", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\warmup.bones.txt" ); - m_Character[PLAYER_2].LoadMilkshapeAsciiBones( "default", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\dance0001.bones.txt" ); + m_Character[PLAYER_2].LoadMilkshapeAsciiBones( "dance", "C:\\My Documents\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\dance0001.bones.txt" ); m_Character[PLAYER_2].PlayAnimation( "rest" ); this->AddChild( &m_Character[PLAYER_2] ); - - StartCameraSweep(); } + + // initial camera sweep is still + m_CameraDistance = CAMERA_REST_DISTANCE; + m_CameraPanYStart = 0; + m_CameraPanYEnd = 0; + m_fCameraHeightStart = LOOK_AT_HEIGHT; + m_fCameraHeightEnd = LOOK_AT_HEIGHT; + m_fThisCameraStartBeat = 0; + m_fThisCameraEndBeat = GAMESTATE->m_pCurSong->m_fFirstBeat; + } +int Neg1OrPos1() { return rand()%2 ? -1 : +1; } + void DancingCharacters::Update( float fDelta ) { - ActorFrame::Update( fDelta ); - - if( PREFSMAN->m_bShowDancingCharacters ) + if( !GAMESTATE->m_bFreeze ) + ActorFrame::Update( fDelta ); + + + static bool bWasHereWeGo = false; + bool bIsHereWeGo = GAMESTATE->m_bPastHereWeGo; + if( !bWasHereWeGo && bIsHereWeGo ) { - + m_Character[PLAYER_1].PlayAnimation( "warmup" ); + m_Character[PLAYER_2].PlayAnimation( "warmup" ); } + bWasHereWeGo = bIsHereWeGo; - // update camera sweep - m_fSecsIntoSweep += fDelta; - if( m_fSecsIntoSweep > m_fSweepSecs ) - StartCameraSweep(); + static float fLastBeat = GAMESTATE->m_fSongBeat; + float fThisBeat = GAMESTATE->m_fSongBeat; + if( fLastBeat < GAMESTATE->m_pCurSong->m_fFirstBeat && + fThisBeat >= GAMESTATE->m_pCurSong->m_fFirstBeat ) + { + m_Character[PLAYER_1].PlayAnimation( "dance" ); + m_Character[PLAYER_2].PlayAnimation( "dance" ); + } + fLastBeat = fThisBeat; - float fPercentIntoSweep = m_fSecsIntoSweep / m_fSweepSecs; - m_CameraEyeCurrent = m_CameraEyeStart * (1-fPercentIntoSweep) + m_CameraEyeEnd * fPercentIntoSweep; + + // time for a new sweep? + if( GAMESTATE->m_fSongBeat > m_fThisCameraEndBeat ) + { + if( rand()%2 ) + { + m_CameraDistance = CAMERA_SWEEP_DISTANCE; + m_CameraPanYStart = m_CameraPanYEnd = RandomInt(-1,1) * CAMERA_SWEEP_PAN_Y_RANGE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = LOOK_AT_HEIGHT; + + m_CameraPanYEnd += RandomInt(-1,1) * CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = m_fCameraHeightStart + RandomInt(-1,1) * CAMERA_SWEEP_HEIGHT_VARIANCE; + + float fCameraHeightVariance = RandomInt(-1,1) * CAMERA_SWEEP_HEIGHT_VARIANCE; + m_fCameraHeightStart -= fCameraHeightVariance; + m_fCameraHeightEnd += fCameraHeightVariance; + } + else + { + m_CameraDistance = CAMERA_STILL_DISTANCE; + m_CameraPanYStart = m_CameraPanYEnd = Neg1OrPos1() * CAMERA_STILL_PAN_Y_RANGE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = LOOK_AT_HEIGHT + Neg1OrPos1() * CAMERA_STILL_HEIGHT_VARIANCE; + } + + int iCurBeat = (int)GAMESTATE->m_fSongBeat; + iCurBeat -= iCurBeat%8; + + m_fThisCameraStartBeat = iCurBeat; + m_fThisCameraEndBeat = iCurBeat + 8; + } } void DancingCharacters::DrawPrimitives() { - DISPLAY->EnterPerspective( 90, false ); + DISPLAY->EnterPerspective( 45, false ); + + float fPercentIntoSweep = SCALE(GAMESTATE->m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f ); + float fCameraPanY = SCALE( fPercentIntoSweep, 0.f, 1.f, m_CameraPanYStart, m_CameraPanYEnd ); + float fCameraHeight = SCALE( fPercentIntoSweep, 0.f, 1.f, m_fCameraHeightStart, m_fCameraHeightEnd ); + + RageVector3 m_CameraPoint( 0, fCameraHeight, -m_CameraDistance ); + RageVec3TransformCoord( &m_CameraPoint, &m_CameraPoint, &RageMatrixRotationY(fCameraPanY) ); + + RageVector3 m_LookAt( 0, LOOK_AT_HEIGHT, 0 ); + DISPLAY->LookAt( - m_CameraEyeCurrent, - m_CameraAt, + m_CameraPoint, + m_LookAt, RageVector3(0,1,0) ); DISPLAY->SetLighting( true ); @@ -93,23 +158,3 @@ void DancingCharacters::DrawPrimitives() DISPLAY->ExitPerspective(); } - -void DancingCharacters::StartCameraSweep() -{ - m_CameraEyeStart = RageVector3( randomf(), randomf(), randomf() ); - RageVec3Normalize( &m_CameraEyeStart, &m_CameraEyeStart ); - m_CameraEyeStart *= CAMERA_DISTANCE + randomf()*CAMERA_DISTANCE_VARIANCE; - m_CameraEyeStart.y += CAMERA_HEIGHT + randomf()*CAMERA_HEIGHT_VARIANCE; - - m_CameraEyeEnd = RageVector3( randomf(), randomf(), randomf() ); - m_CameraEyeEnd += m_CameraEyeStart/2; // bias the end toward the start to that we don't sweep through the chars' bodies - RageVec3Normalize( &m_CameraEyeEnd, &m_CameraEyeEnd ); - m_CameraEyeEnd *= CAMERA_DISTANCE + randomf()*CAMERA_DISTANCE_VARIANCE; - m_CameraEyeEnd.y += CAMERA_HEIGHT + randomf()*CAMERA_HEIGHT_VARIANCE; - - m_CameraAt = RageVector3(0,CAMERA_HEIGHT + randomf()*CAMERA_HEIGHT_VARIANCE,0); - - m_fSweepSecs = CAMERA_SWEEP_SECONDS + randomf()*CAMERA_SWEEP_SECONDS_VARIANCE; - - m_fSecsIntoSweep = 0; -} \ No newline at end of file diff --git a/stepmania/src/DancingCharacters.h b/stepmania/src/DancingCharacters.h index ee4b4b10ef..204aa66594 100644 --- a/stepmania/src/DancingCharacters.h +++ b/stepmania/src/DancingCharacters.h @@ -25,16 +25,16 @@ public: virtual void DrawPrimitives(); protected: - void StartCameraSweep(); Model m_Character[NUM_PLAYERS]; - RageVector3 m_CameraEyeStart; - RageVector3 m_CameraEyeEnd; - RageVector3 m_CameraEyeCurrent; - RageVector3 m_CameraAt; - float m_fSweepSecs; - float m_fSecsIntoSweep; + float m_CameraDistance; + float m_CameraPanYStart; + float m_CameraPanYEnd; + float m_fCameraHeightStart; + float m_fCameraHeightEnd; + float m_fThisCameraStartBeat; + float m_fThisCameraEndBeat; }; #endif diff --git a/stepmania/src/RageMath.cpp b/stepmania/src/RageMath.cpp index 156ec2cc0c..83f7d8fb20 100644 --- a/stepmania/src/RageMath.cpp +++ b/stepmania/src/RageMath.cpp @@ -171,6 +171,26 @@ void RageMatrixRotationZ( RageMatrix* pOut, float theta ) pOut->m[1][0] = -pOut->m[0][1]; } +RageMatrix RageMatrixRotationX( float theta ) +{ + RageMatrix m; + RageMatrixRotationX( &m, theta ); + return m; +} +RageMatrix RageMatrixRotationY( float theta ) +{ + RageMatrix m; + RageMatrixRotationY( &m, theta ); + return m; +} +RageMatrix RageMatrixRotationZ( float theta ) +{ + RageMatrix m; + RageMatrixRotationZ( &m, theta ); + return m; +} + + /* This is similar in style to Actor::Command. However, Actors don't store * matrix stacks; they only store offsets and scales, and compound them into * a single transformations at once. This makes some things easy, but it's not diff --git a/stepmania/src/RageMath.h b/stepmania/src/RageMath.h index 8eb7470aac..abd8c22119 100644 --- a/stepmania/src/RageMath.h +++ b/stepmania/src/RageMath.h @@ -29,6 +29,9 @@ void RageMatrixScaling( RageMatrix* pOut, float x, float y, float z ); void RageMatrixRotationX( RageMatrix* pOut, float fTheta ); void RageMatrixRotationY( RageMatrix* pOut, float fTheta ); void RageMatrixRotationZ( RageMatrix* pOut, float fTheta ); +RageMatrix RageMatrixRotationX( float fTheta ); +RageMatrix RageMatrixRotationY( float fTheta ); +RageMatrix RageMatrixRotationZ( float fTheta ); void RageMatrixCommand( CString sCommandString, RageMatrix &mat ); void RageQuatFromHPR(RageVector4* pOut, RageVector3 hpr ); void RageMatrixFromQuat( RageMatrix* pOut, const RageVector4 q );