//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifdef _MSC_VER #pragma warning(disable : 4786 4018) #endif #include "appSequence.h" #include "appNode.h" #include "appConfig.h" #include "DTSShape.h" namespace DTS { const char * AppSequenceNode::getName() { const char * prefix = "Sequence::"; const char * name = mAppNode->getName(); if (!_strnicmp(name,prefix,strlen(prefix))) name += strlen(prefix); return name; } void AppSequenceNode::getSequenceData(AppSequenceData * seqData) { seqData->cyclic = true; seqData->blend = false; seqData->ignoreGround = false; seqData->enableMorph = false; seqData->enableTVert = false; seqData->enableVis = true; seqData->enableTransform = true; seqData->enableScale = true; seqData->enableUniformScale = true; seqData->enableAlignedScale = true; seqData->enableArbitraryScale = true; seqData->enableIFL = true; seqData->forceMorph = false; seqData->forceTVert = false; seqData->forceVis = false; seqData->forceTransform = false; seqData->forceScale = false; seqData->frameRate = 30; seqData->groundFrameRate = 10; seqData->numFrames = 0; seqData->groundNumFrames = 0; seqData->overrideDuration = -1.0f; seqData->priority = 5.0f; S32 startFrame = 0; S32 endFrame = 0; S32 blendReferenceFrame = 0; mAppNode->getBool("cyclic",seqData->cyclic); mAppNode->getBool("blend",seqData->blend); mAppNode->getBool("ignoreGround",seqData->ignoreGround); mAppNode->getBool("enableMorph",seqData->enableMorph); mAppNode->getBool("enableTVert",seqData->enableTVert); mAppNode->getBool("enableVis",seqData->enableVis); mAppNode->getBool("enableTransform",seqData->enableTransform); mAppNode->getBool("enableScale",seqData->enableScale); mAppNode->getBool("enableUniformScale",seqData->enableUniformScale); mAppNode->getBool("enableAlignedScale",seqData->enableAlignedScale); mAppNode->getBool("enableArbitraryScale",seqData->enableArbitraryScale); mAppNode->getBool("enableIFL",seqData->enableIFL); mAppNode->getBool("forceMorph",seqData->forceMorph); mAppNode->getBool("forceTVert",seqData->forceTVert); mAppNode->getBool("forceVis",seqData->forceVis); mAppNode->getBool("forceTransform",seqData->forceTransform); mAppNode->getBool("forceScale",seqData->forceScale); mAppNode->getFloat("priority",seqData->priority); mAppNode->getInt("startFrame",startFrame); mAppNode->getInt("endFrame",endFrame); mAppNode->getInt("blendReferenceFrame",blendReferenceFrame); mAppNode->getFloat("overrideDuration",seqData->overrideDuration); mAppNode->getFloat("frameRate",seqData->frameRate); if (seqData->frameRate<0.000001f) seqData->frameRate = 1.0f/30.0f; mAppNode->getFloat("groundFrameRate",seqData->groundFrameRate); if (seqData->groundFrameRate<0.000001f) seqData->groundFrameRate = 1.0f/10.0f; // convert from frames to times F32 appFPS = AppConfig::AppFramesPerSec(); // not necessarily same as exported fps F32 startTime = F32(startFrame) / appFPS; F32 endTime = F32(endFrame) / appFPS; F32 blendReferenceTime = F32(blendReferenceFrame) / appFPS; seqData->startTime.set(startTime,0); seqData->endTime.set(endTime,0); seqData->blendReferenceTime.set(blendReferenceTime,0); F32 duration = seqData->endTime.getF32() - seqData->startTime.getF32(); if (seqData->cyclic) // This is required to match up with what is displayed by 3dsMax when // playing animation cyclically. Set to zero for apps that don't need it. duration += AppConfig::CyclicSequencePadding(); F32 delta = 0.0f; F32 groundDelta = 0.0f; // Get sequence timing information if (mAppNode->getInt("numFrames",seqData->numFrames) && seqData->numFrames>0) seqData->numFrames--; else seqData->numFrames = (S32) ((duration + 0.25f/seqData->frameRate) * seqData->frameRate); delta = seqData->numFrames ? duration / F32(seqData->numFrames) : duration; if (!seqData->cyclic) seqData->numFrames++; // Get sequence ground timing information if (mAppNode->getInt("groundNumFrames",seqData->groundNumFrames) && seqData->groundNumFrames>1) { groundDelta = duration / (F32)(seqData->groundNumFrames-1); } else { seqData->groundNumFrames = (S32)((duration + 0.25f/seqData->groundFrameRate) * seqData->groundFrameRate); groundDelta = seqData->groundNumFrames ? duration / (F32) seqData->groundNumFrames : duration; seqData->groundNumFrames++; } seqData->duration.set(duration,0); seqData->delta.set(delta,0); seqData->groundDelta.set(groundDelta,0); } S32 AppSequenceNode::getNumTriggers() { S32 num = 0; mAppNode->getInt("numTriggers",num); return num; } Trigger AppSequenceNode::getTrigger(S32 idx) { char buffer[256]; sprintf(buffer,"triggerFrame%i",idx); S32 frame = 0; mAppNode->getInt(buffer,frame); sprintf(buffer,"triggerState%i",idx); S32 state = 0; mAppNode->getInt(buffer,state); AppSequenceData seqData; getSequenceData(&seqData); F32 appFPS = AppConfig::AppFramesPerSec(); // not necessarily same as exported fps Trigger ret; if (state<0) ret.state = 1<<(-state-1); else ret.state = (1<<(state-1)) | TriggerState::StateOn; if (seqData.duration.getF32()<0.001f) ret.pos=0; else ret.pos = F32(frame/appFPS-seqData.startTime.getF32())/seqData.duration.getF32(); return ret; } void AppSequence::setTSSequence(Sequence * seq) { AppSequenceData seqData; getSequenceData(&seqData); // fill in some sequence data seq->flags = 0; if (seqData.cyclic) seq->flags |= Sequence::Cyclic; if (seqData.blend) seq->flags |= Sequence::Blend; seq->priority = S32(seqData.priority); seq->numKeyFrames = seqData.numFrames; seq->duration = seqData.overrideDuration>0 ? seqData.overrideDuration : seqData.duration.getF32(); seq->toolBegin = seqData.startTime.getF32(); seq->numTriggers = 0; seq->firstTrigger = 0; } }; // namespace DTS