void AnimController::Update(unsigned elapsed) { if(current != nullptr) { UpdateInstance(current, elapsed); } }
///SS5の場合 SsPartのarrayIndexは、親子順(子は親より先にいない)と ///なっているためそのまま木構造を作らずUpdateを行う void FSsAnimeDecoder::Update() { int32 time = (int32)NowPlatTime; if(EffectUntreatedDeltaTime < 0.f) { ReloadEffects(); EffectUntreatedDeltaTime = NowPlatTime; } int32 EffectUpdateTimes = (int32)EffectUntreatedDeltaTime; int32 EffectBaseTime = time - EffectUpdateTimes + 1; for(int i = 0; i < PartAnime.Num(); ++i) { FSsPart* part = PartAnime[i].Key; FSsPartAnime* anime = PartAnime[i].Value; if((part->Type == SsPartType::Effect) && (PartState[i].RefEffect)) { // エフェクトは1フレーム単位でしか更新しない // (1フレーム == 0.5フレームずつ2回更新) if(0 == EffectUpdateTimes) { UpdateState(time, part, anime, &PartState[i]); UpdateMatrix(part, anime, &PartState[i]); PartState[i].RefEffect->Update(0.f); } else { for (int32 j = 0; j < (EffectUpdateTimes*2); ++j) { UpdateState(EffectBaseTime + j, part, anime, &PartState[i]); UpdateMatrix(part, anime, &PartState[i]); PartState[i].RefEffect->Update( PartState[i].RefEffect->GetFirstUpdated() ? .5f : 0.f ); } } } else { UpdateState(time, part, anime, &PartState[i]); UpdateMatrix(part, anime, &PartState[i]); if (part->Type == SsPartType::Instance) { UpdateInstance(time, part, anime, &PartState[i]); UpdateVertices(part, anime, &PartState[i]); } } } EffectUntreatedDeltaTime -= EffectUpdateTimes; SortList.Sort(); }
void Scene::SetGlobalScale(float scale) { if((scale - m_fScale) < 0.01 && (scale - m_fScale) > -0.01) return; m_fScale = scale; for(int i = 0; i < g_iMaxInstances; i++) { UpdateInstance(i, 0.f, 1.f / 30.f); } }
Scene::Scene(D3DXVECTOR3& initialWorldSize) : m_iNumUpdateThreads(0), // default m_bTermThreads(false), m_iNumActiveInstances(1), m_fScale(1.f) { for(int i = 0; i < g_iMaxInstances; i++) { m_iInstanceMeshIndices[i] = 0; int instancesPerAxis = (int)pow((double)g_iMaxInstances, 0.333333) + 1; // cuberoot D3DXVECTOR3 unitsPerInstance = initialWorldSize / (float)instancesPerAxis; D3DXVECTOR3 halfWorldSize = initialWorldSize / 2.f; int y = i / (instancesPerAxis * instancesPerAxis); int xzIndex = i % (instancesPerAxis * instancesPerAxis); int z = xzIndex / instancesPerAxis; int x = xzIndex % instancesPerAxis; D3DXVECTOR3 zeroBasedPosition = D3DXVECTOR3((float)x * unitsPerInstance.x, (float)y * unitsPerInstance.y, (float)z * unitsPerInstance.z); D3DXVECTOR3 initialPos = -halfWorldSize + zeroBasedPosition; m_pShips[i] = new SimpleShipController(this, i, initialPos); UpdateInstance(i, 0.f, 1.f / 30.f); } for(int i = 0; i < g_iMaxNumUpdateThreads; i++) { m_hInstanceUpdateThreads[i] = NULL; m_hBeginInstanceUpdateEvent[i] = NULL; m_hEndInstanceUpdateEvent[i] = NULL; m_threadActive[i] = false; } for(int index = 0; index < g_iNumLights ; index++) { memcpy(&m_lights[index], &g_lights[index], sizeof(DC_Light)); // negative falloffdistend means unset, so we set it m_lights[index].fLightFalloffDistEnd = m_lights[index].fLightFarPlane; m_lights[index].fLightFalloffDistRange = m_lights[index].fLightFarPlane / 4.f; m_lights[index].fLightFalloffCosAngleEnd = cosf(m_lights[index].fLightFOV / 2.0f); m_lights[index].fLightFalloffCosAngleRange = 0.1f; D3DXVec3Normalize(&m_lights[index].vLightDir, &m_lights[index].vLightDir); } }
void AnimController::UpdateInstance(Instance* instance, unsigned elapsed) { ResourceAnimation* anim = static_cast<ResourceAnimation*>(App->resources->Get(instance->clip)); if (anim != nullptr && anim->GetDuration() > 0) { unsigned me_elapsed = unsigned(elapsed*instance->speed); me_elapsed = me_elapsed % anim->GetDuration(); unsigned to_end = anim->GetDuration() - instance->time; if (me_elapsed <= to_end) { instance->time += me_elapsed; } else if (instance->loop) { instance->time = (me_elapsed - to_end); } else { instance->time = anim->GetDuration(); } assert(instance->time <= anim->GetDuration()); } if(instance->next != nullptr) { unsigned to_end = instance->fade_duration-instance->fade_time; if(elapsed <= to_end) { instance->fade_time += elapsed; UpdateInstance(instance->next, elapsed); } else { ReleaseInstance(instance->next); instance->next = nullptr; instance->fade_time = instance->fade_duration = 0; } } }
void vsModelInstanceLodGroup::RemoveInstance( vsModelInstance *inst ) { // FIRST, update this instance to not be visible. That gets it out of our // matrix and matrixInstanceId arrays, if it had been visible. UpdateInstance( inst, false ); // NOW, I want to swap this instance into last position in the instance // array. // Check whether I'm already in last position. int lastIndex = m_instance.ItemCount()-1; if ( inst->index != lastIndex ) { // Not in last position, so swap that last item into my current spot. vsModelInstance *last = m_instance[ lastIndex ]; // To do this swap, I potentially need to update two references to the // 'last' item being swapped: the instance array, and (if the 'last' // instance is visible), the modelInstanceId array which tells where // it can be found in the instance array. m_instance[ inst->index ] = last; last->index = inst->index; if ( last->matrixIndex >= 0 ) { m_matrixInstanceId[ last->matrixIndex ] = inst->index; } } // Finally, drop that last instance. m_instance.PopBack(); #ifdef INSTANCED_MODEL_USES_LOCAL_BUFFER m_bufferIsDirty = true; #endif }
void Scene::UpdateScene(double fTime, float fElapsedTime) { { static bool bOneTime = true; if(bMovingLights || bOneTime) { UpdateLights(fTime); bOneTime = false; } } if(bMovingMeshes) { // copy current to previous (for use in per instance logic) memcpy((void*)m_MeshPreviousWorlds, (void*)m_MeshWorlds, m_iNumActiveInstances * sizeof(D3DXMATRIX)); if(m_iNumUpdateThreads == 0) // non threaded updates { for(int i = 0; i < m_iNumActiveInstances; i++) { UpdateInstance(i, (float)fTime, fElapsedTime); } } else { for(int iThread = 0; iThread < m_iNumUpdateThreads; iThread++) { int iStart = iThread * m_iNumActiveInstances / m_iNumUpdateThreads; int iEnd = iStart + (m_iNumActiveInstances / m_iNumUpdateThreads) - 1; if(iThread == m_iNumUpdateThreads - 1) iEnd = m_iNumActiveInstances - 1; // last thread catches the slop m_threadShared[iThread].iStartMeshIndex = iStart; m_threadShared[iThread].iEndMeshIndex = iEnd; m_threadShared[iThread].fTime = (float)fTime; m_threadShared[iThread].fElapsedTime = (float)fElapsedTime; // set event to begin on all scene thread SetEvent(m_hBeginInstanceUpdateEvent[iThread]); m_threadActive[iThread] = true; } // $$ For now just block, but in the future, render can use m_threadActive + start/end to know if a mesh is ready to be rendered; // wait for completion WaitForMultipleObjects(m_iNumUpdateThreads, m_hEndInstanceUpdateEvent, TRUE, INFINITE); for(int iThread = 0; iThread < m_iNumUpdateThreads; iThread++) { m_threadActive[iThread] = false; } } } }