/** * CAIStateMove::enter * @date Modified April 21, 2006 */ void CAIStateMove::enter(CAIEntity* poAIEntity, CCharacter* poCharacter) { D3DXVECTOR3 vVelocity(0.0f, 0.0f, 0.0f); D3DXVec3Normalize(NULL, &vVelocity, &poCharacter->getVelocity()); poCharacter->setOrientation(vVelocity); // scale the unit velocity based on the entity's type switch (poCharacter->getType()) { case OBJ_ENEMY_ZOMBIECITIZEN: D3DXVec3Scale(&vVelocity, &vVelocity, ZOMBIE_SPEED); break; case OBJ_ENEMY_GASEOUSCLAY: D3DXVec3Scale(&vVelocity, &vVelocity, GASEOUS_SPEED); break; case OBJ_ENEMY_ICECREAMMAN: D3DXVec3Scale(&vVelocity, &vVelocity, ACIDIC_SPEED); break; case OBJ_ENEMY_QUARTERBACK: D3DXVec3Scale(&vVelocity, &vVelocity, QB_SPEED); break; } poCharacter->setVelocity(vVelocity); }
BuildArea* BuildAreaBuilder::CurveAreaBuild(bool _isLeft) { // もともとのStartPosからEndPosの長さ int length = static_cast<int>(sqrt( (m_EndPos.x - m_StartPos.x) * (m_EndPos.x - m_StartPos.x) + (m_EndPos.y - m_StartPos.y) * (m_EndPos.y - m_StartPos.y) + (m_EndPos.z - m_StartPos.z) * (m_EndPos.z - m_StartPos.z))); // エリアの数 int NumZ = 0; int VecLength = 0; if (length % int(ROAD_H_SIZE) == int(ROAD_H_SIZE - 1)) { NumZ = int(length / ROAD_W_SIZE) + 1; VecLength = int(NumZ * ROAD_H_SIZE); } else { NumZ = int(length / ROAD_W_SIZE); VecLength = int(NumZ * ROAD_H_SIZE); } // StartPosからEndPosの角度をとる float angle = atan2(m_EndPos.z - m_StartPos.z, m_EndPos.x - m_StartPos.x); // EndPosを原点に戻して、正規化、スケーリングして、もう一度同じ場所に戻す D3DXVECTOR3 roadVec = m_EndPos - m_StartPos; D3DXVec3Normalize(&roadVec, &roadVec); D3DXVec3Scale(&roadVec, &roadVec, static_cast<float>(length)); roadVec = roadVec + m_StartPos; //@todo ここがずれてる原因と分かったので直す D3DXVECTOR3 Vec = m_EndPos - m_StartPos; D3DXVec3Normalize(&Vec, &Vec); D3DXVec3Scale(&Vec, &Vec, static_cast<float>(VecLength)); Vec = Vec + m_StartPos; BuildArea* pBuildArea = NULL; float length1 = sqrt( (m_ControlPos.x - m_EndPos.x) * (m_ControlPos.x - m_EndPos.x) + (m_ControlPos.y - m_EndPos.y) * (m_ControlPos.y - m_EndPos.y) + (m_ControlPos.z - m_EndPos.z) * (m_ControlPos.z - m_EndPos.z)); float length2 = sqrt( (m_ControlPos.x - m_StartPos.x) * (m_ControlPos.x - m_StartPos.x) + (m_ControlPos.y - m_StartPos.y) * (m_ControlPos.y - m_StartPos.y) + (m_ControlPos.z - m_StartPos.z) * (m_ControlPos.z - m_StartPos.z)); if (length1 > 1000 && length2 > 1000) { pBuildArea = new CurveBuildArea(_isLeft, m_StartPos, m_ControlPos, Vec, roadVec, m_roadStartAngle, m_roadEndAngle, m_StartPosLink, m_EndPosLink); } return pBuildArea; }
/** * CCamera::updateCameraMP * date Modified March 13, 2006 */ void CCamera::updateCameraMP(const D3DXVECTOR3 &one, const D3DXVECTOR3 &two) { // check whether to update or not if(!m_bUpdateMP) return; // set the target to the point b/w the two players' D3DXVec3Scale(&m_Target, &(one + two), 0.5f); // compute the distance b/w the characters float fDist = computeDistance(one, two); // move the camera forward/back based on the change in distance b/w characters m_Position = m_Target + m_TargToPos; m_Position += m_UnitTargPos * ((m_fInitDist - fDist)/m_fInitDist*m_fMoveDist); m_TargToPos = m_Position - m_Target; m_fInitDist = fDist; // if the camera moves too far away, stop it if((fDist = D3DXVec3Length(&m_TargToPos)) > 150.0f) { m_TargToPos *= (1.0f/fDist); m_TargToPos *= 150.0f; } }
static inline Vector* findNearestPointOnLine(Vector* result, Vector* point, Vector* start, Vector* end) { float mu; Vector line; D3DXVec3Subtract( &line, end, start ); mu = D3DXVec3Dot( point, &line ) - D3DXVec3Dot( start, &line ); if( mu <= 0 ) { *result = *start; } else { float lineLength2; lineLength2 = D3DXVec3Dot( &line, &line ); if( mu < lineLength2 ) { mu /= lineLength2; D3DXVec3Scale( result, &line, mu ); D3DXVec3Add( result, result, start ); } else { *result = *end; } } return result; }
/************************************************************************* * D3DXComputeBoundingSphere */ HRESULT WINAPI D3DXComputeBoundingSphere(CONST D3DXVECTOR3* pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, FLOAT *pradius) { D3DXVECTOR3 temp, temp1; FLOAT d; unsigned int i; if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL; temp.x = 0.0f; temp.y = 0.0f; temp.z = 0.0f; temp1 = temp; d = 0.0f; *pradius = 0.0f; for(i=0; i<numvertices; i++) { D3DXVec3Add(&temp1, &temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i)); temp = temp1; } D3DXVec3Scale(pcenter, &temp, 1.0f/((FLOAT)numvertices)); for(i=0; i<numvertices; i++) { d = D3DXVec3Length(D3DXVec3Subtract(&temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i), pcenter)); if ( d > *pradius ) *pradius = d; } return D3D_OK; }
/** * CAIStateQBRangeAttack::update * @date Modified May 9, 2006 */ void CAIStateQBRangeAttack::update(CAIEntity* poAIEntity, CCharacter* poCharacter) { ((CAnimatedMesh*)poCharacter->getMesh())->setAnimationSetByName("Attack"); // look at the player D3DXVECTOR3 vAtGoal; CAINode* poGoalNode = CAIManager::getInstancePtr()->findBestGoal(poCharacter); D3DXVec3Subtract(&vAtGoal, &poGoalNode->getPosition(), &poCharacter->getPosition()); D3DXVec3Normalize(&vAtGoal, &vAtGoal); poCharacter->setOrientation(vAtGoal); // wait for the animation to play if (poAIEntity->getCurrentStateTime() < ((CAnimatedMesh*)poCharacter->getMesh())->getAnimationLength()) return; // spawn projectile CFootBall* poBall = (CFootBall*)CObjectManager::getInstancePtr()->createObject(OBJ_WEAPONPROJ_FOOTBALL); vAtGoal = poCharacter->getBV().centerPt; vAtGoal.y += 10.0f; poBall->setPosition(vAtGoal); D3DXVec3Subtract(&vAtGoal, &poGoalNode->getPosition(), &vAtGoal); D3DXVec3Normalize(NULL, &vAtGoal, &vAtGoal); poBall->setOrientation(vAtGoal); poBall->setVelocity(*D3DXVec3Scale(&vAtGoal, &vAtGoal, 50.0f)); poBall->setBV(poBall->getPosition(), 2.0f); poBall->setPlayer((CPlayer*)poCharacter); ((CEnemy*)(poCharacter))->setAIState(CAIStateQBMeleeAttack::getInstancePtr()); }
void Engine::onMouseMove(int x, int y, uint32_t mouseKeys) { if(m_mouseX < 0) { m_mouseX = x; } if(m_mouseY < 0) { m_mouseX = y; } int dx = m_mouseX - x; int dy = m_mouseY - y; m_mouseX = x; m_mouseY = y; if(mouseKeys & MK_LBUTTON) { m_mainCamera.rotateUp(dx / MOUSE_ROTATE_FACTOR); m_mainCamera.rotateRight(dy / MOUSE_ROTATE_FACTOR); D3DXVECTOR3 look = m_mainCamera.look(); m_mainCamera.setPosition(*D3DXVec3Scale(&look, &look, -m_radius)); updateMatrices(); } }
LPD3DXMESH Renderer::CreateD3DXTextMesh( const char* pString, bool bCentered ) { HRESULT hr; LPD3DXMESH pMeshNew = NULL; HDC hdc = CreateCompatibleDC( NULL ); if( hdc == NULL ) return NULL; HFONT newfont=CreateFont(10, //Height 0, //Width 0, //Escapement 0, //Orientation FW_NORMAL, //Weight false, //Italic false, //Underline false, //Strikeout DEFAULT_CHARSET,//Charset OUT_DEFAULT_PRECIS, //Output Precision CLIP_DEFAULT_PRECIS, //Clipping Precision DEFAULT_QUALITY, //Quality DEFAULT_PITCH|FF_DONTCARE, //Pitch and Family "Arial"); HFONT hFontOld; hFontOld = ( HFONT )SelectObject( hdc, newfont ); hr = D3DXCreateText( m_pD3DDevice, hdc, pString, 0.001f, 0.2f, &pMeshNew, NULL, NULL ); SelectObject( hdc, hFontOld ); DeleteDC( hdc ); if( SUCCEEDED( hr ) ) { if( bCentered ) { // Center text D3DXVECTOR3 vMin, vMax; PosNormalVertex* pVertices; pMeshNew->LockVertexBuffer( 0, reinterpret_cast<VOID**>(&pVertices)); D3DXComputeBoundingBox( (D3DXVECTOR3*)pVertices, pMeshNew->GetNumVertices(), sizeof ( PosNormalVertex ), &vMin, &vMax ); D3DXVECTOR3 vOffset; D3DXVec3Subtract( &vOffset, &vMax, &vMin ); D3DXVec3Scale( &vOffset, &vOffset, 0.5f ); for ( unsigned int i = 0; i < pMeshNew->GetNumVertices(); i++) { D3DXVec3Subtract( &pVertices[i].Coord, &pVertices[i].Coord, &vOffset ); } pMeshNew->UnlockVertexBuffer(); } } return pMeshNew; }
void Pyramid::calcNorm(D3DXVECTOR3* output, Triangle & _tri) { D3DXVECTOR3 x, y; D3DXVec3Subtract(&x, &_tri.b, &_tri.a); D3DXVec3Subtract(&y, &_tri.c, &_tri.a); D3DXVec3Cross(output, &x, &y); D3DXVec3Normalize(output, output); D3DXVec3Scale(output, output, -1.0f); }
void Engine::onMouseWheel(int delta) { m_radius -= delta / MOUSE_WHEEL_FACTOR; if(m_radius < 0.0f) { m_radius = 0.0f; } D3DXVECTOR3 look = m_mainCamera.look(); m_mainCamera.setPosition(*D3DXVec3Scale(&look, &look, -m_radius)); updateMatrices(); }
/** * CAIGroup::calculateAvgPos * @date Modified May 11, 2006 */ void CAIGroup::calculateAvgPos(void) { std::list<CEnemy*>::iterator oEnemyIter = m_loEnemies.begin(); D3DXVECTOR3 vPos(0.0f, 0.0f, 0.0f); while (oEnemyIter != m_loEnemies.end()) { vPos += ((CEnemy*)(*oEnemyIter))->getBV().centerPt; oEnemyIter++; } D3DXVec3Scale(&m_vAvgPos, &vPos, (1.0f / (float)m_loEnemies.size())); }
static inline void calcSphereTriangleDistance( Sphere* sphere, Vector* normal, Vector* v0, Vector* v1, Vector* v2, Vector* collPoint, float* distance ) { // project sphere center onto plane of triangle. Vector* center = &sphere->center; Vector projPoint; float dist2plane = D3DXVec3Dot( v0, normal ) - D3DXVec3Dot( center, normal ); D3DXVec3Scale( &projPoint, normal, dist2plane ); D3DXVec3Add( &projPoint, &projPoint, center ); // does the projected point lie within the collision triangle? Vector* vertices[3]; vertices[0] = v0, vertices[1] = v1, vertices[2] = v2; if( isPointWithinTriangle( &projPoint, vertices, normal ) ) { *distance = fabs( dist2plane ); *collPoint = projPoint; return; } // projected point lies outside the triangle, so find the nearest // point on the triangle boundary... else { float currdist; Vector closestPoint, temp; findNearestPointOnLine( &closestPoint, &projPoint, v0, v1 ); D3DXVec3Subtract( &temp, center, &closestPoint ); *distance = D3DXVec3Length(&temp), *collPoint = closestPoint; findNearestPointOnLine( &closestPoint, &projPoint, v1, v2 ); D3DXVec3Subtract(&temp, center, &closestPoint); currdist = D3DXVec3Length(&temp); if( *distance > currdist ) *distance = currdist, *collPoint = closestPoint; findNearestPointOnLine( &closestPoint, &projPoint, v0, v2 ); D3DXVec3Subtract(&temp, center, &closestPoint); currdist = D3DXVec3Length(&temp); if( *distance > currdist ) *distance = currdist, *collPoint = closestPoint; } }
/** * CAIStateAcidicAttack::update * @date Modified May 4, 2006 */ void CAIStateAcidicAttack::update(CAIEntity* poAIEntity, CCharacter* poCharacter) { D3DCOLOR color = poCharacter->getColor(); if (color == 0xff000000) poCharacter->setColor(0xff005555); else poCharacter->setColor(0xff000000); // look at the player D3DXVECTOR3 vAtGoal; CAINode* poGoalNode = CAIManager::getInstancePtr()->findBestGoal(poCharacter); D3DXVec3Subtract(&vAtGoal, &poGoalNode->getPosition(), &poCharacter->getPosition()); D3DXVec3Normalize(&vAtGoal, &vAtGoal); poCharacter->setOrientation(vAtGoal); // wait so we can flash a bit and then throw if (poAIEntity->getCurrentStateTime() < 0.5) return; ((CAnimatedMesh*)poCharacter->getMesh())->setAnimationSetByName("Attack"); // wait for the animation to play if (poAIEntity->getCurrentStateTime() < (((CAnimatedMesh*)poCharacter->getMesh())->getAnimationLength() + 0.5)) return; // spawn projectile CIceCream* poBall = (CIceCream*)CObjectManager::getInstancePtr()->createObject(OBJ_WEAPONPROJ_ACIDICE); vAtGoal = poCharacter->getBV().centerPt; vAtGoal.y += 10.0f; poBall->setPosition(vAtGoal); D3DXVec3Subtract(&vAtGoal, &poGoalNode->getPosition(), &vAtGoal); D3DXVec3Normalize(NULL, &vAtGoal, &vAtGoal); poBall->setOrientation(vAtGoal); poBall->setVelocity(*D3DXVec3Scale(&vAtGoal, &vAtGoal, 50.0f)); poBall->setBV(poBall->getPosition(), 2.0f); poBall->setPlayer((CPlayer*)poCharacter); ((CEnemy*)(poCharacter))->setAIState(CAIStateAcidicFollow::getInstancePtr()); }
void CActorInstance::OnRender() { D3DMATERIAL8 kMtrl; STATEMANAGER.GetMaterial(&kMtrl); kMtrl.Diffuse=D3DXCOLOR(m_dwMtrlColor); STATEMANAGER.SetMaterial(&kMtrl); // 현재는 이렇게.. 최종적인 형태는 Diffuse와 Blend의 분리로.. // 아니면 이런 형태로 가되 Texture & State Sorting 지원으로.. - [levites] STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); switch(m_iRenderMode) { case RENDER_MODE_NORMAL: BeginDiffuseRender(); RenderWithOneTexture(); EndDiffuseRender(); BeginOpacityRender(); BlendRenderWithOneTexture(); EndOpacityRender(); break; case RENDER_MODE_BLEND: if (m_fAlphaValue == 1.0f) { BeginDiffuseRender(); RenderWithOneTexture(); EndDiffuseRender(); BeginOpacityRender(); BlendRenderWithOneTexture(); EndOpacityRender(); } else if (m_fAlphaValue > 0.0f) { BeginBlendRender(); RenderWithOneTexture(); BlendRenderWithOneTexture(); EndBlendRender(); } break; case RENDER_MODE_ADD: BeginAddRender(); RenderWithOneTexture(); BlendRenderWithOneTexture(); EndAddRender(); break; case RENDER_MODE_MODULATE: BeginModulateRender(); RenderWithOneTexture(); BlendRenderWithOneTexture(); EndModulateRender(); break; } STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); kMtrl.Diffuse=D3DXCOLOR(0xffffffff); STATEMANAGER.SetMaterial(&kMtrl); if (ms_isDirLine) { D3DXVECTOR3 kD3DVt3Cur(m_x, m_y, m_z); D3DXVECTOR3 kD3DVt3LookDir(0.0f, -1.0f, 0.0f); D3DXMATRIX kD3DMatLook; D3DXMatrixRotationZ(&kD3DMatLook, D3DXToRadian(GetRotation())); D3DXVec3TransformCoord(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DMatLook); D3DXVec3Scale(&kD3DVt3LookDir, &kD3DVt3LookDir, 200.0f); D3DXVec3Add(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DVt3Cur); D3DXVECTOR3 kD3DVt3AdvDir(0.0f, -1.0f, 0.0f); D3DXMATRIX kD3DMatAdv; D3DXMatrixRotationZ(&kD3DMatAdv, D3DXToRadian(GetAdvancingRotation())); D3DXVec3TransformCoord(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DMatAdv); D3DXVec3Scale(&kD3DVt3AdvDir, &kD3DVt3AdvDir, 200.0f); D3DXVec3Add(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DVt3Cur); static CScreen s_kScreen; STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); s_kScreen.SetDiffuseColor(1.0f, 1.0f, 0.0f); s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3AdvDir.x, kD3DVt3AdvDir.y, kD3DVt3AdvDir.z); s_kScreen.SetDiffuseColor(0.0f, 1.0f, 1.0f); s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3LookDir.x, kD3DVt3LookDir.y, kD3DVt3LookDir.z); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); STATEMANAGER.RestoreVertexShader(); } }
/** * CAIGroup::disband * @date Modified April 26, 2006 */ void CAIGroup::disband(bool bDisperse) { std::list<CEnemy*>::iterator oEnemyIter = m_loEnemies.begin(); CAIStatePathPlan* poPlan = CAIStatePathPlan::getInstancePtr(); // for dispersal CAIStateMove* poMove = NULL; D3DXVECTOR3 vFrontBack(0.0f, 0.0f, 0.0f), vLeftRight(0.0f, 0.0f, 0.0f), vTemp(0.0f, 0.0f, 0.0f); CAINode* poGoalNode = NULL; float fDot = 0.0f; // if the enemies are to disperse, this information is needed if (bDisperse) { poMove = CAIStateMove::getInstancePtr(); calculateAvgPos(); poGoalNode = CAIManager::getInstancePtr()->findBestGoal(*oEnemyIter); // calculate vectors to perform a halfspace tests to determine members' position in the group D3DXVec3Subtract(&vFrontBack, &poGoalNode->getPosition(), &m_vAvgPos); D3DXVec3Normalize(NULL, &vFrontBack, &vFrontBack); D3DXVec3Cross(&vLeftRight, &D3DXVECTOR3(0.0f, 1.0f, 0.0f), &vLeftRight); D3DXVec3Normalize(NULL, &vLeftRight, &vLeftRight); } while (oEnemyIter != m_loEnemies.end()) { (*oEnemyIter)->getAI()->setGroup(NULL); if (bDisperse) { if ((*oEnemyIter)->getType() == OBJ_ENEMY_ZOMBIECITIZEN) { D3DXVec3Subtract(&vTemp, &ENEMY_PTR(oEnemyIter)->getBV().centerPt, &m_vAvgPos); D3DXVec3Normalize(NULL, &vTemp, &vTemp); fDot = D3DXVec3Dot(&vTemp, &vFrontBack); // if this enemy is in back send him straight to the goal if (fDot <= 0.0f) { (*oEnemyIter)->setAIState(poPlan); } // if this enemy is in front, make him move forward else { ENEMY_PTR(oEnemyIter)->setOrientation(vTemp); D3DXVec3Scale(&vTemp, &vFrontBack, 10.0f); ENEMY_PTR(oEnemyIter)->setVelocity(vTemp); (*oEnemyIter)->setAIState(poMove); } } else { (*oEnemyIter)->setAIState(poPlan); } } else { (*oEnemyIter)->setAIState(poPlan); } oEnemyIter = m_loEnemies.erase(oEnemyIter); } }
/** * CAIStateAcidicFollow::update * @date Modified April 18, 2006 */ void CAIStateAcidicFollow::update(CAIEntity* poAIEntity, CCharacter* poCharacter) { // check for a valid path, one with nodes in it if (poAIEntity->m_loPath.empty()) { // this is bad that there are no nodes to go to // remove our influence poCharacter->setVelocity(m_vVelocity); // but not for now ((CEnemy*)(poCharacter))->setAIState(NULL); return; } m_poCurrentPos->setPosition(poCharacter->getPosition()); // ACIDIC SPECIFIC ////////////////// // see if we are close enough float fDist = computeDistance(PATH_FRONT->getPosition(), poCharacter->getBV().centerPt); if (fDist < ((CAcidic*)(poCharacter))->getAttackDist() + ACIDIC_BUFFER_ZONE) { // needs to get to the center of the range before starting to circle if (fDist < ((CAcidic*)(poCharacter))->getAttackDist()) { ((CAcidic*)(poCharacter))->addCircleTime(CTimer::getInstance().getFrameTime()); } // continue to go to the player D3DXVECTOR3 vNewVelocity; D3DXVec3Subtract(&vNewVelocity, &PATH_BACK->getPosition(), &poCharacter->getBV().centerPt); D3DXVec3Normalize(NULL, &vNewVelocity, &vNewVelocity); // only start to circle if we have time if (((CAcidic*)(poCharacter))->getCircleTime() > 0.0) { // add time for as long as we have gotten close enough to start timing ((CAcidic*)(poCharacter))->addCircleTime(CTimer::getInstance().getFrameTime()); // if we are far enough away, continue to circle if (fDist > (((CAcidic*)(poCharacter))->getAttackDist())) { // circle the player if (((CAcidic*)poCharacter)->getWay()) D3DXVec3Cross(&vNewVelocity, &vNewVelocity, &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); else D3DXVec3Cross(&vNewVelocity, &D3DXVECTOR3(0.0f, 1.0f, 0.0f), &vNewVelocity); } else { // move away from the player D3DXVec3Subtract(&vNewVelocity, &poCharacter->getBV().centerPt, &PATH_BACK->getPosition()); } D3DXVec3Normalize(NULL, &vNewVelocity, &vNewVelocity); } // not fall through plane HACK vNewVelocity.y = 0.0f; poCharacter->setOrientation(vNewVelocity); D3DXVec3Scale(&vNewVelocity, &vNewVelocity, ACIDIC_SPEED); // set velocity poCharacter->setVelocity(vNewVelocity); // circled long enough to attack if (((CAcidic*)(poCharacter))->getCircleTime() > ACIDIC_CIRCLE_TIME) { // change to attack state // remove influences poCharacter->setVelocity(m_vVelocity); ((CEnemy*)(poCharacter))->setAIState(CAIStateAcidicAttack::getInstancePtr()); ((CAcidic*)(poCharacter))->resetCircleTime(); } return; } ////////////////// CAIStatePathFollow::getInstancePtr()->followPath(poAIEntity, poCharacter, ACIDIC_SPEED); }
void Rain::render(void) { float dot; Vector x,y,z; Vector vector; Matrix m; unsigned int i; // culling value float cullDot = cos( Camera::fov * D3DX_PI / 180.0f ); // lock buffers void* vertexData = NULL; void* indexData = NULL; _dxCR( _vertexBuffer->Lock( 0, _numParticles * 4 * sizeof( RainParticleVertex ), &vertexData, D3DLOCK_DISCARD ) ); _dxCR( _indexBuffer->Lock( 0, _numParticles * 6 * sizeof( WORD ), &indexData, D3DLOCK_DISCARD ) ); assert( vertexData ); assert( indexData ); RainParticleVertex* vertex = (RainParticleVertex*)( vertexData ); WORD* index = (WORD*)( indexData ); // render particles RainParticle* particle; unsigned int numVisibleParticles = 0; for( i=0; i<_numParticles; i++ ) { // particle pointer particle = _particles + i; // build billboard matrix z = particle->pos - Camera::eyePos; D3DXVec3Normalize( &z, &z ); // particle culling dot = D3DXVec3Dot( &z, &Camera::eyeDirection ); if( -dot <= cullDot ) continue; // rest of billboard matrix D3DXVec3Scale( &y, &particle->vel, -1 ); D3DXVec3Normalize( &y, &y ); D3DXVec3Cross( &x, &y, &z ); D3DXVec3Normalize( &x, &x ); x.x *= rainXScale, x.y *= rainXScale, x.z *= rainXScale; y.x *= rainYScale, y.y *= rainYScale, y.z *= rainYScale; z.x *= rainZScale, z.y *= rainZScale, z.z *= rainZScale; // finalize m._11 = x.x, m._12 = x.y, m._13 = x.z, m._14 = 0.0f, m._21 = y.x, m._22 = y.y, m._23 = y.z, m._24 = 0.0f, m._31 = z.x, m._32 = z.y, m._33 = z.z, m._34 = 0.0f, m._41 = 0.0f, m._42 = 0.0f, m._43 = 0.0f, m._44 = 1.0f; // transform vertex coordinates by matrix D3DXVec3TransformCoord( &vertex[0].pos, &billboardVertices[0], &m ); D3DXVec3TransformCoord( &vertex[1].pos, &billboardVertices[1], &m ); D3DXVec3TransformCoord( &vertex[2].pos, &billboardVertices[2], &m ); D3DXVec3TransformCoord( &vertex[3].pos, &billboardVertices[3], &m ); vertex[0].pos.x += particle->pos.x, vertex[0].pos.y += particle->pos.y, vertex[0].pos.z += particle->pos.z, vertex[1].pos.x += particle->pos.x, vertex[1].pos.y += particle->pos.y, vertex[1].pos.z += particle->pos.z, vertex[2].pos.x += particle->pos.x, vertex[2].pos.y += particle->pos.y, vertex[2].pos.z += particle->pos.z, vertex[3].pos.x += particle->pos.x, vertex[3].pos.y += particle->pos.y, vertex[3].pos.z += particle->pos.z; // setup uvs vertex[0].uv = billboardUVs[0]; vertex[1].uv = billboardUVs[1]; vertex[2].uv = billboardUVs[2]; vertex[3].uv = billboardUVs[3]; // setup colors vertex[0].color = vertex[1].color = vertex[2].color = vertex[3].color = _ambient; // indices... index[0] = numVisibleParticles * 4 + 0; index[1] = numVisibleParticles * 4 + 1; index[2] = numVisibleParticles * 4 + 2; index[3] = numVisibleParticles * 4 + 0; index[4] = numVisibleParticles * 4 + 2; index[5] = numVisibleParticles * 4 + 3; // next particle vertex += 4, index += 6, numVisibleParticles++; } // unlock buffers _vertexBuffer->Unlock(); _indexBuffer->Unlock(); // render buffers // render _dxCR( dxSetRenderState( D3DRS_LIGHTING, FALSE ) ); _dxCR( dxSetRenderState( D3DRS_ZWRITEENABLE, FALSE ) ); _dxCR( dxSetRenderState( D3DRS_COLORVERTEX, TRUE ) ); _dxCR( dxSetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL ) ); _dxCR( dxSetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 ) ); _dxCR( dxSetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL ) ); _dxCR( dxSetRenderState( D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL ) ); _shader->apply(); _dxCR( iDirect3DDevice->SetTransform( D3DTS_WORLD, &identity ) ); _dxCR( iDirect3DDevice->SetFVF( particleFVF ) ); _dxCR( iDirect3DDevice->SetStreamSource( 0, _vertexBuffer, 0, sizeof( RainParticleVertex ) ) ); _dxCR( iDirect3DDevice->SetIndices( _indexBuffer ) ); _dxCR( iDirect3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, numVisibleParticles * 4, 0, numVisibleParticles * 2 ) ); _dxCR( dxSetRenderState( D3DRS_ZWRITEENABLE, TRUE ) ); _dxCR( dxSetRenderState( D3DRS_LIGHTING, TRUE ) ); // debug info //mainwnd::IMainWnd* iMainWnd; //queryInterfaceT( "MainWnd", &iMainWnd ); //iMainWnd->setWindowText( strformat( "Rain::render(): numVisibleParticles = %d", numVisibleParticles ).c_str() ); }
/** * CAIStatePathFollow::followPath * @dateModified May 4, 2006 */ void CAIStatePathFollow::followPath(CAIEntity* poAIEntity, CCharacter* poCharacter, float fSpeed) { // check for a valid path, one with nodes in it if (poAIEntity->m_loPath.empty()) { // this is bad that there are no nodes to go to // remove our influence poCharacter->setVelocity(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); // but not for now ((CEnemy*)(poCharacter))->setAIState(NULL); return; } // if it isn't moving to a node yet, start the movement if (memcmp(&m_vVelocity, &poCharacter->getVelocity(), sizeof(D3DXVECTOR3)) == 0) { // get vector from current position to next node D3DXVECTOR3 vNextNode; D3DXVec3Subtract(&vNextNode, &PATH_BACK->getPosition(), &poCharacter->getBV().centerPt); D3DXVec3Normalize(NULL, &vNextNode, &vNextNode); // scale by speed poCharacter->setOrientation(vNextNode); D3DXVec3Scale(&vNextNode, &vNextNode, fSpeed); // set velocity poCharacter->setVelocity(vNextNode); } // check to see if we should target to the next node else if (computeDistanceSquared(poCharacter->getBV().centerPt, PATH_BACK->getPosition()) < (PATH_BACK->m_fRadius * PATH_BACK->m_fRadius)) { // we need to go to the next node poAIEntity->m_loPath.pop_back(); // are we now at the goal if (poAIEntity->m_loPath.empty()) { // we are at the goal // remove influence poCharacter->setVelocity(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); // but not for now ((CEnemy*)(poCharacter))->setAIState(NULL); return; } // loose movement around the nodes ////////////////////////////////// D3DXVECTOR3 vNextNode, vGoalNode; // get vector from entity to next node D3DXVec3Subtract(&vNextNode, &PATH_BACK->getPosition(), &poCharacter->getBV().centerPt); // get vector from entity to goal node D3DXVec3Subtract(&vGoalNode, &PATH_FRONT->getPosition(), &poCharacter->getBV().centerPt); D3DXVec3Normalize(NULL, &vGoalNode, &vGoalNode); // project vector from entity to next node onto vector from entity to goal node float fProjection = D3DXVec3Dot(&vNextNode, &vGoalNode); // store the position there now vNextNode = PATH_BACK->getPosition(); // scale vector from entity to goal node by the projection value D3DXVec3Scale(&vGoalNode, &vGoalNode, fProjection); // add vector from entity to goal node to get point closest to next node D3DXVec3Add(&vGoalNode, &poCharacter->getBV().centerPt, &vGoalNode); // get the vector from the next node to the closest point D3DXVec3Subtract(&vGoalNode, &vGoalNode, &vNextNode); // if the magnitude of the vector between the next node and the closest point // is greater than the radius of the node, do some randomization if (D3DXVec3Length(&vGoalNode) > PATH_BACK->m_fRadius) { D3DXVec3Normalize(NULL, &vGoalNode, &vGoalNode); int nRandInt = (int)(PATH_BACK->m_fRadius * 10); float fRandFloat = (float)(rand()%nRandInt) / 10.0f; D3DXVec3Scale(&vGoalNode, &vGoalNode, fRandFloat); } // add vector from next node to point within radius D3DXVec3Add(&vNextNode, &vNextNode, &vGoalNode); // get vector from entity to point within radius to be new velocity D3DXVec3Subtract(&vGoalNode, &vNextNode, &poCharacter->getBV().centerPt); // normalize and scale by speed poCharacter->setOrientation(vGoalNode); D3DXVec3Normalize(NULL, &vGoalNode, &vGoalNode); D3DXVec3Scale(&vGoalNode, &vGoalNode, fSpeed); vGoalNode.y = 0.0f; // set velocity poCharacter->setVelocity(vGoalNode); return; } // have we been following for too long that the goal may have moved if (poAIEntity->getCurrentStateTime() > 0.25f) { // remove our influence poCharacter->setVelocity(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); // should probably path again ((CEnemy*)(poCharacter))->setAIState(CAIStatePathPlan::getInstancePtr()); } }
//////////////////////////////////////// // PUBLIC UTILITY FUNCTIONS //////////////////////////////////////// void Camera::Render() { D3DXVECTOR3 up, position, lookAt; float yaw, pitch, roll; D3DXMATRIX rotationMatrix; D3DXMatrixIdentity(&rotationMatrix); // Setup the vector that points upwards. up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; // Setup the position of the camera in the world. position.x = m_positionX; position.y = m_positionY; position.z = m_positionZ; // Setup where the camera is looking by default. lookAt.x = 0.0f; lookAt.y = 0.0f; lookAt.z = 1.0f; // Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians. pitch = m_rotationX * 0.0174532925f; yaw = m_rotationY * 0.0174532925f; roll = m_rotationZ * 0.0174532925f; // Create the rotation matrix from the yaw, pitch, and roll values. D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll); // Move position based on local X/Y/Z vectors D3DXVECTOR3 xVec(rotationMatrix._11,rotationMatrix._12,rotationMatrix._13); D3DXVECTOR3 yVec(rotationMatrix._21,rotationMatrix._22,rotationMatrix._23); D3DXVECTOR3 zVec(rotationMatrix._31,rotationMatrix._32,rotationMatrix._33); // Get amount to add to position D3DXVec3Scale(&xVec,&xVec,m_moveDelta.x); D3DXVec3Scale(&yVec,&yVec,m_moveDelta.y); D3DXVec3Scale(&zVec,&zVec,m_moveDelta.z); // Autobots: roll out! position += xVec + yVec + zVec; // Save new position m_positionX = position.x; m_positionY = position.y; m_positionZ = position.z; // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin. D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix); D3DXVec3TransformCoord(&up, &up, &rotationMatrix); // Translate the rotated camera position to the location of the viewer. lookAt = position + lookAt; // Finally create the view matrix from the three updated vectors. D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up); return; }
bool Engine::init(int width, int height, HINSTANCE hInstance) { WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, ::WindowProc, 0, 0, hInstance, 0, 0, 0, 0, "CG Task3", 0}; if (0 == RegisterClassEx(&wc)) { return false; } m_window = CreateWindow("CG Task3", "CG Task3: Cylinder", (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), 0, 0, width, height, GetDesktopWindow(), 0, hInstance, 0); if(NULL == m_window) { return false; } m_d3d = Direct3DCreate9(D3D_SDK_VERSION); if(!m_d3d) { return false; } D3DPRESENT_PARAMETERS d3dpp = {0}; d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; HRESULT hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_d3dDevice); if(FAILED(hr) || !m_d3dDevice) { return false; } m_d3dDevice->SetRenderState(D3DRS_AMBIENT, AMBIENT_COLOR); m_d3dDevice->SetRenderState(D3DRS_LIGHTING, false); m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); //m_d3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); D3DVERTEXELEMENT9 vertexDeclaration[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 3 * sizeof(float), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}; IDirect3DVertexDeclaration9 *decl; if(FAILED(m_d3dDevice->CreateVertexDeclaration(vertexDeclaration, &decl))) { return false; } if(FAILED(m_d3dDevice->SetVertexDeclaration(decl))) { return false; } decl->Release(); Vertex *vertices; uint16_t *indices; generateCylinder(CYLINDER_STACKS, CYLINDER_SLICES, CYLINDER_RADIUS, CYLINDER_HEIGHT, 0x80000000, true, &indices, &vertices, m_indexCount, m_vertexCount); if((0 == vertices) || (0 == indices)) { return false; } if(FAILED(m_d3dDevice->CreateVertexBuffer(m_vertexCount * sizeof(Vertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertexBuffer, 0))) { return false; } void *vertexPointer; if(FAILED(m_vertexBuffer->Lock(0, m_vertexCount * sizeof(Vertex), (void**)&vertexPointer, 0))) { return false; } memcpy(vertexPointer, vertices, m_vertexCount * sizeof(Vertex)); if(FAILED(m_vertexBuffer->Unlock())) { return false; } if(FAILED(m_d3dDevice->CreateIndexBuffer(m_indexCount * sizeof(uint16_t), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_indexBuffer, 0))) { return false; } void *indexPointer; if(FAILED(m_indexBuffer->Lock(0, m_indexCount * sizeof(uint16_t), (void**)&indexPointer, 0))) { return false; } memcpy(indexPointer, indices, m_indexCount * sizeof(uint16_t)); if(FAILED(m_indexBuffer->Unlock())) { return false; } #include "shader.h" if (FAILED(m_d3dDevice->CreateVertexShader(g_vs11_main, &m_shader))) { return false; } m_mainCamera.setDirection(DEFAULT_CAMERA_LOOK, DEFAULT_CAMERA_UP); D3DXVECTOR3 look = m_mainCamera.look(); m_mainCamera.setPosition(*D3DXVec3Scale(&look, &look, -m_radius)); D3DXMatrixIdentity(&m_worldMatrix); resize(width, height); m_bones = new D3DXMATRIX[2]; D3DXMatrixIdentity(&m_bones[0]); D3DXMatrixIdentity(&m_bones[1]); D3DXMatrixTranspose(&m_bones[0], &m_bones[0]); D3DXMatrixTranspose(&m_bones[1], &m_bones[1]); m_d3dDevice->SetVertexShader(m_shader); if(FAILED(m_d3dDevice->SetVertexShaderConstantF(4, &(m_bones[0].m[0][0]), 4))) { return false; } if(FAILED(m_d3dDevice->SetVertexShaderConstantF(8, &(m_bones[1].m[0][0]), 4))) { return false; } float sizeConst[4]; sizeConst[0] = 1 / CYLINDER_HEIGHT; if(FAILED(m_d3dDevice->SetVertexShaderConstantF(12, sizeConst, 1))) { return false; } updateMatrices(); return true; }
void Rain::onUpdate(float dt) { // actual dt dt *= _propTimeSpeed; // squared size of emission sphere float emissionSphereSq = _emissionSphere * _emissionSphere; // offset of emission center _centerOffset = _propCenter - _centerOffset; bool predictionIsAvaiable = ( D3DXVec3LengthSq( &_centerOffset ) < emissionSphereSq ); // rough speed of emission center D3DXVec3Scale( &_centerVelocity, &_centerOffset, 1.0f/dt ); // motion direction of of emission center Vector centerMotionN; D3DXVec3Normalize( ¢erMotionN, &_centerVelocity ); // normal of particle velocity Vector velocityN; D3DXVec3Normalize( &velocityN, &_propVelocity ); // magnitude of particle initial velocity float velocityM = D3DXVec3Length( &_propVelocity ); // pass all of particles Vector r,axis; Matrix m; float space; RainParticle* particle; unsigned int i; for( i=0; i<_numParticles; i++ ) { // current particle particle = _particles + i; // check particle is outside of emission sphere D3DXVec3Subtract( &r, &particle->pos, &_propCenter ); if( D3DXVec3LengthSq( &r ) > emissionSphereSq ) { // randomize position if( predictionIsAvaiable ) { r.x = getCore()->getRandToolkit()->getUniform( -1,1 ); r.y = getCore()->getRandToolkit()->getUniform( -1,1 ); r.z = getCore()->getRandToolkit()->getUniform( -1,1 ); D3DXVec3Normalize( &r, &r ); r += centerMotionN; } else { r.x = getCore()->getRandToolkit()->getUniform( -1,1 ); r.y = getCore()->getRandToolkit()->getUniform( -1,1 ); r.z = getCore()->getRandToolkit()->getUniform( -1,1 ); } D3DXVec3Normalize( &r, &r ); space = getCore()->getRandToolkit()->getUniform( 0, _emissionSphere ); D3DXVec3Scale( &particle->pos, &r, space ); particle->pos += _propCenter; // predict position by velocity of emission center if( predictionIsAvaiable ) particle->pos += _centerVelocity * dt; // setup particle velocity if( _propNBias > 0 ) { m = identity; axis.x = getCore()->getRandToolkit()->getUniform( -1,1 ); axis.y = getCore()->getRandToolkit()->getUniform( -1,1 ); axis.z = getCore()->getRandToolkit()->getUniform( -1,1 ); D3DXVec3Normalize( &axis, &axis ); dxRotate( &m, &axis, getCore()->getRandToolkit()->getUniform( - _propNBias, _propNBias ) ); D3DXVec3TransformNormal( &r, &velocityN, &m ); D3DXVec3Scale( &particle->vel, &r, velocityM ); } else { particle->vel = _propVelocity; } // carefully move particle towards edge of emission sphere // (this feature avaiable is for each second particle) if( _useEdgeOffset ) { _useEdgeOffset = 0; D3DXVec3Normalize( &r, &particle->vel ); space = _emissionSphere - space; r.x *= space, r.y *= space, r.z *= space; particle->pos -= r; } else { _useEdgeOffset = 1; } } } // pass all of particles for( i=0; i<_numParticles; i++ ) { // current particle particle = _particles + i; // move particle particle->pos += particle->vel * dt; } // store current emission center _centerOffset = _propCenter; }