////////////////////////////////////////////////////////////////////////// // update ////////////////////////////////////////////////////////////////////////// void ZClothEmblem::update() { if( !isInViewFrustum( &mAABB, RGetViewFrustum() ) || !m_pWorld->GetBsp()->IsVisible(mAABB) ) { mbIsInFrustrum = false; return; } DWORD currTime = timeGetTime(); if ( currTime - mMyTime < 17 ) return; // 초당 60번으로 제한 mMyTime = timeGetTime(); accumulateForces(); varlet(); memset( m_pForce, 0, sizeof(rvector)*m_nCntP ); //memset( mpWind, 0, sizeof(rvector) ); if(mpWind!=NULL) { mpWind->x = 0.f; mpWind->y = 0.f; mpWind->z = 0.f; } satisfyConstraints(); mWndGenerator.Update( timeGetTime() ); mbIsInFrustrum = true; // 다음 루프에서 시뮬레이션 대상에 추가한다 }
////////////////////////////////////////////////////////////////////////// // CheckSpearing ////////////////////////////////////////////////////////////////////////// void ZClothEmblem::CheckSpearing( rvector& bullet_begin_, rvector& bullet_end_, float power_ ) { if(mbIsInFrustrum) { if(!isInViewFrustum( &mAABB, RGetViewFrustum())) mbIsInFrustrum =false; } else return; rvector dir = bullet_end_ - bullet_begin_; D3DXVec3Normalize( &dir, &dir ); // test line vs AABB if( !D3DXBoxBoundProbe( &mAABB.vmin , &mAABB.vmax, &bullet_begin_, &dir ) ) { return; } // line vs triangle test and determine which particle get power int index[3], sIndex = -1; rvector uvt; rvector* v[3]; for( int i = 0 ; i < mpMeshNode->m_face_num; ++i ) { for( int j = 0 ; j < 3; ++j ) { index[j]= mpMeshNode->m_face_list[i].m_point_index[j]; v[j] = &m_pX[index[j]]; } if( D3DXIntersectTri( v[0], v[1], v[2], &bullet_begin_, &dir, &uvt.x, &uvt.y, &uvt.z ) ) { if( uvt.x + uvt.y < 0.66 ) { sIndex = index[2]; } else if( uvt.x > uvt.y ) { sIndex = index[0]; } else { sIndex = index[1]; } m_pForce[sIndex] += dir * power_; break; } } }
void ZWorld::Draw() { if( m_pSkyBox != NULL ) { m_pSkyBox->Render(); } // farz clipping 을 위해 farz plane 을 다시 계산해준다 if(m_bFog) { ComputeZPlane(RGetViewFrustum()+5,m_fFogFar,-1); } m_pBsp->Draw(); //RGetDynamicLightManager()->Update(); RealSpace2::g_poly_render_cnt = 0; __BP(16,"ZGame::Draw::flags"); m_flags.Draw(); __EP(16); }
////////////////////////////////////////////////////////////////////////// // satisfyConstraints ////////////////////////////////////////////////////////////////////////// void ZClothEmblem::satisfyConstraints() { sConstraint* c; rvector* x1; rvector* x2; rvector delta; float deltaLegth; float diff; int i,j; // if( mbIsInFrustrum ) { for( i = 0 ; i < m_nCntIter; ++i ) { // 캐릭터와 충돌 체크 for (ZCharacterManager::iterator itor = ZGetCharacterManager()->begin(); itor != ZGetCharacterManager()->end(); ++itor) { ZCharacter* pCharacter = (*itor).second; // 현재 화면에 보이는 캐릭터만 대상으로 체크.. 뷰프러스텀 컬링 if( !isInViewFrustum( pCharacter->GetPosition(), CHARACTER_RADIUS + 10, RGetViewFrustum() ) ) { continue; } if( pCharacter->IsDie() && pCharacter->m_dwStatusBitPackingValue.Ref().m_bBlastDrop && !pCharacter->IsVisible() ) { continue; } for( j = 0 ; j < m_nCntP; ++j ) { rvector pos = pCharacter->GetPosition(); rvector myPos = m_pX[j]; if( pos.z + 190 < myPos.z || pos.z > myPos.z ) { continue; } pos.z = 0; myPos.z = 0; rvector dir = myPos - pos; float lengthsq = D3DXVec3LengthSq( &dir ); if( lengthsq > CHARACTER_RADIUS*CHARACTER_RADIUS ) { continue; } D3DXVec3Normalize( &dir, &dir ); myPos = pos + dir * ( CHARACTER_RADIUS ); m_pX[j].x = myPos.x; m_pX[j].y = myPos.y; //break; } } } // Restriction for( list<sRestriction*>::iterator itor = mRestrictionList.begin(); itor != mRestrictionList.end(); ++itor ) { for( int j = 0 ; j < m_nCntP; ++j ) { float* p = (float*)&m_pX[j]; sRestriction* r = *itor; p += (int)r->axis; // 축결정 if( r->compare == COMPARE_GREATER) { if( *p > r->position ) { *p = r->position; } } else { if( *p < r->position -3) { *p = r->position; } } } } // Relaxation for( j = 0 ; j < m_nCntC; ++j ) { c = &m_pConst[j]; x1 = &m_pX[ c->refA ]; x2 = &m_pX[ c->refB ]; delta = *x2 - *x1; deltaLegth = D3DXVec3Length( &delta ); diff = (float) ( ( deltaLegth - c->restLength ) / (deltaLegth )); *x1 += delta * diff * 0.5; *x2 -= delta * diff * 0.5; } } for( i = 0 ; i < m_nCntP; ++i ) { if( m_pHolds[i] & CLOTH_HOLD ) { m_pX[i] = m_pOldX[i]; } } }