// ----------------------------------------------------------------------------
void vHavokChainAnimation::CommonInit()
{
CommonDeinit();
if (!m_pOwner || !m_pOwner->IsOfType(V_RUNTIME_CLASS(VisBaseEntity_cl)))
return;
Vision::Callbacks.OnUpdateSceneFinished += this;
m_pOwnerEntity = static_cast<VisBaseEntity_cl*>(m_pOwner);
VisAnimConfig_cl *pAnimConfig = m_pOwnerEntity->GetAnimConfig();
// If there is no AnimConfig, but we can get a skeleton, create the AnimConfig.
if (!pAnimConfig)
{
VDynamicMesh *pMesh = m_pOwnerEntity->GetMesh();
VisSkeleton_cl *pSkeleton = pMesh ? pMesh->GetSkeleton() : NULL;
if (pSkeleton)
{
VisAnimFinalSkeletalResult_cl* pFinalSkeletalResult;
pAnimConfig = VisAnimConfig_cl::CreateSkeletalConfig(pMesh, &pFinalSkeletalResult);
m_pOwnerEntity->SetAnimConfig(pAnimConfig);
}
}
}
void SimpleSkeletalAnimatedObject_cl::LookAt()
{
// start a single animation
StartSingleAnimation(true);
// start a simple skeletal animation
bool bLooped = true;
int iFlags = VSKELANIMCTRL_DEFAULTS;
if (bLooped)
iFlags |= VANIMCTRL_LOOP;
m_spSingleAnimControl = VisAnimConfig_cl::StartSkeletalAnimation(this, "Run", iFlags);
// find the head bone index
VDynamicMesh *pMesh = GetMesh();
m_iHeadBoneIndex = pMesh->GetSkeleton()->GetBoneIndexByName("skeleton1:Head");
// create a rotation matrix that defines the actual orientation of the head. This is model specific and can
// only be found out by trial and error (typically 0, 90 or 180 deg). In our case the head is rotated by 180 degrees; Without this additional
// orientation that model would follow the target with the backside of the head.
m_RelativeHeadOrientation.setFromEulerAngles (90, 0, 270);
// create an entity that rotates around the model
m_pLookAtTarget = Vision::Game.CreateEntity("VisBaseEntity_cl", hkvVec3::ZeroVector(), "Models/MagicBall.model");
m_fLookAtRotationPhase = 0.f;
}
bool VAnimationEventEffectTrigger::CommonInit()
{
// Initialize base component
if (!IVTransitionEventTrigger::CommonInit())
return false;
// Get owner entity
VisBaseEntity_cl *pEntity = (VisBaseEntity_cl *)m_pOwner;
if (pEntity == NULL)
return false;
// Fill the event trigger info
if (m_iEventTriggerInfoCount <= 0)
{
VEventEffectTriggerInfo_t* info = NULL;
if(m_pActiveTriggerInfo == NULL) //make sure it does not get created more than once
{
// Create new list with only one entry and set properties
info = new VEventEffectTriggerInfo_t();
}
else
{
info = (VEventEffectTriggerInfo_t*)m_pActiveTriggerInfo;
}
info->m_vPositionOffset = PositionOffset;
info->m_vOrientationOffset= OrientationOffset;
// Get effect file
info->m_spEffectFile = VisParticleGroupManager_cl::GlobalManager().LoadFromFile(EffectFilename);
if (info->m_spEffectFile == NULL || !GetEventTriggerInfoBaseData(info))
{
V_SAFE_DELETE(info);
m_pActiveTriggerInfo = NULL;
return false;
}
// Get Bone Index if specified
if (!AttachToBone.IsEmpty())
{
VDynamicMesh* pMesh = pEntity->GetMesh();
if (pMesh == NULL)
return false;
VisSkeleton_cl *pSkeleton = pMesh->GetSkeleton();
if (pSkeleton == NULL)
return false;
info->m_iAttachToBone = pSkeleton->GetBoneIndexByName(AttachToBone);
}
// Set it as the active event trigger info
m_pActiveTriggerInfo = info;
}
return true;
}
// **************************************************
// OVERRIDDEN ENTITY FUNCTIONS
// **************************************************
void TransitionBarbarian_cl::InitFunction()
{
if (!HasMesh())
return;
SetCastShadows(TRUE);
// Setup all animation sequences
SetupAnimations();
if (!m_bModelValid)
return;
if( !m_pPhys)
{
m_pPhys = new vHavokCharacterController();
m_pPhys->Initialize();
hkvAlignedBBox bbox;
VDynamicMesh *pMesh = GetMesh();
pMesh->GetCollisionBoundingBox(bbox);
float r = bbox.getSizeX() * 0.5f;
m_pPhys->Capsule_Radius = r;
m_pPhys->Character_Top.set(0,0,bbox.m_vMax.z - r);
m_pPhys->Character_Bottom.set(0,0,bbox.m_vMin.z + r);
m_pPhys->Max_Slope = 75.0f;
AddComponent(m_pPhys);
// pPhys->SetDebugRendering(TRUE);
}
// Get Model
VDynamicMesh* pModel = GetMesh();
VASSERT(pModel);
// Transition table to use
VTransitionTable *pTable = VTransitionManager::GlobalManager().LoadTransitionTable(pModel,"Barbarian.vTransition");
VASSERT(pTable && pTable->IsLoaded());
// Setup the state machine component and pass the filename of the transition file
// in which the transitions between the various animation states are defined.
m_pStateMachine = new VTransitionStateMachine();
m_pStateMachine->Init(this, pTable);
AddComponent(m_pStateMachine);
// Set initial state
m_pStateMachine->SetState(m_pSkeletalSequenceList[ANIMID_IDLE]);
}
void SimpleSkeletalAnimatedObject_cl::ForwardKinematics()
{
// Apply forward kinematics to the head "Neck" bone, using a bone modifier node. The bone modifier
// gets a skeletal animation as input, modifies the translation of the neck bone and generates the
// combined result. The animation tree looks as follows:
//
// - FinalSkeletalResult
// - BoneModifierNode (modifies the neck bone)
// - SkeletalAnimControl (Walk Animation)
//
// The translation of the neck bone is set on the bone modifier node.
//
// Create a new AnimConfig instance
VDynamicMesh *pMesh = GetMesh();
VisAnimFinalSkeletalResult_cl* pFinalSkeletalResult;
VisAnimConfig_cl* pConfig = VisAnimConfig_cl::CreateSkeletalConfig(pMesh, &pFinalSkeletalResult);
// Get skeletal animation sequence.
VisSkeletalAnimSequence_cl* pAnimSequenceWalk =
static_cast<VisSkeletalAnimSequence_cl*>(pMesh->GetSequence("Walk", VIS_MODELANIM_SKELETAL));
if (pAnimSequenceWalk == NULL)
return;
// Create the animation control to play the walk animation (via a helper function).
VSmartPtr<VisSkeletalAnimControl_cl> spWalkAnimControl = VisSkeletalAnimControl_cl::Create(
pMesh->GetSkeleton(), pAnimSequenceWalk, VANIMCTRL_LOOP|VSKELANIMCTRL_DEFAULTS, 1.0f, true);
// Create the bone modifier node that translates the head bone. Set the animation control instance
// as the input for this node.
m_spBoneModifierNode = new VisAnimBoneModifierNode_cl(pMesh->GetSkeleton());
m_spBoneModifierNode->SetModifierInput(spWalkAnimControl);
hkvQuat customBoneRotation;
// set the neck bone translation on the bone modifier node
m_iNeckBoneIndex = pMesh->GetSkeleton()->GetBoneIndexByName("skeleton1:Neck");
customBoneRotation.setFromEulerAngles (0, -45, 0);
m_spBoneModifierNode->SetCustomBoneRotation(m_iNeckBoneIndex, customBoneRotation, VIS_MODIFY_BONE);
// finally set the bone modifier as the root animation node
pFinalSkeletalResult->SetSkeletalAnimInput(m_spBoneModifierNode);
SetAnimConfig(pConfig);
// The bone modifier node is now part of the animation tree. You can at any time update the translation
// on the bone modifier. The animation system will take care of generating the proper final result.
}
// Render shaders on entities
void VPostProcessTranslucencies::DrawEntitiesShaders(const VisEntityCollection_cl &EntityCollection, VPassType_e ePassType)
{
VisDrawCallInfo_t SurfaceShaderList[RLP_MAX_ENTITY_SURFACESHADERS];
unsigned int iNumEntities = EntityCollection.GetNumEntries();
unsigned int i;
Vision::RenderLoopHelper.BeginEntityRendering();
for (i=0; i<iNumEntities; i++)
{
VisBaseEntity_cl *pEntity = EntityCollection.GetEntry(i);
// Foreground entities will be handled separately
if (pEntity->IsObjectAlwaysInForegroundEnabled()) continue;
if ( pEntity->HasShadersForPass(ePassType) )
{
// Get a list of the corresponding pass type surface shaders
VisShaderSet_cl *pShaderSet = pEntity->GetActiveShaderSet();
if (pShaderSet == NULL) continue;
int iNumSurfaceShaders = pShaderSet->GetShaderAssignmentList(SurfaceShaderList, ePassType, RLP_MAX_ENTITY_SURFACESHADERS);
VASSERT(iNumSurfaceShaders < RLP_MAX_ENTITY_SURFACESHADERS);
if (iNumSurfaceShaders == 0) continue;
VDynamicMesh *pMesh = pEntity->GetMesh();
// If the model has lit surfaces, and if the shaders makes use of the lighting information, we need to set up
// the global lights.
if (pMesh != NULL && pMesh->HasLitSurfaces() && (pShaderSet->GetCombinedTrackingMask()&(VSHADER_TRACKING_LIGHTGRID_PS|VSHADER_TRACKING_LIGHTGRID_GS|VSHADER_TRACKING_LIGHTGRID_VS)) )
{
Vision::RenderLoopHelper.TrackLightGridInfo(pEntity);
}
// Render the entity with the surface shader list
Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(pEntity, iNumSurfaceShaders, SurfaceShaderList);
}
}
Vision::RenderLoopHelper.EndEntityRendering();
}
// Renders foreground entities (i.e. entities which have been flagged as "always in foreground")
void VPostProcessTranslucencies::DrawTransparentForegroundEntities(const VisEntityCollection_cl &EntityCollection)
{
unsigned int iNumEntities = EntityCollection.GetNumEntries(); // this collection only contains foreground objects
if (iNumEntities==0 || m_spForegroundFillPassTechnique==NULL)
return;
INSERT_PERF_MARKER_SCOPE("VisionRenderLoop_cl::DrawForegroundEntities");
unsigned int i;
const hkvMat4* pLastProj = NULL;
Vision::RenderLoopHelper.BeginEntityRendering();
const int iPassCount = m_spForegroundFillPassTechnique->GetShaderCount();
for (int iPass=0;iPass<=iPassCount;iPass++) // +1 passes, where the last one is the actual material pass
{
for (i=0; i<iNumEntities; i++)
{
VisBaseEntity_cl *pEntity = EntityCollection.GetEntry(i);
// Render only Entities that are flagged as "always in foreground"
VASSERT_MSG(pEntity->IsObjectAlwaysInForegroundEnabled(), "Only entities with this flag should be passed to this function");
if (pEntity->HasShadersForPass(VPT_TransparentPass))
{
VDynamicMesh *pMesh = pEntity->GetMesh();
VisShaderSet_cl *pShaderSet = pEntity->GetActiveShaderSet();
VASSERT(pMesh && pShaderSet);
const hkvMat4* pThisProj = pEntity->GetCustomProjectionMatrixForForegroundObject();
if (pThisProj != pLastProj)
{
VisRenderStates_cl::SetCurrentProjectionMatrix(pThisProj);
pLastProj = pThisProj;
}
if (iPass<iPassCount) // depth fill pass
{
VCompiledShaderPass *pPass = m_spForegroundFillPassTechnique->GetShader(iPass);
Vision::RenderLoopHelper.RenderEntityWithShaders(pEntity, 1, &pPass);
}
else // material pass
{
const VisDrawCallInfo_t *pAssignment;
int iNumSurfaceShaders = pShaderSet->GetShaderAssignmentList(&pAssignment);
// If the shaders make use of the lighting information, we need to track the light grid
if (pMesh != NULL && pMesh->HasLitSurfaces() &&
(pShaderSet->GetCombinedTrackingMask() & (VSHADER_TRACKING_LIGHTGRID_PS|VSHADER_TRACKING_LIGHTGRID_GS|VSHADER_TRACKING_LIGHTGRID_VS)) )
{
Vision::RenderLoopHelper.TrackLightGridInfo(pEntity);
}
// Render the entity with the surface shader list
Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(pEntity, iNumSurfaceShaders, pAssignment);
}
}
}
}
Vision::RenderLoopHelper.EndEntityRendering();
// reset to context projection matrix
if (pLastProj)
{
VisRenderStates_cl::SetCurrentProjectionMatrix(NULL);
}
}
BOOL VLineFollowerComponent::StartAnimation(const char *szAnimName)
{
VisBaseEntity_cl* pOwner = (VisBaseEntity_cl *)GetOwner();
if (!pOwner)
return false;
m_bPlayingAnim = false;
// Check for animation sequences
VDynamicMesh *pMesh = pOwner->GetMesh();
if (!pMesh || !pMesh->GetSequenceSetCollection() || !pMesh->GetSequenceSetCollection()->GetSequenceSetCount())
return false;
VisAnimFinalSkeletalResult_cl* pFinalSkeletalResult = NULL;
VisVertexAnimDeformer_cl* pVertexAnimDeformer = NULL;
// Get the sequence(s) for vertex and skeletal animation
VisSkeletalAnimSequence_cl* pAnimSequenceSkeletal = (VisSkeletalAnimSequence_cl*)pMesh->GetSequence(szAnimName, VIS_MODELANIM_SKELETAL);
VisVertexAnimSequence_cl* pAnimSequenceVertex = (VisVertexAnimSequence_cl*)pMesh->GetSequence(szAnimName, VIS_MODELANIM_VERTEX);
// If no sequence with the given name is present
if ((!pAnimSequenceSkeletal) && (!pAnimSequenceVertex))
{
VisAnimSequenceSet_cl * pSequenceSet = pMesh->GetSequenceSetCollection()->GetSequenceSet(0);
// Find the first skeletal or vertex animation and use it
for (int i=0; i< pSequenceSet->GetSequenceCount(); ++i)
{
VisAnimSequence_cl* pTempAnimSequence = pSequenceSet->GetSequence(i);
if (pTempAnimSequence->GetType() == VIS_MODELANIM_SKELETAL)
{
// If it is a skeletal animation, create a config for it
VisAnimConfig_cl* pConfig = VisAnimConfig_cl::CreateSkeletalConfig(pMesh, &pFinalSkeletalResult);
VisSkeletalAnimControl_cl* pSkeletalAnimControl = VisSkeletalAnimControl_cl::Create(pMesh->GetSkeleton(), (VisSkeletalAnimSequence_cl*)pTempAnimSequence, VANIMCTRL_LOOP|VSKELANIMCTRL_DEFAULTS, 1.0f, true);
pFinalSkeletalResult->SetSkeletalAnimInput(pSkeletalAnimControl);
pOwner->SetAnimConfig(pConfig);
m_bPlayingAnim = true;
return true;
}
else if (pTempAnimSequence->GetType() == VIS_MODELANIM_VERTEX)
{
// If it is a vertex animation, create a config for it
VisAnimConfig_cl* pConfig = VisAnimConfig_cl::CreateVertexConfig(pMesh, &pVertexAnimDeformer);
VisVertexAnimControl_cl* pVertexAnimControl = VisVertexAnimControl_cl::Create((VisVertexAnimSequence_cl*)pTempAnimSequence, VANIMCTRL_LOOP|VSKELANIMCTRL_DEFAULTS, 1.0f, true);
pVertexAnimDeformer->AddVertexAnimControl(pVertexAnimControl, 1.0f);
pOwner->SetAnimConfig(pConfig);
m_bPlayingAnim = true;
return true;
}
}
// If neither a skeletal nor a vertex animation has been found, report failure
return false;
}
// If both a vertex and a skeletal animation with the given name has been found
// create a combined config for skeletal and vertex animation.
VisAnimConfig_cl* pConfig = NULL;
if ((pAnimSequenceSkeletal) && (pAnimSequenceVertex))
pConfig = VisAnimConfig_cl::CreateSkeletalVertexConfig(pMesh, &pFinalSkeletalResult, &pVertexAnimDeformer);
// If it is just a skeletal animation, create a config for it
if (pAnimSequenceSkeletal)
{
if (!pConfig)
pConfig = VisAnimConfig_cl::CreateSkeletalConfig(pMesh, &pFinalSkeletalResult);
// If a skeletal animation has been found create a control for it
VisSkeletalAnimControl_cl* pSkeletalAnimControl = VisSkeletalAnimControl_cl::Create(pMesh->GetSkeleton(), pAnimSequenceSkeletal, VANIMCTRL_LOOP|VSKELANIMCTRL_DEFAULTS, 1.0f, true);
// And set it as the input for the final skeletal result
pFinalSkeletalResult->SetSkeletalAnimInput(pSkeletalAnimControl);
}
// If it is just a vertex animation, create a config for it
if (pAnimSequenceVertex)
{
if (!pConfig)
pConfig = VisAnimConfig_cl::CreateVertexConfig(pMesh, &pVertexAnimDeformer);
// If a vertex animation has been found create a control for it
VisVertexAnimControl_cl* pVertexAnimControl = VisVertexAnimControl_cl::Create(pAnimSequenceVertex, VANIMCTRL_LOOP|VSKELANIMCTRL_DEFAULTS, 1.0f, true);
// And set add it to the vertex anim deformer
pVertexAnimDeformer->AddVertexAnimControl(pVertexAnimControl, 1.0f);
}
// Set the current config
pOwner->SetAnimConfig(pConfig);
// Make sure we get the motion delta from the animation
pOwner->GetAnimConfig()->SetFlags(pOwner->GetAnimConfig()->GetFlags() | APPLY_MOTION_DELTA | MULTITHREADED_ANIMATION);
// And report success
m_bPlayingAnim = true;
return true;
}
VBool SaveGame(int iNum)
{
if ( (iNum < 1) || (iNum > 4) )
{
// we just allow 4 save games
return FALSE;
}
int i;
char pszSaveFileName[FS_MAX_PATH];
sprintf(pszSaveFileName,SAVEGAME_NAME, iNum);
IVFileOutStream* pOut = Vision::File.Create(pszSaveFileName);
// creating the file didn't work!
if (!pOut)
{
return FALSE;
}
VArchive ar( pszSaveFileName, pOut, Vision::GetTypeManager() );
// serialize global game data
ar << ARCHIVE_START_TAG; // magic number
int iSavingVersion = Vision::GetArchiveVersion();
ar << iSavingVersion; // archive class version
ar << g_iCurrentMap; // current map number
ar << Vision::GetTimer()->GetTime(); // current time
// count entities
SerializeBaseEntity_cl *pSerEnt = NULL;
VisBaseEntity_cl *pEnt = NULL;
int iFullCtr = 0;
int iReCreateCtr = 0;
int iNumOfAllEntities = VisBaseEntity_cl::ElementManagerGetSize();
for (i = 0; i < iNumOfAllEntities; i++)
{
pEnt = VisBaseEntity_cl::ElementManagerGet(i);
if ( pEnt )
{
if ( pEnt->IsOfType(SerializeBaseEntity_cl::GetClassTypeId()) )
{
pSerEnt = static_cast<SerializeBaseEntity_cl*>(pEnt);
if ( pSerEnt->GetSerializeType() == SERIALIZE_FULL )
iFullCtr++;
else
iReCreateCtr++;
}
}
}
// serialize number of entities
ar << iReCreateCtr;
ar << iFullCtr;
hkvVec3 vTemp;
// do ReCreate serialization of entities
for (i = 0; i < iNumOfAllEntities; i++)
{
pEnt = VisBaseEntity_cl::ElementManagerGet(i);
if ( pEnt )
{
if ( pEnt->IsOfType(SerializeBaseEntity_cl::GetClassTypeId()) )
{
pSerEnt = (SerializeBaseEntity_cl *) pEnt;
if ( pSerEnt->GetSerializeType() == SERIALIZE_RECREATE )
{
char pszEntityParams[4000];
GetEntityParameters( pSerEnt, pszEntityParams );
VDynamicMesh* pMesh = pSerEnt->GetMesh();
ar << pSerEnt->GetClassFullName() << pSerEnt->GetEntityKey();
vTemp = pSerEnt->GetPosition();
vTemp.SerializeAsVisVector (ar);
vTemp = pSerEnt->GetOrientation();
vTemp.SerializeAsVisVector (ar);
const char *szFilename = pMesh ? pMesh->GetFilename() : NULL;
ar << szFilename << pszEntityParams;
}
}
}
}
// do full serialization of entities
for (i = 0; i < iNumOfAllEntities; i++)
{
pEnt = VisBaseEntity_cl::ElementManagerGet(i);
if ( pEnt )
{
if ( pEnt->IsOfType(SerializeBaseEntity_cl::GetClassTypeId()) )
{
pSerEnt = (SerializeBaseEntity_cl *) pEnt;
if ( pSerEnt->GetSerializeType() == SERIALIZE_FULL )
{
ar << pSerEnt;
}
}
}
}
// store end tag - useful to verify a valid archive
//.........这里部分代码省略.........
请发表评论