Пример #1
0
/**
* 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);
}
Пример #2
0
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;
}
Пример #3
0
/**
* 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;
	}
}
Пример #4
0
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;
}
Пример #5
0
/*************************************************************************
 * 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());
}
Пример #7
0
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;
}
Пример #9
0
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);
}
Пример #10
0
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();
}
Пример #11
0
/**
* 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()));
}
Пример #12
0
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;
    }
}
Пример #13
0
/**
* 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());
}
Пример #14
0
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();
	}
}
Пример #15
0
/**
* 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);
	}
}
Пример #16
0
/**
* 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);
}
Пример #17
0
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() );
}
Пример #18
0
/**
* 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());
	}
}
Пример #19
0
////////////////////////////////////////
//		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;
}
Пример #20
0
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;
}
Пример #21
0
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( &centerMotionN, &_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;
}