2003-02-16 04:01:45 +00:00
#include "global.h" // testing updates
2003-07-07 18:22:36 +00:00
2001-11-04 19:34:28 +00:00
/*
-----------------------------------------------------------------------------
2002-05-19 01:59:48 +00:00
Class: Actor
2001-11-04 19:34:28 +00:00
2002-05-19 01:59:48 +00:00
Desc: See header.
2001-11-04 19:34:28 +00:00
2002-05-19 01:59:48 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
2001-11-04 19:34:28 +00:00
-----------------------------------------------------------------------------
*/
2001-11-03 10:52:42 +00:00
#include "Actor.h"
#include <math.h>
2002-05-19 01:59:48 +00:00
#include "RageDisplay.h"
2002-03-30 20:00:13 +00:00
#include "PrefsManager.h"
2002-11-11 04:53:31 +00:00
#include "RageUtil.h"
2003-04-14 22:01:57 +00:00
#include "RageMath.h"
2002-11-11 04:53:31 +00:00
#include "GameConstantsAndTypes.h"
2003-03-02 01:43:33 +00:00
#include "RageLog.h"
2003-07-11 03:15:28 +00:00
#include "arch/ArchHooks/ArchHooks.h"
2001-11-03 10:52:42 +00:00
2003-04-02 05:41:22 +00:00
/* This is Reset instead of Init since many derived classes have Init() functions
* that shouldn't change the position of the actor. */
void Actor :: Reset ()
2001-11-03 10:52:42 +00:00
{
2003-04-02 05:41:22 +00:00
m_TweenStates . clear ();
m_TweenInfo . clear ();
2003-01-10 02:22:07 +00:00
2003-10-07 04:26:14 +00:00
m_pTempState = NULL ;
2003-02-06 07:32:57 +00:00
m_baseRotation = RageVector3 ( 0 , 0 , 0 );
m_baseScale = RageVector3 ( 1 , 1 , 1 );
2002-09-02 21:59:58 +00:00
m_start . Init ();
m_current . Init ();
2002-03-30 20:00:13 +00:00
m_HorizAlign = align_center ;
m_VertAlign = align_middle ;
2003-02-17 12:19:42 +00:00
m_Effect = no_effect ;
m_fSecsIntoEffect = 0 ;
m_fEffectPeriodSeconds = 1 ;
2003-03-02 01:43:33 +00:00
m_vEffectMagnitude = RageVector3 ( 0 , 0 , 10 );
m_effectColor1 = RageColor ( 1 , 1 , 1 , 1 );
m_effectColor2 = RageColor ( 1 , 1 , 1 , 1 );
2002-03-30 20:00:13 +00:00
2003-10-22 10:18:46 +00:00
m_bHidden = false ;
2002-05-01 19:14:55 +00:00
m_bShadow = false ;
2002-04-16 17:31:00 +00:00
m_fShadowLength = 4 ;
2003-03-05 02:52:40 +00:00
m_bIsAnimating = true ;
2003-05-15 22:43:02 +00:00
m_bTextureWrapping = false ;
2003-05-15 06:09:19 +00:00
m_BlendMode = BLEND_NORMAL ;
2003-07-07 20:24:51 +00:00
m_bClearZBuffer = false ;
2003-05-15 06:09:19 +00:00
m_bUseZBuffer = false ;
2003-05-15 22:43:02 +00:00
m_bUseBackfaceCull = false ;
2001-11-03 10:52:42 +00:00
}
2003-04-02 05:41:22 +00:00
Actor :: Actor ()
{
2003-10-22 09:44:27 +00:00
m_size = RageVector2 ( 1 , 1 );
2003-04-02 05:41:22 +00:00
Reset ();
m_bFirstUpdate = true ;
}
2002-08-19 20:02:30 +00:00
void Actor :: Draw ()
{
2003-10-22 10:18:46 +00:00
if ( m_bHidden )
return ; // early abort
2002-08-19 20:02:30 +00:00
// call the most-derived versions
this -> BeginDraw ();
this -> DrawPrimitives (); // call the most-derived version of DrawPrimitives();
this -> EndDraw ();
}
void Actor :: BeginDraw () // set the world matrix and calculate actor properties
2001-11-28 20:26:45 +00:00
{
2002-05-19 01:59:48 +00:00
DISPLAY -> PushMatrix (); // we're actually going to do some drawing in this function
2002-01-16 10:01:32 +00:00
2001-11-28 20:26:45 +00:00
2002-03-30 20:00:13 +00:00
//
// set temporary drawing properties based on Effects
//
2003-10-07 04:26:14 +00:00
if ( m_Effect == no_effect )
2001-11-28 20:26:45 +00:00
{
2003-10-07 04:26:14 +00:00
m_pTempState = & m_current ;
}
else
{
m_pTempState = & m_tempState ;
m_tempState = m_current ;
float fPercentThroughEffect = m_fSecsIntoEffect / m_fEffectPeriodSeconds ;
bool bBlinkOn = fPercentThroughEffect > 0.5f ;
float fPercentBetweenColors = ( fPercentThroughEffect == 0 ) ? 0 : ( sinf ( fPercentThroughEffect * 2 * PI ) / 2 + 0.5f );
ASSERT ( fPercentBetweenColors >= 0 && fPercentBetweenColors <= 1 );
float fOriginalAlpha = m_tempState . diffuse [ 0 ]. a ;
int i ;
switch ( m_Effect )
2002-03-30 20:00:13 +00:00
{
2003-10-07 04:26:14 +00:00
case diffuse_blink :
for ( i = 0 ; i < 4 ; i ++ )
m_tempState . diffuse [ i ] = bBlinkOn ? m_effectColor1 : m_effectColor2 ;
break ;
case diffuse_shift :
for ( i = 0 ; i < 4 ; i ++ )
m_tempState . diffuse [ i ] = m_effectColor1 * fPercentBetweenColors + m_effectColor2 * ( 1.0f - fPercentBetweenColors );
break ;
case glow_blink :
m_tempState . glow = bBlinkOn ? m_effectColor1 : m_effectColor2 ;
m_tempState . glow . a *= fOriginalAlpha ; // don't glow if the Actor is transparent!
break ;
case glow_shift :
m_tempState . glow = m_effectColor1 * fPercentBetweenColors + m_effectColor2 * ( 1.0f - fPercentBetweenColors );
m_tempState . glow . a *= fOriginalAlpha ; // don't glow if the Actor is transparent!
break ;
case rainbow :
m_tempState . diffuse [ 0 ] = RageColor (
cosf ( fPercentBetweenColors * 2 * PI ) * 0.5f + 0.5f ,
cosf ( fPercentBetweenColors * 2 * PI + PI * 2.0f / 3.0f ) * 0.5f + 0.5f ,
cosf ( fPercentBetweenColors * 2 * PI + PI * 4.0f / 3.0f ) * 0.5f + 0.5f ,
fOriginalAlpha );
for ( i = 1 ; i < 4 ; i ++ )
m_tempState . diffuse [ i ] = m_tempState . diffuse [ 0 ];
break ;
case wag :
m_tempState . rotation = m_vEffectMagnitude * sinf ( fPercentThroughEffect * 2.0f * PI );
break ;
case spin :
// nothing needs to be here
break ;
case vibrate :
m_tempState . pos . x += m_vEffectMagnitude . x * randomf ( - 1.0f , 1.0f ) * GetZoom ();
m_tempState . pos . y += m_vEffectMagnitude . y * randomf ( - 1.0f , 1.0f ) * GetZoom ();
m_tempState . pos . z += m_vEffectMagnitude . z * randomf ( - 1.0f , 1.0f ) * GetZoom ();
break ;
case bounce :
{
float fPercentOffset = sinf ( fPercentThroughEffect * PI );
m_tempState . pos += m_vEffectMagnitude * fPercentOffset ;
m_tempState . pos . x = roundf ( m_tempState . pos . x );
m_tempState . pos . y = roundf ( m_tempState . pos . y );
m_tempState . pos . z = roundf ( m_tempState . pos . z );
}
break ;
case bob :
{
float fPercentOffset = sinf ( fPercentThroughEffect * PI * 2 );
m_tempState . pos += m_vEffectMagnitude * fPercentOffset ;
m_tempState . pos . x = roundf ( m_tempState . pos . x );
m_tempState . pos . y = roundf ( m_tempState . pos . y );
m_tempState . pos . z = roundf ( m_tempState . pos . z );
}
break ;
case pulse :
{
float fMinZoom = m_vEffectMagnitude [ 0 ];
float fMaxZoom = m_vEffectMagnitude [ 1 ];
float fPercentOffset = sinf ( fPercentThroughEffect * PI );
float fZoom = SCALE ( fPercentOffset , 0.f , 1.f , fMinZoom , fMaxZoom );
m_tempState . scale = RageVector3 ( fZoom , fZoom , fZoom );
}
break ;
default :
ASSERT ( 0 ); // invalid Effect
2002-03-30 20:00:13 +00:00
}
2001-11-28 20:26:45 +00:00
}
2003-10-07 04:26:14 +00:00
DISPLAY -> Translate (
m_pTempState -> pos . x ,
m_pTempState -> pos . y ,
m_pTempState -> pos . z );
DISPLAY -> Scale (
m_pTempState -> scale . x * m_baseScale . x ,
m_pTempState -> scale . y * m_baseScale . y ,
m_pTempState -> scale . z * m_baseScale . z );
2001-11-28 20:26:45 +00:00
2003-04-14 22:01:57 +00:00
/* The only time rotation and quat should normally be used simultaneously
* is for m_baseRotation. */
2003-10-07 04:26:14 +00:00
if ( m_pTempState -> rotation . x + m_baseRotation . x != 0 )
DISPLAY -> RotateX ( m_pTempState -> rotation . x + m_baseRotation . x );
if ( m_pTempState -> rotation . y + m_baseRotation . y != 0 )
DISPLAY -> RotateY ( m_pTempState -> rotation . y + m_baseRotation . y );
if ( m_pTempState -> rotation . z + m_baseRotation . z != 0 )
DISPLAY -> RotateZ ( m_pTempState -> rotation . z + m_baseRotation . z );
2003-04-14 22:01:57 +00:00
2003-10-07 04:26:14 +00:00
if ( m_pTempState -> quat . x != 0 || m_pTempState -> quat . y != 0 || m_pTempState -> quat . z != 0 || m_pTempState -> quat . w != 1 )
2003-04-14 22:01:57 +00:00
{
RageMatrix mat ;
2003-10-07 04:26:14 +00:00
RageMatrixFromQuat ( & mat , m_pTempState -> quat );
2003-04-14 22:01:57 +00:00
DISPLAY -> MultMatrix ( mat );
}
2002-08-19 20:02:30 +00:00
}
2002-01-16 10:01:32 +00:00
2003-05-15 06:09:19 +00:00
void Actor :: SetRenderStates ()
{
// set Actor-defined render states
DISPLAY -> SetTextureWrapping ( m_bTextureWrapping );
DISPLAY -> SetBlendMode ( m_BlendMode );
DISPLAY -> SetZBuffer ( m_bUseZBuffer );
2003-07-07 20:24:51 +00:00
if ( m_bClearZBuffer )
DISPLAY -> ClearZBuffer ();
2003-05-15 06:09:19 +00:00
DISPLAY -> SetBackfaceCull ( m_bUseBackfaceCull );
}
2002-08-19 20:02:30 +00:00
void Actor :: EndDraw ()
{
2002-05-19 01:59:48 +00:00
DISPLAY -> PopMatrix ();
2001-11-28 20:26:45 +00:00
}
2002-09-04 21:53:43 +00:00
void Actor :: UpdateTweening ( float fDeltaTime )
{
2003-05-16 21:09:26 +00:00
while ( 1 )
2002-09-04 21:53:43 +00:00
{
2003-05-16 21:09:26 +00:00
if ( m_TweenStates . empty () ) // nothing to do
return ;
if ( fDeltaTime == 0 ) // nothing will change
return ;
// update current tween state
TweenState & TS = m_TweenStates [ 0 ]; // earliest tween
TweenInfo & TI = m_TweenInfo [ 0 ]; // earliest tween
if ( TI . m_fTimeLeftInTween == TI . m_fTweenTime ) // we are just beginning this tween
m_start = m_current ; // set the start position
float fSecsToSubtract = min ( TI . m_fTimeLeftInTween , fDeltaTime );
TI . m_fTimeLeftInTween -= fSecsToSubtract ;
fDeltaTime -= fSecsToSubtract ;
2002-09-04 21:53:43 +00:00
2003-05-16 21:09:26 +00:00
if ( TI . m_fTimeLeftInTween == 0 ) // Current tween is over. Stop.
2002-09-04 21:53:43 +00:00
{
2003-05-16 21:09:26 +00:00
m_current = TS ;
// delete the head tween
m_TweenStates . erase ( m_TweenStates . begin () );
m_TweenInfo . erase ( m_TweenInfo . begin () );
2002-09-04 21:53:43 +00:00
}
2003-05-16 21:09:26 +00:00
else // in the middle of tweening. Recalcute the current position.
{
const float fPercentThroughTween = 1 - ( TI . m_fTimeLeftInTween / TI . m_fTweenTime );
2002-09-04 21:53:43 +00:00
2003-05-16 21:09:26 +00:00
// distort the percentage if appropriate
float fPercentAlongPath = 0.f ;
switch ( TI . m_TweenType )
{
case TWEEN_LINEAR : fPercentAlongPath = fPercentThroughTween ; break ;
case TWEEN_ACCELERATE : fPercentAlongPath = fPercentThroughTween * fPercentThroughTween ; break ;
case TWEEN_DECELERATE : fPercentAlongPath = 1 - ( 1 - fPercentThroughTween ) * ( 1 - fPercentThroughTween ); break ;
case TWEEN_BOUNCE_BEGIN : fPercentAlongPath = 1 - sinf ( 1.1f + fPercentThroughTween * ( PI - 1.1f ) ) / 0.89f ; break ;
case TWEEN_BOUNCE_END : fPercentAlongPath = sinf ( 1.1f + ( 1 - fPercentThroughTween ) * ( PI - 1.1f ) ) / 0.89f ; break ;
case TWEEN_SPRING : fPercentAlongPath = 1 - cosf ( fPercentThroughTween * PI * 2.5f ) / ( 1 + fPercentThroughTween * 3 ); break ;
default : ASSERT ( 0 );
}
TweenState :: MakeWeightedAverage ( m_current , m_start , TS , fPercentAlongPath );
}
2002-09-04 21:53:43 +00:00
}
}
2001-11-28 20:26:45 +00:00
2003-01-10 02:22:07 +00:00
bool Actor :: IsFirstUpdate ()
{
return m_bFirstUpdate ;
}
2002-01-16 10:01:32 +00:00
void Actor :: Update ( float fDeltaTime )
2001-11-03 10:52:42 +00:00
{
2002-07-31 19:40:40 +00:00
// LOG->Trace( "Actor::Update( %f )", fDeltaTime );
2001-11-03 10:52:42 +00:00
2001-11-28 20:26:45 +00:00
// update effect
switch ( m_Effect )
{
case no_effect :
break ;
2003-03-02 01:43:33 +00:00
case diffuse_blink :
2003-02-18 23:15:38 +00:00
case diffuse_shift :
2003-03-02 01:43:33 +00:00
case glow_blink :
2003-02-18 23:15:38 +00:00
case glow_shift :
2003-03-05 02:52:40 +00:00
case rainbow :
2003-03-02 01:43:33 +00:00
case wag :
case bounce :
case bob :
2003-03-05 02:52:40 +00:00
case pulse :
2003-02-17 12:19:42 +00:00
m_fSecsIntoEffect += fDeltaTime ;
while ( m_fSecsIntoEffect >= m_fEffectPeriodSeconds )
m_fSecsIntoEffect -= m_fEffectPeriodSeconds ;
2001-11-28 20:26:45 +00:00
break ;
2003-03-02 01:43:33 +00:00
case spin :
2003-03-05 02:52:40 +00:00
m_current . rotation += fDeltaTime * m_vEffectMagnitude ;
2003-04-21 02:35:16 +00:00
if ( m_current . rotation . x > 360 ) m_current . rotation . x -= 360 ;
if ( m_current . rotation . y > 360 ) m_current . rotation . y -= 360 ;
if ( m_current . rotation . z > 360 ) m_current . rotation . z -= 360 ;
if ( m_current . rotation . x < - 360 ) m_current . rotation . x += 360 ;
if ( m_current . rotation . y < - 360 ) m_current . rotation . y += 360 ;
if ( m_current . rotation . z < - 360 ) m_current . rotation . z += 360 ;
2001-11-28 20:26:45 +00:00
break ;
2003-03-02 01:43:33 +00:00
case vibrate :
2001-11-28 20:26:45 +00:00
break ;
}
2002-09-04 21:53:43 +00:00
UpdateTweening ( fDeltaTime );
2003-01-19 04:44:22 +00:00
if ( m_bFirstUpdate )
m_bFirstUpdate = false ;
2003-05-11 22:19:40 +00:00
2001-11-03 10:52:42 +00:00
}
2001-11-28 20:26:45 +00:00
void Actor :: BeginTweening ( float time , TweenType tt )
2002-01-16 10:01:32 +00:00
{
2002-04-16 17:31:00 +00:00
ASSERT ( time >= 0 );
2002-01-16 10:01:32 +00:00
2003-03-09 00:55:49 +00:00
time = max ( time , 0 );
2003-02-25 02:51:04 +00:00
ASSERT ( m_TweenStates . size () < 50 ); // there's no reason for the number of tweens to ever go this large
2002-11-11 04:53:31 +00:00
2002-03-09 06:19:40 +00:00
// add a new TweenState to the tail, and initialize it
2003-02-25 02:51:04 +00:00
m_TweenStates . resize ( m_TweenStates . size () + 1 );
m_TweenInfo . resize ( m_TweenInfo . size () + 1 );
2002-01-16 10:01:32 +00:00
2003-03-05 23:35:43 +00:00
ASSERT ( m_TweenStates . size () == m_TweenInfo . size () );
2003-02-25 02:51:04 +00:00
TweenState & TS = m_TweenStates . back (); // latest
TweenInfo & TI = m_TweenInfo . back (); // latest
if ( m_TweenStates . size () >= 2 ) // if there was already a TS on the stack
2002-03-09 06:19:40 +00:00
{
// initialize the new TS from the last TS in the list
2003-02-25 02:51:04 +00:00
TS = m_TweenStates [ m_TweenStates . size () - 2 ];
2002-03-09 06:19:40 +00:00
}
else
{
// This new TS is the only TS.
// Set our tween starting and ending values to the current position.
2002-09-02 21:59:58 +00:00
TS = m_current ;
2002-03-09 06:19:40 +00:00
}
2002-01-16 10:01:32 +00:00
2002-09-02 21:59:58 +00:00
TI . m_TweenType = tt ;
TI . m_fTweenTime = time ;
TI . m_fTimeLeftInTween = time ;
2002-01-16 10:01:32 +00:00
}
2002-05-28 20:01:22 +00:00
void Actor :: StopTweening ()
{
2003-02-25 02:51:04 +00:00
m_TweenStates . clear ();
m_TweenInfo . clear ();
2003-03-02 01:43:33 +00:00
ASSERT ( m_TweenStates . empty () );
ASSERT ( m_TweenInfo . empty () );
2002-05-28 20:01:22 +00:00
}
2003-06-16 17:33:28 +00:00
void Actor :: FinishTweening ()
{
m_current = DestTweenState ();
StopTweening ();
}
2002-05-28 20:01:22 +00:00
2001-11-03 10:52:42 +00:00
2002-11-01 20:01:59 +00:00
void Actor :: ScaleTo ( const RectI & rect , StretchType st )
2001-11-03 10:52:42 +00:00
{
// width and height of rectangle
2002-12-17 06:25:03 +00:00
float rect_width = ( float ) rect . GetWidth ();
float rect_height = ( float ) rect . GetHeight ();
2001-11-03 10:52:42 +00:00
2003-04-02 06:02:55 +00:00
if ( rect_width < 0 ) SetRotationY ( 180 );
if ( rect_height < 0 ) SetRotationX ( 180 );
2001-11-25 10:49:31 +00:00
2001-11-03 10:52:42 +00:00
// center of the rectangle
2002-11-01 20:01:59 +00:00
float rect_cx = rect . left + rect_width / 2 ;
float rect_cy = rect . top + rect_height / 2 ;
2001-11-03 10:52:42 +00:00
2002-01-16 10:01:32 +00:00
// zoom fActor needed to scale the Actor to fill the rectangle
2002-02-24 01:43:11 +00:00
float fNewZoomX = fabsf ( rect_width / m_size . x );
float fNewZoomY = fabsf ( rect_height / m_size . y );
2001-11-03 10:52:42 +00:00
2002-09-07 10:11:00 +00:00
float fNewZoom = 0.f ;
2001-11-03 10:52:42 +00:00
switch ( st )
{
case cover :
fNewZoom = fNewZoomX > fNewZoomY ? fNewZoomX : fNewZoomY ; // use larger zoom
break ;
case fit_inside :
fNewZoom = fNewZoomX > fNewZoomY ? fNewZoomY : fNewZoomX ; // use smaller zoom
break ;
}
2001-11-25 04:31:44 +00:00
SetXY ( rect_cx , rect_cy );
2001-11-03 10:52:42 +00:00
SetZoom ( fNewZoom );
}
2003-04-02 05:41:22 +00:00
void Actor :: SetHorizAlign ( CString s )
{
s . MakeLower ();
2003-11-05 05:10:19 +00:00
if ( s == "left" ) SetHorizAlign ( align_left ); /* call derived */
else if ( s == "center" ) SetHorizAlign ( align_center );
else if ( s == "right" ) SetHorizAlign ( align_right );
2003-04-02 05:41:22 +00:00
else ASSERT ( 0 );
}
void Actor :: SetVertAlign ( CString s )
{
s . MakeLower ();
2003-11-05 05:10:19 +00:00
if ( s == "top" ) SetVertAlign ( align_top ); /* call derived */
else if ( s == "middle" ) SetVertAlign ( align_middle );
else if ( s == "bottom" ) SetVertAlign ( align_bottom );
2003-04-02 05:41:22 +00:00
else ASSERT ( 0 );
}
2003-02-19 07:59:00 +00:00
void Actor :: StretchTo ( const RectI & r )
{
RectF r2 ( ( float ) r . left , ( float ) r . top , ( float ) r . right , ( float ) r . bottom );
StretchTo ( r2 );
}
2001-11-03 10:52:42 +00:00
2003-02-19 07:59:00 +00:00
void Actor :: StretchTo ( const RectF & r )
2001-11-03 10:52:42 +00:00
{
// width and height of rectangle
2003-02-19 07:59:00 +00:00
float width = r . GetWidth ();
float height = r . GetHeight ();
2001-11-03 10:52:42 +00:00
// center of the rectangle
2003-02-19 07:59:00 +00:00
float cx = r . left + width / 2.0f ;
float cy = r . top + height / 2.0f ;
2001-11-03 10:52:42 +00:00
2002-01-16 10:01:32 +00:00
// zoom fActor needed to scale the Actor to fill the rectangle
2003-02-19 07:59:00 +00:00
float fNewZoomX = width / m_size . x ;
float fNewZoomY = height / m_size . y ;
2001-11-03 10:52:42 +00:00
2003-02-19 07:59:00 +00:00
SetXY ( cx , cy );
2002-01-16 10:01:32 +00:00
SetZoomX ( fNewZoomX );
SetZoomY ( fNewZoomY );
2001-11-03 10:52:42 +00:00
}
2001-11-28 20:26:45 +00:00
2003-03-02 01:43:33 +00:00
// effect "macros"
2001-11-28 20:26:45 +00:00
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectDiffuseBlink ( float fEffectPeriodSeconds , RageColor c1 , RageColor c2 )
2001-11-28 20:26:45 +00:00
{
2003-03-24 21:37:13 +00:00
if ( m_Effect != diffuse_blink )
{
m_Effect = diffuse_blink ;
m_fEffectPeriodSeconds = fEffectPeriodSeconds ;
m_fSecsIntoEffect = 0 ;
}
2003-02-17 12:19:42 +00:00
m_effectColor1 = c1 ;
m_effectColor2 = c2 ;
2001-11-28 20:26:45 +00:00
}
2003-02-18 23:15:38 +00:00
void Actor :: SetEffectDiffuseShift ( float fEffectPeriodSeconds , RageColor c1 , RageColor c2 )
2001-11-28 20:26:45 +00:00
{
2003-03-24 21:37:13 +00:00
if ( m_Effect != diffuse_shift )
{
m_Effect = diffuse_shift ;
m_fEffectPeriodSeconds = fEffectPeriodSeconds ;
m_fSecsIntoEffect = 0 ;
}
2003-02-17 12:19:42 +00:00
m_effectColor1 = c1 ;
m_effectColor2 = c2 ;
2001-11-28 20:26:45 +00:00
}
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectGlowBlink ( float fEffectPeriodSeconds , RageColor c1 , RageColor c2 )
2001-11-28 20:26:45 +00:00
{
2003-03-24 21:37:13 +00:00
if ( m_Effect != glow_blink )
{
m_Effect = glow_blink ;
m_fEffectPeriodSeconds = fEffectPeriodSeconds ;
m_fSecsIntoEffect = 0 ;
}
2003-02-17 12:19:42 +00:00
m_effectColor1 = c1 ;
m_effectColor2 = c2 ;
}
2002-01-16 10:01:32 +00:00
2003-02-18 23:15:38 +00:00
void Actor :: SetEffectGlowShift ( float fEffectPeriodSeconds , RageColor c1 , RageColor c2 )
2003-02-17 12:19:42 +00:00
{
2003-03-24 21:37:13 +00:00
if ( m_Effect != glow_shift )
{
m_Effect = glow_shift ;
m_fEffectPeriodSeconds = fEffectPeriodSeconds ;
m_fSecsIntoEffect = 0 ;
}
2003-02-17 12:19:42 +00:00
m_effectColor1 = c1 ;
m_effectColor2 = c2 ;
2001-11-28 20:26:45 +00:00
}
2003-03-05 02:52:40 +00:00
void Actor :: SetEffectRainbow ( float fEffectPeriodSeconds )
{
m_Effect = rainbow ;
m_fEffectPeriodSeconds = fEffectPeriodSeconds ;
m_fSecsIntoEffect = 0 ;
}
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectWag ( float fPeriod , RageVector3 vect )
2001-11-28 20:26:45 +00:00
{
2003-03-02 01:43:33 +00:00
m_Effect = wag ;
2003-02-17 12:19:42 +00:00
m_fEffectPeriodSeconds = fPeriod ;
2003-03-02 01:43:33 +00:00
m_vEffectMagnitude = vect ;
2003-02-17 12:19:42 +00:00
m_fSecsIntoEffect = 0 ;
2002-07-27 19:29:51 +00:00
}
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectBounce ( float fPeriod , RageVector3 vect )
2002-07-27 19:29:51 +00:00
{
2003-03-02 01:43:33 +00:00
m_Effect = bounce ;
2003-02-17 12:19:42 +00:00
m_fEffectPeriodSeconds = fPeriod ;
2003-03-02 01:43:33 +00:00
m_vEffectMagnitude = vect ;
2003-02-17 12:19:42 +00:00
m_fSecsIntoEffect = 0 ;
2002-09-02 21:59:58 +00:00
}
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectBob ( float fPeriod , RageVector3 vect )
2002-09-02 21:59:58 +00:00
{
2003-04-21 22:26:07 +00:00
if ( m_Effect != bob || m_fEffectPeriodSeconds != fPeriod )
{
m_Effect = bob ;
m_fEffectPeriodSeconds = fPeriod ;
m_fSecsIntoEffect = 0 ;
}
2003-03-02 01:43:33 +00:00
m_vEffectMagnitude = vect ;
2002-09-02 21:59:58 +00:00
}
2003-03-02 01:43:33 +00:00
void Actor :: SetEffectSpin ( RageVector3 vect )
{
m_Effect = spin ;
m_vEffectMagnitude = vect ;
}
void Actor :: SetEffectVibrate ( RageVector3 vect )
{
m_Effect = vibrate ;
m_vEffectMagnitude = vect ;
}
2002-09-02 21:59:58 +00:00
2003-03-05 02:52:40 +00:00
void Actor :: SetEffectPulse ( float fPeriod , float fMinZoom , float fMaxZoom )
{
m_Effect = pulse ;
m_fEffectPeriodSeconds = fPeriod ;
m_vEffectMagnitude [ 0 ] = fMinZoom ;
m_vEffectMagnitude [ 1 ] = fMaxZoom ;
}
2002-09-02 21:59:58 +00:00
2003-04-02 05:41:22 +00:00
void Actor :: SetShadowLength ( float fLength )
{
if ( fLength == 0 )
m_bShadow = false ;
else
{
m_fShadowLength = fLength ;
m_bShadow = true ;
}
}
2003-02-24 00:47:13 +00:00
void Actor :: Fade ( float fSleepSeconds , CString sFadeString , float fFadeSeconds , bool bFadingOff )
2002-09-02 21:59:58 +00:00
{
sFadeString . MakeLower ();
2003-03-02 01:43:33 +00:00
sFadeString . Replace ( ' ' , ',' );
2002-09-02 21:59:58 +00:00
TweenState original = m_current ;
TweenState mod = m_current ;
2003-02-23 23:29:22 +00:00
CStringArray asBits ;
2003-03-02 01:43:33 +00:00
split ( sFadeString , "," , asBits );
2003-02-23 23:29:22 +00:00
#define CONTAINS(needle) (find( asBits.begin(), asBits.end(), needle ) != asBits.end())
2002-09-02 21:59:58 +00:00
TweenType tt ;
if ( CONTAINS ( "linear" ) ) tt = TWEEN_LINEAR ;
2003-03-02 01:43:33 +00:00
else if ( CONTAINS ( "accelerate" ) ) tt = bFadingOff ? TWEEN_ACCELERATE : TWEEN_DECELERATE ;
2003-02-24 00:47:13 +00:00
else if ( CONTAINS ( "bounce" ) ) tt = bFadingOff ? TWEEN_BOUNCE_BEGIN : TWEEN_BOUNCE_END ;
2002-09-02 21:59:58 +00:00
else if ( CONTAINS ( "spring" ) ) tt = TWEEN_SPRING ;
else tt = TWEEN_LINEAR ;
2003-01-26 20:49:05 +00:00
float fDeltaX = ( float )( CONTAINS ( "left" ) ?- SCREEN_WIDTH : 0 ) + ( CONTAINS ( "right" ) ?+ SCREEN_HEIGHT : 0 );
float fDeltaY = ( float )( CONTAINS ( "top" ) ?- SCREEN_WIDTH : 0 ) + ( CONTAINS ( "bottom" ) ?+ SCREEN_HEIGHT : 0 );
float fDeltaZ = ( float ) 0 ;
if ( CONTAINS ( "far" ) )
{
fDeltaX *= 2 ;
fDeltaY *= 2 ;
fDeltaZ *= 2 ;
}
mod . pos . x += fDeltaX ;
mod . pos . y += fDeltaY ;
mod . pos . z += fDeltaZ ;
2003-04-21 02:35:16 +00:00
mod . rotation . x += ( CONTAINS ( "spinx" ) ?- 360 : 0 );
mod . rotation . y += ( CONTAINS ( "spiny" ) ?- 360 : 0 );
mod . rotation . z += ( CONTAINS ( "spinz" ) ?- 360 : 0 );
2003-02-23 23:29:22 +00:00
mod . scale . x *= ( CONTAINS ( "foldx" ) ? 0 : 1 ) * ( CONTAINS ( "zoomx" ) || CONTAINS ( "zoom" ) ? 3 : 1 );
mod . scale . y *= ( CONTAINS ( "foldy" ) ? 0 : 1 ) * ( CONTAINS ( "zoomy" ) || CONTAINS ( "zoom" ) ? 3 : 1 );
2002-09-02 21:59:58 +00:00
for ( int i = 0 ; i < 4 ; i ++ )
{
mod . diffuse [ i ] = GetDiffuse ();
mod . diffuse [ i ]. a *= CONTAINS ( "fade" ) ? 0 : 1 ;
}
mod . glow = GetGlow ();
mod . glow . a *= CONTAINS ( "glow" ) ? 1 : 0 ;
2003-03-02 01:43:33 +00:00
TweenState & start = bFadingOff ? original : mod ;
TweenState & end = bFadingOff ? mod : original ;
// apply tweens
2003-01-26 20:49:05 +00:00
StopTweening ();
2003-03-02 01:43:33 +00:00
if ( CONTAINS ( "ghost" ) )
{
// start with no glow, no alpha
start . glow . a = 0 ;
2003-03-05 23:35:43 +00:00
int i ;
for ( i = 0 ; i < 4 ; i ++ )
2003-03-02 01:43:33 +00:00
start . diffuse [ i ]. a = 0 ;
m_current = start ;
TweenState mid ;
TweenState :: MakeWeightedAverage ( mid , start , end , 0.5 );
// tween to full glow, no alpha
mid . glow . a = 1 ;
for ( i = 0 ; i < 4 ; i ++ )
mid . diffuse [ i ]. a = 0 ;
BeginTweening ( fFadeSeconds / 2 , tt );
LatestTween () = mid ;
// snap to full alpha
for ( i = 0 ; i < 4 ; i ++ )
mid . diffuse [ i ]. a = 1 ;
BeginTweening ( 0.0001f , tt );
LatestTween () = mid ;
// tween to no glow
mid . glow . a = 0 ;
BeginTweening ( fFadeSeconds / 2 , tt );
LatestTween () = mid ;
}
else
{
m_current = start ;
BeginTweening ( fSleepSeconds );
BeginTweening ( fFadeSeconds , tt );
LatestTween () = end ;
}
2002-09-02 21:59:58 +00:00
}
2003-04-14 22:01:57 +00:00
void Actor :: AddRotationH ( float rot )
{
RageQuatMultiply ( & DestTweenState (). quat , DestTweenState (). quat , RageQuatFromH ( rot ) );
}
void Actor :: AddRotationP ( float rot )
{
RageQuatMultiply ( & DestTweenState (). quat , DestTweenState (). quat , RageQuatFromP ( rot ) );
}
void Actor :: AddRotationR ( float rot )
{
RageQuatMultiply ( & DestTweenState (). quat , DestTweenState (). quat , RageQuatFromR ( rot ) );
}
2003-06-20 23:04:11 +00:00
float Actor :: Command ( CString sCommandString )
2003-03-02 01:43:33 +00:00
{
2003-03-24 21:37:13 +00:00
// OPTIMIZATION OPPORTUNITY: sCommandString could be parsed more efficiently.
2003-03-02 01:43:33 +00:00
2003-06-20 23:04:11 +00:00
sCommandString . MakeLower ();
2003-03-02 01:43:33 +00:00
CStringArray asCommands ;
split ( sCommandString , ";" , asCommands , true );
for ( unsigned c = 0 ; c < asCommands . size (); c ++ )
{
CStringArray asTokens ;
split ( asCommands [ c ], "," , asTokens , true );
2003-05-07 04:03:46 +00:00
for ( unsigned d = 0 ; d < asTokens . size (); d ++ )
{
2003-07-07 01:29:18 +00:00
TrimLeft ( asTokens [ d ]);
TrimRight ( asTokens [ d ]);
2003-05-07 04:03:46 +00:00
}
2003-07-07 01:29:18 +00:00
if ( asTokens [ 0 ]. size () == 0 )
continue ;
this -> HandleCommand ( asTokens );
}
return GetTweenTimeLeft ();
}
inline CString GetParam ( const CStringArray & sParams , int iIndex , int & iMaxIndexAccessed )
{
iMaxIndexAccessed = max ( iIndex , iMaxIndexAccessed );
if ( iIndex < int ( sParams . size ()) )
return sParams [ iIndex ];
else
return "" ;
}
void Actor :: HandleCommand ( const CStringArray & asTokens )
{
int iMaxIndexAccessed = 0 ;
2003-03-02 01:43:33 +00:00
2003-03-24 21:37:13 +00:00
#define sParam(i) (GetParam(asTokens,i,iMaxIndexAccessed))
2003-03-02 01:43:33 +00:00
#define fParam(i) ((float)atof(sParam(i)))
#define iParam(i) (atoi(sParam(i)))
#define bParam(i) (iParam(i)!=0)
2003-07-07 01:29:18 +00:00
const CString & sName = asTokens [ 0 ];
2003-03-24 21:37:13 +00:00
2003-07-07 01:29:18 +00:00
// Commands that go in the tweening queue:
if ( sName == "sleep" ) { BeginTweening ( fParam ( 1 ), TWEEN_LINEAR ); BeginTweening ( 0 , TWEEN_LINEAR ); }
else if ( sName == "linear" ) BeginTweening ( fParam ( 1 ), TWEEN_LINEAR );
else if ( sName == "accelerate" ) BeginTweening ( fParam ( 1 ), TWEEN_ACCELERATE );
else if ( sName == "decelerate" ) BeginTweening ( fParam ( 1 ), TWEEN_DECELERATE );
else if ( sName == "bouncebegin" ) BeginTweening ( fParam ( 1 ), TWEEN_BOUNCE_BEGIN );
else if ( sName == "bounceend" ) BeginTweening ( fParam ( 1 ), TWEEN_BOUNCE_END );
else if ( sName == "spring" ) BeginTweening ( fParam ( 1 ), TWEEN_SPRING );
2003-10-24 08:50:35 +00:00
else if ( sName == "stoptweening" ) { StopTweening (); BeginTweening ( 0.0001f , TWEEN_LINEAR ); } // Why BeginT again? -Chris
else if ( sName == "finishtweening" ) FinishTweening ();
2003-07-07 01:29:18 +00:00
else if ( sName == "x" ) SetX ( fParam ( 1 ) );
else if ( sName == "y" ) SetY ( fParam ( 1 ) );
else if ( sName == "z" ) SetZ ( fParam ( 1 ) );
else if ( sName == "addx" ) SetX ( GetX () + fParam ( 1 ) );
else if ( sName == "addy" ) SetY ( GetY () + fParam ( 1 ) );
else if ( sName == "addz" ) SetZ ( GetZ () + fParam ( 1 ) );
else if ( sName == "zoom" ) SetZoom ( fParam ( 1 ) );
else if ( sName == "zoomx" ) SetZoomX ( fParam ( 1 ) );
else if ( sName == "zoomy" ) SetZoomY ( fParam ( 1 ) );
2003-04-02 18:15:35 +00:00
// else if( sName=="zoomz" ) SetZoomZ( fParam(1) );
2003-07-07 01:29:18 +00:00
else if ( sName == "zoomtowidth" ) ZoomToWidth ( fParam ( 1 ) );
else if ( sName == "zoomtoheight" ) ZoomToHeight ( fParam ( 1 ) );
2003-11-08 20:37:40 +00:00
else if ( sName == "stretchto" ) StretchTo ( RectF ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 ) ) );
2003-07-07 01:29:18 +00:00
else if ( sName == "cropleft" ) SetCropLeft ( fParam ( 1 ) );
else if ( sName == "croptop" ) SetCropTop ( fParam ( 1 ) );
else if ( sName == "cropright" ) SetCropRight ( fParam ( 1 ) );
else if ( sName == "cropbottom" ) SetCropBottom ( fParam ( 1 ) );
2003-11-08 19:23:40 +00:00
else if ( sName == "fadeleft" ) SetFadeLeft ( fParam ( 1 ) );
else if ( sName == "fadetop" ) SetFadeTop ( fParam ( 1 ) );
else if ( sName == "faderight" ) SetFadeRight ( fParam ( 1 ) );
else if ( sName == "fadebottom" ) SetFadeBottom ( fParam ( 1 ) );
else if ( sName == "fadecolor" ) SetFadeDiffuseColor ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
2003-07-07 01:29:18 +00:00
else if ( sName == "diffuse" ) SetDiffuse ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "diffuseleftedge" ) SetDiffuseLeftEdge ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "diffuserightedge" ) SetDiffuseRightEdge ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "diffusetopedge" ) SetDiffuseTopEdge ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "diffusebottomedge" ) SetDiffuseBottomEdge ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
/* Add left/right/top/bottom for alpha if needed. */
else if ( sName == "diffusealpha" ) SetDiffuseAlpha ( fParam ( 1 ) );
else if ( sName == "glow" ) SetGlow ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "glowmode" ) {
if ( ! sParam ( 1 ). CompareNoCase ( "whiten" ))
SetGlowMode ( GLOW_WHITEN );
else if ( ! sParam ( 1 ). CompareNoCase ( "brighten" ))
SetGlowMode ( GLOW_BRIGHTEN );
else ASSERT ( 0 );
}
else if ( sName == "rotationx" ) SetRotationX ( fParam ( 1 ) );
else if ( sName == "rotationy" ) SetRotationY ( fParam ( 1 ) );
else if ( sName == "rotationz" ) SetRotationZ ( fParam ( 1 ) );
else if ( sName == "heading" ) AddRotationH ( fParam ( 1 ) );
else if ( sName == "pitch" ) AddRotationP ( fParam ( 1 ) );
else if ( sName == "roll" ) AddRotationR ( fParam ( 1 ) );
else if ( sName == "shadowlength" ) SetShadowLength ( fParam ( 1 ) );
else if ( sName == "horizalign" ) SetHorizAlign ( sParam ( 1 ) );
else if ( sName == "vertalign" ) SetVertAlign ( sParam ( 1 ) );
else if ( sName == "diffuseblink" ) SetEffectDiffuseBlink ();
else if ( sName == "diffuseshift" ) SetEffectDiffuseShift ();
else if ( sName == "glowblink" ) SetEffectGlowBlink ();
else if ( sName == "glowshift" ) SetEffectGlowShift ();
else if ( sName == "rainbow" ) SetEffectRainbow ();
else if ( sName == "wag" ) SetEffectWag ();
else if ( sName == "bounce" ) SetEffectBounce ();
else if ( sName == "bob" ) SetEffectBob ();
else if ( sName == "pulse" ) SetEffectPulse ();
else if ( sName == "spin" ) SetEffectSpin ();
else if ( sName == "vibrate" ) SetEffectVibrate ();
else if ( sName == "stopeffect" ) SetEffectNone ();
else if ( sName == "effectcolor1" ) SetEffectColor1 ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "effectcolor2" ) SetEffectColor2 ( RageColor ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 ), fParam ( 4 )) );
else if ( sName == "effectperiod" ) SetEffectPeriod ( fParam ( 1 ) );
else if ( sName == "effectmagnitude" ) SetEffectMagnitude ( RageVector3 ( fParam ( 1 ), fParam ( 2 ), fParam ( 3 )) );
else if ( sName == "scaletocover" ) { RectI R ( iParam ( 1 ), iParam ( 2 ), iParam ( 3 ), iParam ( 4 )); ScaleToCover ( R ); }
// Commands that take effect immediately (ignoring the tweening queue):
else if ( sName == "animate" ) EnableAnimation ( bParam ( 1 ) );
else if ( sName == "texturewrapping" ) SetTextureWrapping ( bParam ( 1 ) );
else if ( sName == "additiveblend" ) SetBlendMode ( bParam ( 1 ) ? BLEND_ADD : BLEND_NORMAL );
else if ( sName == "blend" ) SetBlendMode ( sParam ( 1 ) );
else if ( sName == "zbuffer" ) SetUseZBuffer ( bParam ( 1 ) );
2003-07-07 20:24:51 +00:00
else if ( sName == "clearzbuffer" ) SetClearZBuffer ( bParam ( 1 ) );
2003-11-06 07:18:11 +00:00
else if ( sName == "hidden" ) SetHidden ( bParam ( 1 ) );
2003-10-31 02:01:55 +00:00
else if ( sName == "playcommand" ) sParam ( 1 ); /* nop: only BGAnimation handles this but everyone receives it */
2003-07-07 01:29:18 +00:00
else
{
CString sError = ssprintf ( "Actor::HandleCommand: Unrecognized command name '%s'." , sName . c_str () );
LOG -> Warn ( sError );
if ( DISPLAY -> IsWindowed () )
HOOKS -> MessageBoxOK ( sError );
2003-03-02 01:43:33 +00:00
}
2003-06-20 23:04:11 +00:00
2003-07-07 01:29:18 +00:00
if ( iMaxIndexAccessed != ( int ) asTokens . size () - 1 )
{
CString sError = ssprintf ( "Actor::HandleCommand: Wrong number of parameters in command '%s'. Expected %d but there are %d." , join ( "," , asTokens ). c_str (), iMaxIndexAccessed + 1 , ( int ) asTokens . size () );
LOG -> Warn ( sError );
if ( DISPLAY -> IsWindowed () )
HOOKS -> MessageBoxOK ( sError );
}
2003-03-02 01:43:33 +00:00
}
2003-03-19 19:56:27 +00:00
float Actor :: GetCommandLength ( CString command )
{
2003-03-28 00:49:01 +00:00
Actor temp ;
2003-03-19 19:56:27 +00:00
temp . Command ( command );
2003-03-28 00:49:01 +00:00
2003-03-19 19:56:27 +00:00
return temp . GetTweenTimeLeft ();
}
2003-03-02 01:43:33 +00:00
float Actor :: GetTweenTimeLeft () const
2003-01-01 09:05:21 +00:00
{
float tot = 0 ;
2003-02-25 02:51:04 +00:00
for ( unsigned i = 0 ; i < m_TweenInfo . size (); ++ i )
2003-01-01 09:05:21 +00:00
tot += m_TweenInfo [ i ]. m_fTimeLeftInTween ;
return tot ;
}
2003-04-02 05:41:22 +00:00
2003-06-16 20:00:10 +00:00
/* This is a hack to change all tween states while leaving existing tweens alone.
*
* Perhaps the regular Set methods should also take an optional parameter, eg.
* "SET_TWEEN" (normal behavior) or "SET_GLOBAL" to set regardless of tweens.
* That might be ugly, too.
*/
void Actor :: SetGlobalDiffuseColor ( RageColor c )
{
for ( int i = 0 ; i < 4 ; i ++ ) /* color, not alpha */
{
for ( unsigned ts = 0 ; ts < m_TweenStates . size (); ++ ts )
{
m_TweenStates [ ts ]. diffuse [ i ]. r = c . r ;
m_TweenStates [ ts ]. diffuse [ i ]. g = c . g ;
m_TweenStates [ ts ]. diffuse [ i ]. b = c . b ;
}
m_current . diffuse [ i ]. r = c . r ;
m_current . diffuse [ i ]. g = c . g ;
m_current . diffuse [ i ]. b = c . b ;
m_start . diffuse [ i ]. r = c . r ;
m_start . diffuse [ i ]. g = c . g ;
m_start . diffuse [ i ]. b = c . b ;
}
}
void Actor :: SetGlobalX ( float x )
{
for ( unsigned ts = 0 ; ts < m_TweenStates . size (); ++ ts )
m_TweenStates [ ts ]. pos . x = x ;
m_current . pos . x = x ;
m_start . pos . x = x ;
}
2003-04-02 05:41:22 +00:00
void Actor :: TweenState :: Init ()
{
pos = RageVector3 ( 0 , 0 , 0 );
rotation = RageVector3 ( 0 , 0 , 0 );
2003-04-14 22:01:57 +00:00
quat = RageVector4 ( 0 , 0 , 0 , 1 );
2003-04-02 05:41:22 +00:00
scale = RageVector3 ( 1 , 1 , 1 );
2003-06-20 23:04:11 +00:00
crop = RectF ( 0 , 0 , 0 , 0 );
2003-11-08 19:23:40 +00:00
fade = RectF ( 0 , 0 , 0 , 0 );
fadecolor = RageColor ( 1 , 1 , 1 , 0 );
2003-04-02 05:41:22 +00:00
for ( int i = 0 ; i < 4 ; i ++ )
diffuse [ i ] = RageColor ( 1 , 1 , 1 , 1 );
glow = RageColor ( 1 , 1 , 1 , 0 );
2003-05-04 22:35:42 +00:00
glowmode = GLOW_WHITEN ;
2003-04-02 05:41:22 +00:00
}
void Actor :: TweenState :: MakeWeightedAverage ( TweenState & average_out , const TweenState & ts1 , const TweenState & ts2 , float fPercentBetween )
{
2003-06-20 23:04:11 +00:00
average_out . pos = ts1 . pos + ( ts2 . pos - ts1 . pos ) * fPercentBetween ;
average_out . scale = ts1 . scale + ( ts2 . scale - ts1 . scale ) * fPercentBetween ;
average_out . rotation = ts1 . rotation + ( ts2 . rotation - ts1 . rotation ) * fPercentBetween ;
2003-04-14 22:01:57 +00:00
RageQuatSlerp ( & average_out . quat , ts1 . quat , ts2 . quat , fPercentBetween );
2003-06-20 23:04:11 +00:00
average_out . crop . left = ts1 . crop . left + ( ts2 . crop . left - ts1 . crop . left ) * fPercentBetween ;
average_out . crop . top = ts1 . crop . top + ( ts2 . crop . top - ts1 . crop . top ) * fPercentBetween ;
average_out . crop . right = ts1 . crop . right + ( ts2 . crop . right - ts1 . crop . right ) * fPercentBetween ;
average_out . crop . bottom = ts1 . crop . bottom + ( ts2 . crop . bottom - ts1 . crop . bottom ) * fPercentBetween ;
2003-04-14 22:01:57 +00:00
2003-11-08 19:23:40 +00:00
average_out . fade . left = ts1 . fade . left + ( ts2 . fade . left - ts1 . fade . left ) * fPercentBetween ;
average_out . fade . top = ts1 . fade . top + ( ts2 . fade . top - ts1 . fade . top ) * fPercentBetween ;
average_out . fade . right = ts1 . fade . right + ( ts2 . fade . right - ts1 . fade . right ) * fPercentBetween ;
average_out . fade . bottom = ts1 . fade . bottom + ( ts2 . fade . bottom - ts1 . fade . bottom ) * fPercentBetween ;
average_out . fadecolor = ts1 . fadecolor + ( ts2 . fadecolor - ts1 . fadecolor ) * fPercentBetween ;
2003-04-02 05:41:22 +00:00
for ( int i = 0 ; i < 4 ; i ++ )
average_out . diffuse [ i ] = ts1 . diffuse [ i ] + ( ts2 . diffuse [ i ] - ts1 . diffuse [ i ]) * fPercentBetween ;
average_out . glow = ts1 . glow + ( ts2 . glow - ts1 . glow ) * fPercentBetween ;
}
2003-07-05 21:36:47 +00:00
void Actor :: SetBlendMode ( CString s )
{
s . MakeLower ();
if ( s == "normal" ) SetBlendMode ( BLEND_NORMAL );
else if ( s == "add" ) SetBlendMode ( BLEND_ADD );
else if ( s == "noeffect" ) SetBlendMode ( BLEND_NO_EFFECT );
else ASSERT ( 0 );
}