//----------------------------------------------------------------------------- // Purpose: // Input : buf - //----------------------------------------------------------------------------- void CBaseDemoAction::SaveKeysToBuffer( int depth, CUtlBuffer& buf ) { // All derived actions will need to do a BaseClass::SaveKeysToBuffer call g_bSaveChained = true; BufPrintf( depth, buf, "name \"%s\"\n", GetActionName() ); if ( ActionHasTarget() ) { BufPrintf( depth, buf, "target \"%s\"\n", GetActionTarget() ); } switch ( GetTimingType() ) { default: case ACTION_USES_NEITHER: break; case ACTION_USES_TICK: { BufPrintf( depth, buf, "starttick \"%i\"\n", GetStartTick() ); } break; case ACTION_USES_TIME: { BufPrintf( depth, buf, "starttime \"%.3f\"\n", GetStartTime() ); } break; } }
//----------------------------------------------------------------------------- // Purpose: // Input : demoframe - // demotime - //----------------------------------------------------------------------------- bool CBaseDemoAction::Update( const DemoActionTimingContext& tc ) { // Already fired and done? if ( HasActionFinished() ) { Assert( GetActionFired() ); return false; } // Already fired, just waiting for finished tag if ( GetActionFired() ) { return true; } // See if it's time to fire switch ( GetTimingType() ) { default: case ACTION_USES_NEITHER: return false; case ACTION_USES_TICK: { if ( GetStartTick() >= tc.prevtick && GetStartTick() <= tc.curtick ) { demoaction->InsertFireEvent( this ); } } break; case ACTION_USES_TIME: { if ( GetStartTime() >= tc.prevtime && GetStartTime() <= tc.curtime ) { demoaction->InsertFireEvent( this ); } } break; } return true; }
bool SGP_MaxInterface::GetMtlAnim( StdMat* pStdMtl, ColorTrack& track, int nChannel ) { if( pStdMtl == NULL ) { assert( false && "std mtl is NULL" ); return false; } int nFrameCount = 0; TimeValue nStartTick = GetStartTick(); TimeValue nEndTick = GetEndTick(); int nTickPerFrame = GetTickPerFrame(); track.bTiling = false; StdUVGen *uv = NULL; Texmap *tx = pStdMtl->GetSubTexmap(nChannel); if( tx ) { if( tx->ClassID() == Class_ID( BMTEX_CLASS_ID, 0 ) ) { BitmapTex *bmt = (BitmapTex*)tx; uv = bmt->GetUVGen(); if( uv ) { track.nUTile = (int)uv->GetUScl(0); track.nVTile = (int)uv->GetVScl(0); if( track.nUTile == 1 && track.nVTile == 1 ) track.bTiling = false; else track.bTiling = true; track.nStartFrame = bmt->GetStartTime(); track.fPlaybackRate = bmt->GetPlaybackRate(); track.nLoopMode = bmt->GetEndCondition(); if( uv->GetUAng( 0 ) != 0.0f || uv->GetVAng( 0 ) != 0.0f ) { track.fUSpeed = uv->GetUAng( 0 ) / piOver180; track.fVSpeed = uv->GetVAng( 0 ) / piOver180; track.bUVMoving = true; } else track.bUVMoving = false; } } } TimeValue t; for( t = nStartTick; t <= nEndTick; t += nTickPerFrame ) nFrameCount++; track.ColorKeyFrame.resize( nFrameCount ); t = nStartTick; for( int i = 0; i < nFrameCount; i++, t += nTickPerFrame ) { SGP_ColorKey key; memset( &key, 0x00, sizeof( key ) ); Color diffuse = pStdMtl->GetDiffuse( t ); Color ambient = pStdMtl->GetAmbient( t ); Color specular = pStdMtl->GetSpecular( t ); Color filter = pStdMtl->GetFilter( t ); float alpha = pStdMtl->GetOpacity( t ); float shinstr = pStdMtl->GetShinStr(t); float selfillum = pStdMtl->GetSelfIllum( t ); float uoffset = 0; float voffset = 0; if( uv ) { uoffset = uv->GetUOffs( t ); voffset = uv->GetVOffs( t ); } /* int nTransparencyType = pStdMtl->GetTransparencyType(); key.dwBlendMode = 0; switch( nTransparencyType ) { case TRANSP_SUBTRACTIVE: key.dwBlendMode |= HR3D_MDX2_MODULATE; break; case TRANSP_ADDITIVE: key.dwBlendMode |= HR3D_MDX2_ADD; break; case TRANSP_FILTER: key.dwBlendMode |= HR3D_MDX2_MODULATE2X; break; default: break; }; */ key.dr = diffuse.r; key.dg = diffuse.g; key.db = diffuse.b; key.da = alpha; if( uv ) { key.uoffset = uv->GetUOffs( t ); key.voffset = uv->GetVOffs( t ); } else { key.uoffset = 0; key.voffset = 0; } track.ColorKeyFrame.getReference(i) = key; } return true; }
int SGP_MaxInterface::GetFrameCount() { return (GetEndTick()-GetStartTick())/GetFps() + 1; }
void SGP_MaxInterface::GetTracks( int nNodeCount, INode** nodes, Track** tracks ) { StartProgressInfo(_M("Get node track...")); TimeValue nStartTick = GetStartTick(); TimeValue nEndTick = GetEndTick(); int nTickPerFrame = GetTickPerFrame(); int nFrameCount = 0; for( TimeValue t = nStartTick; t <= nEndTick; t += nTickPerFrame ) nFrameCount++; for( int i = 0; i < nNodeCount; i++ ) { tracks[i]->vectorVisible.resize( nFrameCount ); tracks[i]->vectorTrans.resize( nFrameCount ); tracks[i]->vectorRot.resize( nFrameCount ); tracks[i]->vectorScale.resize( nFrameCount ); Matrix3 matrix = nodes[i]->GetObjTMAfterWSM ( 0 ); bool bMirror = DotProd ( CrossProd ( matrix.GetRow ( 0 ), matrix.GetRow ( 1 ) ), matrix.GetRow ( 2 ) ) < 0.0 ? true : false; tracks[i]->bMirror = bMirror; } TimeValue t = nStartTick; for( int nFrameId = 0; nFrameId < nFrameCount; nFrameId++, t += nTickPerFrame ) { SetProgressInfo( 100.0f*nFrameId/nFrameCount ); for( int nNodeId = 0; nNodeId < nNodeCount; nNodeId++ ) { INode* pNode = nodes[nNodeId]; Track* pTrack = tracks[nNodeId]; Matrix3 tm = pNode->GetNodeTM(t); // The coordinate system of 3DMax9 is Right-X Up-Z Screenin-Y // But coordinate system of SGP Engine is like D3D Right-X Up-Y Screenin-Z // Node Transform Matrix should be swaped. /* If your matrix looks like this: { rx, ry, rz, 0 } { ux, uy, uz, 0 } { lx, ly, lz, 0 } { px, py, pz, 1 } To change it from left to right or right to left, flip it like this: { rx, rz, ry, 0 } { lx, lz, ly, 0 } { ux, uz, uy, 0 } { px, pz, py, 1 } */ Point3 Row0 = tm.GetRow(0); Point3 Row1 = tm.GetRow(1); Point3 Row2 = tm.GetRow(2); Point3 Row3 = tm.GetRow(3); sgp::swapVariables( Row0.y, Row0.z ); sgp::swapVariables( Row1.x, Row2.x ); sgp::swapVariables( Row1.y, Row2.z ); sgp::swapVariables( Row1.z, Row2.y ); sgp::swapVariables( Row3.y, Row3.z ); tm.SetRow(0, Row0); tm.SetRow(1, Row1); tm.SetRow(2, Row2); tm.SetRow(3, Row3); Point3 trans; Quat quat; Point3 scale; { // calculate the translation component Point3 p; p = tm.GetTrans(); trans.x = p.x; trans.y = p.y; trans.z = p.z; scale.x = tm.GetRow(0).Length(); scale.y = tm.GetRow(1).Length(); scale.z = tm.GetRow(2).Length(); tm.NoScale(); // calculate the rotation component Quat q(tm); if( tracks[nNodeId]->bMirror ) { float m[4][3]; memcpy( m, &tm, sizeof(float)*4*3 ); m[0][0] *= -1; m[1][0] *= -1; m[2][0] *= -1; Matrix3 mm(m); Quat q0(mm); q = q0; } quat.x = q.x; quat.y = q.y; quat.z = q.z; quat.w = q.w; } pTrack->vectorTrans.getReference(nFrameId) = trans; pTrack->vectorRot.getReference(nFrameId) = quat; pTrack->vectorScale.getReference(nFrameId) = scale; float fv = pNode->GetVisibility( t ); if( fv == 0 ) pTrack->vectorVisible.getReference(nFrameId) = false; else pTrack->vectorVisible.getReference(nFrameId) = true; } } StopProgressInfo(); }