Exemple #1
0
    void MainLoop()
    {
	    Layer[0] = new VRLayer(Session);

	    while (HandleMessages())
	    {
			//Need to check we're visible, before proceeding with velocity changes, 
			//otherwise it does this a lot of times, and we
			//end up miles away from our start point from the sheer number of iterations.
			ovrSessionStatus sessionStatus;
			ovr_GetSessionStatus(Session, &sessionStatus);
			if (sessionStatus.IsVisible)
			{
				// Take out manual yaw rotation (leaving button move for now)
				ActionFromInput(1, false);
				ovrTrackingState trackingState = Layer[0]->GetEyePoses();

				// Set various control methods into camera
				MainCam->Pos = XMVectorAdd(MainCam->Pos, FindVelocityFromTilt(this, Layer[0], &trackingState));

				MainCam->Pos = XMVectorSet(XMVectorGetX(MainCam->Pos),
					GetAccelJumpPosY(this, &trackingState),
					XMVectorGetZ(MainCam->Pos), 0);

				MainCam->Rot = GetAutoYawRotation(Layer[0]);

				// If tap side of Rift, then fire a bullet
				bool singleTap = WasItTapped(trackingState.HeadPose.LinearAcceleration);

				static XMVECTOR bulletPos = XMVectorZero();
				static XMVECTOR bulletVel = XMVectorZero();
				if (singleTap)
				{
					XMVECTOR eye0 = ConvertToXM(Layer[0]->EyeRenderPose[0].Position);
					XMVECTOR eye1 = ConvertToXM(Layer[0]->EyeRenderPose[1].Position);
					XMVECTOR midEyePos = XMVectorScale(XMVectorAdd(eye0, eye1), 0.5f);

					XMVECTOR totalRot = XMQuaternionMultiply(ConvertToXM(Layer[0]->EyeRenderPose[0].Orientation), MainCam->Rot);
					XMVECTOR posOfOrigin = XMVectorAdd(MainCam->Pos, XMVector3Rotate(midEyePos, MainCam->Rot));

					XMVECTOR unitDirOfMainCamera = XMVector3Rotate(XMVectorSet(0, 0, -1, 0), totalRot);

					bulletPos = XMVectorAdd(posOfOrigin, XMVectorScale(unitDirOfMainCamera, 2.0f));
					bulletVel = XMVectorScale(unitDirOfMainCamera, 0.3f);
				}

				// Move missile on, and set its position
				bulletPos = XMVectorAdd(bulletPos, bulletVel);
				XMStoreFloat3(&RoomScene->Models[1]->Pos, bulletPos);

				for (int eye = 0; eye < 2; ++eye)
				{
					Layer[0]->RenderSceneToEyeBuffer(MainCam, RoomScene, eye);
				}

				Layer[0]->PrepareLayerHeader();
				DistortAndPresent(1);
			}
	    }
    }
Exemple #2
0
    void MainLoop()
    {
	    Layer[0] = new VRLayer(HMD);

	    while (HandleMessages())
	    {
            // We turn off yaw to keep the case simple
		    ActionFromInput(1, false);
		    Layer[0]->GetEyePoses();

            // Find perturbation of position from point 1m in front of camera
            XMVECTOR eye0 = ConvertToXM(Layer[0]->EyeRenderPose[0].Position);
            XMVECTOR eye1 = ConvertToXM(Layer[0]->EyeRenderPose[1].Position);
            XMVECTOR perturb = XMVectorScale(XMVectorAdd(eye0, eye1), 0.5f);

            // Calculate velocity from this
            const float sensitivity = 0.2f;
		    XMVECTOR vel = XMVectorScale(XMVectorSet(-XMVectorGetX(perturb), 0, -XMVectorGetZ(perturb), 0), sensitivity);

              // Add velocity to camera
            MainCam->Pos = XMVectorAdd(MainCam->Pos, vel);

            for (int eye = 0; eye < 2; ++eye)
		    {
			    Layer[0]->RenderSceneToEyeBuffer(MainCam, RoomScene, eye);
		    }

		    Layer[0]->PrepareLayerHeader();
		    DistortAndPresent(1);
	    }
    }
VOID DebugDraw::DrawRay( const XMFLOAT3& Origin, const XMFLOAT3& Direction, BOOL bNormalize, D3DCOLOR Color )
{
    MeshVertexP verts[3];
    memcpy( &verts[0], &Origin, 3 * sizeof( FLOAT ) );

    XMVECTOR RayOrigin = XMLoadFloat3( &Origin );
    XMVECTOR RayDirection = XMLoadFloat3( &Direction );
    XMVECTOR NormDirection = XMVector3Normalize( RayDirection );
    if( bNormalize )
        RayDirection = NormDirection;

    XMVECTOR PerpVector;
    XMVECTOR CrossVector = XMVectorSet( 0, 1, 0, 0 );
    PerpVector = XMVector3Cross( NormDirection, CrossVector );

    if( XMVector3Equal( XMVector3LengthSq( PerpVector ), XMVectorSet( 0, 0, 0, 0 ) ) )
    {
        CrossVector = XMVectorSet( 0, 0, 1, 0 );
        PerpVector = XMVector3Cross( NormDirection, CrossVector );
    }
    PerpVector = XMVector3Normalize( PerpVector );

    XMStoreFloat3( ( XMFLOAT3* )&verts[1], XMVectorAdd( RayDirection, RayOrigin ) );
    PerpVector = XMVectorScale( PerpVector, 0.0625f );
    NormDirection = XMVectorScale( NormDirection, -0.25f );
    RayDirection = XMVectorAdd( PerpVector, RayDirection );
    RayDirection = XMVectorAdd( NormDirection, RayDirection );
    XMStoreFloat3( ( XMFLOAT3* )&verts[2], XMVectorAdd( RayDirection, RayOrigin ) );

    SimpleShaders::SetDeclPos();
    SimpleShaders::BeginShader_Transformed_ConstantColor( g_matViewProjection, Color );
    g_pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, 2, ( const VOID* )verts, sizeof( MeshVertexP ) );
    SimpleShaders::EndShader();
}
Exemple #4
0
void GuardianSystemDemo::UpdateObjectsCollisionWithBoundary(float elapsedTimeSec)
{
    if (mGlobalTimeSec < 1.0f) return; // Start update after 1s

    for (int32_t i = 0; i < mDynamicScene.numModels; ++i) {
        XMFLOAT3 newPosition;
        XMVECTOR newPositionVec = XMVectorAdd(mObjPosition[i], XMVectorScale(mObjVelocity[i], elapsedTimeSec));
        XMStoreFloat3(&newPosition, newPositionVec);

        // Test object collision with boundary
        ovrBoundaryTestResult test;
        ovr_TestBoundaryPoint(mSession, (ovrVector3f*)&newPosition.x, ovrBoundary_Outer, &test);

        // Collides with surface at 2cm
        if (test.ClosestDistance < 0.02f) {
            XMVECTOR surfaceNormal = XMVectorSet(test.ClosestPointNormal.x, test.ClosestPointNormal.y, test.ClosestPointNormal.z, 0.0f);
            mObjVelocity[i] = XMVector3Reflect(mObjVelocity[i], surfaceNormal);

            newPositionVec = XMVectorAdd(mObjPosition[i], XMVectorScale(mObjVelocity[i], elapsedTimeSec));
            XMStoreFloat3(&newPosition, newPositionVec);
        }

        mObjPosition[i] = newPositionVec;
        mDynamicScene.Models[i]->Pos = newPosition;
    }
}
Exemple #5
0
	// Converts from barycentric to cartesian coordinates
	XMVECTOR BarycentricToCartesian(const XMFLOAT3& r, FXMVECTOR pos1, FXMVECTOR pos2, FXMVECTOR pos3)
	{
		XMVECTOR rvec;
		rvec = XMVectorScale(pos1, r.x);
		rvec += XMVectorScale(pos2, r.y);
		rvec += XMVectorScale(pos3, r.z);

		return rvec;
	}
HRESULT SceneObjectGrid::InitializeMeshStreams(__in ISceneObjectMesh* pMesh, __in UINT resolution, __in FLOAT size, __in XMFLOAT4 color)
{
	if (resolution == 0 || size <= 0 || pMesh == NULL)
	{
		return E_INVALIDARG;
	}

	XMVECTOR xAxis = XMVectorScale(XMLoadFloat3(&XMFLOAT3(1.0f, 0.0f, 0.0f)), size);
	XMVECTOR yAxis = XMVectorScale(XMLoadFloat3(&XMFLOAT3(0.0f, 0.0f, 1.0f)), size);
	XMFLOAT3 origin(0.0f, 0.0f, 0.0f);

	return InitializeMeshStreams(pMesh, xAxis, yAxis, origin, resolution, resolution, color);
}
Exemple #7
0
void Cloth::calcForces() {
  double currentTime = getCounter();

  for (int i = 0; i < numStructural; i++) {
    structuralSprings[i].calcSpringForce();
  }
  for (int i = 0; i < numShear; i++) {
    shearSprings[i].calcSpringForce();
  }
  for (int i = 0; i < numFlexion; i++) {
    flexionSprings[i].calcSpringForce();
  }

  timeSpentCalculatingInternalForce += getCounter() - currentTime;

  currentTime = getCounter();

  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < columns; j++) {
      particles[(i * columns) + j].addForce(XMVectorScale(GRAVITY, particles[(i * columns) + j].getMass()));

      if (currentScenario == FLAG) {
        if (i < rows - 1 && j < columns - 1) {
          addWindForce(particles[(i * columns) + j], particles[(i * columns) + j + 1], particles[((i + 1) * columns) + j]);
          addWindForce(particles[((i + 1) * columns) + j], particles[(i * columns) + j + 1], particles[((i + 1) * columns) + j + 1]);
        }
      }
    }
  }

  timeSpentCalculatingExternalForce += getCounter() - currentTime;
}
_Use_decl_annotations_
void BspCompiler::SplitEdge(const Vertex& v0, const Vertex& v1, const XMFLOAT4& plane, Vertex* v)
{
    XMFLOAT3 vv0 = v0.Position;
    XMFLOAT3 vv1 = v1.Position;

    float d0 = DistToPlane(plane, vv0);

    XMVECTOR sub = XMVectorSubtract(XMLoadFloat3(&vv1), XMLoadFloat3(&vv0));
    XMVECTOR dir = XMVector3Normalize(sub);
    XMVECTOR n = XMLoadFloat4(&plane);
    float d = d0;
    if (d > 0)
    {
        n = XMVectorNegate(n);
    }
    else if (d < 0)
    {
        d = -d;
    }
    else
    {
        assert(false);
    }

    float x = d / XMVectorGetX(XMVector3Dot(n, dir));
    XMStoreFloat3(&v->Position, XMVectorAdd(XMLoadFloat3(&vv0), XMVectorScale(dir, x)));
}
Exemple #9
0
_Use_decl_annotations_
void KdTreeCompiler2::SplitEdge(_In_ const StaticGeometryVertex& v0, _In_ const StaticGeometryVertex& v1, uint32_t axis, float value, _Out_ StaticGeometryVertex* v)
{
    XMFLOAT3 vv0 = v0.Position;
    XMFLOAT3 vv1 = v1.Position;

    float d0 = *(&vv0.x + axis) - value;

    XMVECTOR sub = XMVectorSubtract(XMLoadFloat3(&vv1), XMLoadFloat3(&vv0));
    XMVECTOR dir = XMVector3Normalize(sub);
    XMVECTOR n = XMLoadFloat3(&_normals[axis]);
    float d = d0;
    if (d > 0)
    {
        n = XMVectorNegate(n);
    }
    else if (d < 0)
    {
        d = -d;
    }
    else
    {
        assert(false);
    }

    float x = d / XMVectorGetX(XMVector3Dot(n, dir));
    XMStoreFloat3(&v->Position, XMVectorAdd(XMLoadFloat3(&vv0), XMVectorScale(dir, x)));
}
Exemple #10
0
		void ComputeAabbFromOrientedBox(SAxisAlignedBox* aabb, const SOrientedBox& obb)
		{
			XMFLOAT3 points[8];
			XMVECTOR bu = XMLoadFloat3(&obb.Axis[0]);
			XMVECTOR bv = XMLoadFloat3(&obb.Axis[1]);
			XMVECTOR bw = XMLoadFloat3(&obb.Axis[2]);

			bu = XMVectorScale(bu, obb.Extents.x);
			bv = XMVectorScale(bv, obb.Extents.y);
			bw = XMVectorScale(bw, obb.Extents.z);

			XMStoreFloat3(&points[0], bu + bv + bw);
			XMStoreFloat3(&points[1], bu + bv - bw);
			XMStoreFloat3(&points[2], bu - bv + bw);
			XMStoreFloat3(&points[3], bu - bv - bw);
			XMStoreFloat3(&points[4], -bu + bv + bw);
			XMStoreFloat3(&points[5], -bu + bv - bw);
			XMStoreFloat3(&points[6], -bu - bv + bw);
			XMStoreFloat3(&points[7], -bu - bv - bw);

			XMFLOAT3 maxPoint(-FLT_MAX, -FLT_MAX, -FLT_MAX);
			XMFLOAT3 minPoint(FLT_MAX, FLT_MAX, FLT_MAX);

			for (u32 i = 0; i < 8; i++)
			{
				XMFLOAT3 point = points[i];
				if (point.x > maxPoint.x)
					maxPoint.x = point.x;
				if (point.x < minPoint.x)
					minPoint.x = point.x;

				if (point.y > maxPoint.y)
					maxPoint.y = point.y;
				if (point.y < minPoint.y)
					minPoint.y = point.y;

				if (point.z > maxPoint.z)
					maxPoint.z = point.z;
				if (point.z < minPoint.z)
					minPoint.z = point.z;
			}

			aabb->Center = obb.Center;
			aabb->Extents = XMFLOAT3((maxPoint.x - minPoint.x) * 0.5f,
				(maxPoint.y - minPoint.y) * 0.5f,
				(maxPoint.z - minPoint.z) * 0.5f);
		}
Exemple #11
0
void BatchRenderer::DrawGrid( const Vec3D& XAxis, const Vec3D& YAxis, const Vec3D& Origin, int iXDivisions, int iYDivisions, const FColor& color )
{
//	HRESULT hr;

	iXDivisions = Max( 1, iXDivisions );
	iYDivisions = Max( 1, iYDivisions );

	// build grid geometry
//	INT iLineCount = iXDivisions + iYDivisions + 2;
	//assert( (2*iLineCount) <= MAX_VERTS );

	XMVECTOR vX = XMLoadFloat3( &as_float3(XAxis) );
	XMVECTOR vY = XMLoadFloat3( &as_float3(YAxis) );
	XMVECTOR vOrigin = XMLoadFloat3( &as_float3(Origin) );

	for( INT i = 0; i <= iXDivisions; i++ )
	{
		FLOAT fPercent = ( FLOAT )i / ( FLOAT )iXDivisions;
		fPercent = ( fPercent * 2.0f ) - 1.0f;
		XMVECTOR vScale = XMVectorScale( vX, fPercent );
		vScale = XMVectorAdd( vScale, vOrigin );

		XMVECTOR vA, vB;
		vA = XMVectorSubtract( vScale, vY );
		vB = XMVectorAdd( vScale, vY );

		DrawLine3D( as_vec4(vA).ToVec3(), as_vec4(vB).ToVec3(), color, color );
	}

//	INT iStartIndex = ( iXDivisions + 1 ) * 2;
	for( INT i = 0; i <= iYDivisions; i++ )
	{
		FLOAT fPercent = ( FLOAT )i / ( FLOAT )iYDivisions;
		fPercent = ( fPercent * 2.0f ) - 1.0f;
		XMVECTOR vScale = XMVectorScale( vY, fPercent );
		vScale = XMVectorAdd( vScale, vOrigin );
		
		XMVECTOR vA, vB;
		vA = XMVectorSubtract( vScale, vX );
		vB = XMVectorAdd( vScale, vX );

		DrawLine3D( as_vec4(vA).ToVec3(), as_vec4(vB).ToVec3(), color, color );
	}
}
Exemple #12
0
/**
 * Code available for download at http://cg.alexandra.dk/?p=147 used as reference for addWindForce
 */
void Cloth::addWindForce(Particle& p1, Particle& p2, Particle& p3) {
  XMVECTOR pos1, pos2, pos3, temp1, temp2, normal, force;

  pos1 = p1.getPosition();
  pos2 = p2.getPosition();
  pos3 = p3.getPosition();

  temp1 = XMVectorSubtract(pos2, pos1);
  temp2 = XMVectorSubtract(pos3, pos1);

  normal = XMVector3Cross(temp1, temp2);
  temp1 = XMVector3Normalize(normal);

  force = XMVectorScale(normal, XMVectorScale(XMVector3Dot(temp1, windDirection), windConstant).m128_f32[0]);

  p1.addForce(force);
  p2.addForce(force);
  p3.addForce(force);
}
Exemple #13
0
void BatchRenderer::DrawRay( const XMFLOAT3& Origin, const XMFLOAT3& Direction, BOOL bNormalize, const FColor& Color )
{
    XMFLOAT3 verts[3];
    memcpy( &verts[0], &Origin, 3 * sizeof( FLOAT ) );

    XMVECTOR RayOrigin = XMLoadFloat3( &Origin );
    XMVECTOR RayDirection = XMLoadFloat3( &Direction );
    XMVECTOR NormDirection = XMVector3Normalize( RayDirection );
    if( bNormalize )
        RayDirection = NormDirection;

    XMVECTOR PerpVector;
    XMVECTOR CrossVector = XMVectorSet( 0, 1, 0, 0 );
    PerpVector = XMVector3Cross( NormDirection, CrossVector );

    if( XMVector3Equal( XMVector3LengthSq( PerpVector ), XMVectorSet( 0, 0, 0, 0 ) ) )
    {
        CrossVector = XMVectorSet( 0, 0, 1, 0 );
        PerpVector = XMVector3Cross( NormDirection, CrossVector );
    }
    PerpVector = XMVector3Normalize( PerpVector );

    XMStoreFloat3( ( XMFLOAT3* )&verts[1], XMVectorAdd( RayDirection, RayOrigin ) );
    PerpVector = XMVectorScale( PerpVector, 0.0625f );
    NormDirection = XMVectorScale( NormDirection, -0.25f );
    RayDirection = XMVectorAdd( PerpVector, RayDirection );
    RayDirection = XMVectorAdd( NormDirection, RayDirection );
    XMStoreFloat3( ( XMFLOAT3* )&verts[2], XMVectorAdd( RayDirection, RayOrigin ) );
    
    // Copy to vertex buffer
    assert( 3 <= MAX_VERTS );
    XMFLOAT3* pVerts = NULL;
    HRESULT hr;
    V( g_pVB->Lock( 0, 0, (void**)&pVerts, D3DLOCK_DISCARD ) )
    memcpy( pVerts, verts, sizeof(verts) );
    V( g_pVB->Unlock() )

    // Draw ray
    D3DXCOLOR clr = Color;
    g_pEffect9->SetFloatArray( g_Color, clr, 4 );
    g_pEffect9->CommitChanges();
    pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 2 );
}
VOID DebugDraw::DrawGrid( const XMFLOAT3& XAxis, const XMFLOAT3& YAxis, const XMFLOAT3& Origin, INT iXDivisions,
                          INT iYDivisions, D3DCOLOR Color )
{
    iXDivisions = max( 1, iXDivisions );
    iYDivisions = max( 1, iYDivisions );

    // build grid geometry
    INT iLineCount = iXDivisions + iYDivisions + 2;
    XMFLOAT3* pLines = new XMFLOAT3[ 2 * iLineCount ];

    XMVECTOR vX = XMLoadFloat3( &XAxis );
    XMVECTOR vY = XMLoadFloat3( &YAxis );
    XMVECTOR vOrigin = XMLoadFloat3( &Origin );

    for( INT i = 0; i <= iXDivisions; i++ )
    {
        FLOAT fPercent = ( FLOAT )i / ( FLOAT )iXDivisions;
        fPercent = ( fPercent * 2.0f ) - 1.0f;
        XMVECTOR vScale = XMVectorScale( vX, fPercent );
        vScale = XMVectorAdd( vScale, vOrigin );
        XMStoreFloat3( &pLines[ ( i * 2 ) ], XMVectorSubtract( vScale, vY ) );
        XMStoreFloat3( &pLines[ ( i * 2 ) + 1 ], XMVectorAdd( vScale, vY ) );
    }

    INT iStartIndex = ( iXDivisions + 1 ) * 2;
    for( INT i = 0; i <= iYDivisions; i++ )
    {
        FLOAT fPercent = ( FLOAT )i / ( FLOAT )iYDivisions;
        fPercent = ( fPercent * 2.0f ) - 1.0f;
        XMVECTOR vScale = XMVectorScale( vY, fPercent );
        vScale = XMVectorAdd( vScale, vOrigin );
        XMStoreFloat3( &pLines[ ( i * 2 ) + iStartIndex ], XMVectorSubtract( vScale, vX ) );
        XMStoreFloat3( &pLines[ ( i * 2 ) + 1 + iStartIndex ], XMVectorAdd( vScale, vX ) );
    }

    // draw grid
    SimpleShaders::SetDeclPos();
    SimpleShaders::BeginShader_Transformed_ConstantColor( g_matViewProjection, Color );
    g_pd3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, iLineCount, pLines, sizeof( XMFLOAT3 ) );
    SimpleShaders::EndShader();

    delete[] pLines;
}
Exemple #15
0
void World::moveEntity( WorldEntity* entity, XMVECTOR moveVec, float dist )
{
    //Try to move the entity in the world along the moveVec
    XMVECTOR pos = XMLoadFloat4( &entity->getPosition() );
    XMVECTOR wall = XMVectorZero();
    XMVECTOR vel = XMVectorScale( moveVec, dist );
    XMVECTOR desiredPos;
    XMFLOAT4 check;
    XMFLOAT4 negativeCheck;

    int checks = 0;
    int maxChecks = 10;
    float saveDist = dist;
    float distInterval = dist / static_cast<float>(maxChecks);

    XMStoreFloat4( &check, XMVector3Length(moveVec) );

    //Don't bother doing anything if there is no movement direction
    if( check.x <= 0.0f ){
        return;
    }

    //Check collision at where we plan to be
    if( checkEntityCollision( entity, pos, &wall ) ){
        XMStoreFloat4( &check, wall );
        XMStoreFloat4( &negativeCheck, vel );

        //Check the negative bit of the x and z values and see if they are equal, if they are, then stop movement
        bool negativeXWall = *(int*)(&check.x) < 0;
        bool negativeZWall = *(int*)(&check.z) < 0;

        bool negativeXVel = *(int*)(&negativeCheck.x) < 0;
        bool negativeZVel = *(int*)(&negativeCheck.z) < 0;

        //If we are not in a corner, collide with the wall, otherwise stop movement
        if(check.w <= 1.5f ||
           ( negativeXWall != negativeXVel || 
             negativeZWall != negativeZVel ) ){
            XMVECTOR invWall = XMVectorNegate( wall );
            wall = wall * XMVector3Length( moveVec * invWall );
            vel = (moveVec - wall) * dist;
        }else{
            vel = XMVectorZero();
        }
    }

    desiredPos = pos + vel;
    
    XMStoreFloat4( &entity->getPosition(), desiredPos );
}
Exemple #16
0
	void CMesh::Setup(unsigned int vbovertices)
	{
		m_nVBOVertices = vbovertices;
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));
		std::vector<XMFLOAT3> data(polygons.size() * VERTICESPERPOLY);
		for (size_t i = 0, dst = 0; i < polygons.size(); ++i) {
			data[dst++] = vertices[polygons[i].v[0]];
			data[dst++] = vertices[polygons[i].v[1]];
			data[dst++] = vertices[polygons[i].v[2]];
		}

		glBufferDataARB(GL_ARRAY_BUFFER_ARB, data.size() * sizeof(XMFLOAT3), &data.front(), GL_STATIC_DRAW_ARB);
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));
		// Normals...
		glGenBuffersARB(1, &m_nVBONormals);
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));
		std::vector<XMFLOAT3> normals(polygons.size() * VERTICESPERPOLY);
		for (size_t i = 0, dst = 0; i < polygons.size(); ++i) {
			// TODO:: ccw hack
			XMFLOAT3 n;
			XMStoreFloat3(&n, XMVectorScale(XMLoadFloat3(&normalsV[i].n[0]), -1.f));
			normals[dst++] = n;
			XMStoreFloat3(&n, XMVectorScale(XMLoadFloat3(&normalsV[i].n[1]), -1.f));
			normals[dst++] = n;
			XMStoreFloat3(&n, XMVectorScale(XMLoadFloat3(&normalsV[i].n[2]), -1.f));
			normals[dst++] = n;
		}

		glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBONormals);
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));
		glBufferDataARB(GL_ARRAY_BUFFER_ARB, normals.size() * sizeof(XMFLOAT3), &normals.front(), GL_STATIC_DRAW_ARB);
		_ASSERT_EXPR_A(!(error = glGetError()), (const char*)gluErrorString(error));

	}
	void RayTraceDataGenerator::GenerateRaytraceResult(int width, int height,float scale, XMFLOAT4 loc, int neardistance, int maxdepth, XMFLOAT4 n, XMFLOAT4 up, void(*CallbackFunc)(int x, int y, const int& TexType, const XMFLOAT4& loc, const XMFLOAT4& n,const float& depth, void* arg), void* arg)
	{
		XMVECTOR v_ori = XMLoadFloat4(&loc);
		XMVECTOR v_center=XMLoadFloat4(&loc);
		XMVECTOR v_n = XMLoadFloat4(&n);
		XMVECTOR v_up = XMVector3Normalize(XMLoadFloat4(&up));
		v_center = XMVectorAdd(v_center, XMVectorScale(v_n, neardistance));
		XMVECTOR v_dir_x = XMVector3Cross(v_n, v_up);
		XMVECTOR v_dir_y = XMVector3Cross(v_n, v_dir_x);
		XMVECTOR v_current = XMVectorAdd(v_center, XMVectorScale(v_dir_x, -scale*width*0.5));
		XMVECTOR v_ret_n;
		XMVECTOR v_ret_loc;
		//XMFLOAT4 v_unpacked;
		XMFLOAT4 v_ret_unpack_n;
		XMFLOAT4 v_ret_unpack_loc;
		XMVECTOR v_corner1;
		XMVECTOR v_corner2;
		bool result;
		float f_ret_depth;
		v_current = XMVectorAdd(v_current, XMVectorScale(v_dir_y, -scale*height*0.5));
		v_corner1 = v_current;
		v_corner2 = XMVectorAdd(v_current, XMVectorScale(v_dir_y, +scale*height*1.0));
		v_corner2 = XMVectorAdd(v_corner2, XMVectorScale(v_dir_x, +scale*width*1.0));
		for (int i = 0; i < width; i++)
		{
			for (int j = 0; j < height; j++)
			{//XMVector3Normalize(XMVectorSubtract(v_current, v_ori))
				result = CalcIntersect(v_current, v_n, &v_ret_n, &v_ret_loc, &f_ret_depth);
				if (result)
				{
					XMStoreFloat4(&v_ret_unpack_loc,v_ret_loc);
					XMStoreFloat4(&v_ret_unpack_n, v_ret_n);
					CallbackFunc(i, j, GetLocInfo((int)v_ret_unpack_loc.x, (int)v_ret_unpack_loc.y, (int)v_ret_unpack_loc.z), v_ret_unpack_loc, v_ret_unpack_n, f_ret_depth, arg);
				}
				else
				{
					v_ret_unpack_n.x = v_ret_unpack_n.y = v_ret_unpack_n.z = -1;
					v_ret_unpack_loc.x = v_ret_unpack_loc.y = v_ret_unpack_loc.z = -1;
					f_ret_depth = -1;
					CallbackFunc(i, j, -1, v_ret_unpack_loc, v_ret_unpack_n, f_ret_depth, arg);
				}
				v_current = XMVectorAdd(v_current, XMVectorScale(v_dir_y, scale));
			}
			v_current = XMVectorAdd(v_current, XMVectorScale(v_dir_x, scale));
		}
	}
Exemple #18
0
void Ball::Reset() {

  FLOAT angle;
  //set random angle for initial impulse
  srand((unsigned int)time(NULL));
  angle = ((FLOAT)rand() / RAND_MAX ) * 360;
  if (angle > 45 && angle < 135) {
    angle -= 90;
  } else if (angle > 225 && angle < 315) {
    angle -= 90;
  }
  angle *= (XM_2PI / 360);
  
  //initialize position to screen center ( bounding box center)
  XMFLOAT2 center;
  center.x = (system->table.left + system->table.right)/2.0f;
  center.y = (system->table.top + system->table.bottom)/2.0f;
  center.x -= radius;
  center.y -= radius;
  impulse = XMVectorSet(cos(angle),sin(angle),0,0);
  impulse = XMVectorScale(impulse,37000);
  position = XMVectorSet(center.x,center.y,0,0);
  object_time = 0;
}
Exemple #19
0
    XMFLOAT2 Skeleton::CalculatePosition2D(std::vector<XMFLOAT2> &jointPositions2D, std::vector<float> &jointRotations2D, XMFLOAT2 &endEffectorPosition)
    {
        if (jointPositions2D.size() < 2) return XMFLOAT2(0.f, 0.f);

        // Walk through each link and apply the transform
        for (size_t i = 0; i < jointPositions2D.size() - 1; ++i)
        {
            float sumRotations = 0.f;
            for (size_t j = 0; j <= i; ++j)
            {
                sumRotations += jointRotations2D[j];
            }
            XMFLOAT2 direction;
            direction.x = cos(sumRotations);
            direction.y = sin(sumRotations);
            XMStoreFloat2(&jointPositions2D[i + 1], XMVectorAdd(XMLoadFloat2(&jointPositions2D[i]), XMVectorScale(XMLoadFloat2(&direction), m_IKLinkLength)));
        }

        float sumRotations = 0.f;
        for (size_t j = 0; j < jointRotations2D.size(); ++j)
        {
            sumRotations += jointRotations2D[j];
        }
        XMFLOAT2 direction;
        direction.x = cos(sumRotations);
        direction.y = sin(sumRotations);                

        XMStoreFloat2(&endEffectorPosition, XMVectorAdd(XMLoadFloat2(&jointPositions2D.back()), XMVectorScale(XMLoadFloat2(&direction), m_IKLinkLength)));

        return endEffectorPosition;
    }
	bool RayTraceDataGenerator::CalcIntersect(const XMVECTOR& p1, const XMVECTOR& n, XMVECTOR* nResult, XMVECTOR* intersectLocation, float* depth)
	{
		/*
		// grid space
		vec3 grid = floor( pos ); //向下取整将坐标在网格中使用
		vec3 grid_step = sign( dir ); //获取dir(方向)的正负符号<-意思就是说获取网格的步进方向,虽然只是正负
		vec3 corner = max( grid_step, vec3( 0.0 ) );//负号->0 //应该是最后在步进方向上产生的偏差值,但是原因不明

		// ray space
		vec3 inv = vec3( 1.0 ) / dir; //取倒数使得各个方向的比值倒过来
		vec3 ratio = ( grid + corner - pos ) * inv;//corn+pos的小数部分
		vec3 ratio_step = grid_step * inv;//不懂
		//于是这个rayspace只是提供一个比值,来决定grid的步进么

		// dda <-数值微分法
		float hit = -1.0;
		for ( int i = 0; i < 128; i++ ) {
		if ( voxel( grid ) > 0.5 ) {

		hit = 1.0;
		break;   //这里应该是可以直接退出循环的,感觉没什么区别
		continue;
		}

		vec3 cp = step( ratio, ratio.yzx );//二维情况的搞清楚了,问题还有就是在三维空间上的扩展

		mask = cp * ( vec3( 1.0 ) - cp.zxy );

		grid  += grid_step  * mask;
		ratio += ratio_step * mask;
		}

		center = grid + vec3( 0.5 );//中心形式表示(跟grid应该没区别吧0 0)
		return dot(ratio - ratio_step,vec3(1.0)) * hit;//dot( ratio - ratio_step, mask ) * hit;
		//这里关心的是hit的深度好像
		*/
		//p1是起点
		XMVECTOR start = p1;
		XMVECTOR dir = n;
		XMVECTOR zero = XMVectorSetBinaryConstant(0, 0, 0, 0);
		XMVECTOR one = XMVectorSetBinaryConstant(1, 1, 1, 1);


		XMVECTOR grid;
		XMVECTOR grid_step;
		XMVECTOR grid_corner;
		grid = XMVectorFloor(start);//实际上w分量为0应该就不影响了吧(
		//好像DirectXMath没有提供Sign的函数(于是用了一个挺别扭的方法- -
		//grid_step 就是 sign_dir
		grid_step = DirectX::XMVectorOrInt(DirectX::XMVectorAndInt(dir, DirectX::XMVectorSplatSignMask()), DirectX::XMVectorSplatOne());
		grid_corner = XMVectorClamp(grid_step, zero, one);

		XMVECTOR inv;
		XMVECTOR ratio;
		XMVECTOR ratio_step;
		inv = XMVectorReciprocal(dir);
		ratio = XMVectorMultiply(XMVectorSubtract(XMVectorAdd(grid, grid_corner), start), inv);
		ratio_step = XMVectorMultiply(grid_step, inv);

		bool hit = false;
		XMVECTOR cp;
		XMVECTOR mask;
		XMVECTOR ratioyzx;
		XMVECTOR cpzxy;
		XMFLOAT4 tmp1;
		XMFLOAT4 tmp2;
		int i;
		for (i = 0; i < 128; ++i)//最大深度为128
		{
			XMStoreFloat4(&tmp1, grid);
			/*
			__try{
			if (map->At(tmp1.x, tmp1.y, tmp1.z).TexType != -1)
			{
			hit = true;
			break;
			}
			}
			__except ((GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED)?EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH)
			{
			//捕获越界错误作为跳出条件,看看有没有问题...
			break;
			}
			*/
			//理论上来说异常的话处理代价太大,还是判断一下range吧= =
			if ((RangeCheck(tmp1.x, tmp1.y, tmp1.z)))
			{
				if (GetLocInfo(tmp1.x, tmp1.y, tmp1.z) != -1)
				{
					hit = true;
					break;
				}
			}
			/*
			修正:发生越界的时候并不一定就要终止,需要考虑到从值域外射出的射线.....
			不过就算不break效率应该也比原先的算法要高...(除了要限制一下最大遍历深度这方面
			*/


			XMStoreFloat4(&tmp1, ratio);
			tmp2.x = tmp1.y; tmp2.y = tmp1.z; tmp2.z = tmp1.x;
			ratioyzx = XMLoadFloat4(&tmp2);

			cp = XMVectorAndInt(XMVectorGreaterOrEqual(ratioyzx, ratio), XMVectorSplatOne());//1 or 0
			XMStoreFloat4(&tmp1, cp);
			tmp2.x = tmp1.z; tmp2.y = tmp1.x; tmp2.z = tmp1.y;
			cpzxy = XMLoadFloat4(&tmp2);
			mask = XMVectorMultiply(cp, XMVectorSubtract(one, cpzxy));

			grid += XMVectorMultiply(grid_step, mask);
			ratio += XMVectorMultiply(ratio_step, mask);
		}
		if (hit)
		{

			XMFLOAT4 result;
			result = tmp1; //所在方块
			if (i == 0)
			{
				//这是在方块内部的情况
				result.w = -1;
				return false;
			}
			XMVECTOR ftmp;
			ftmp = XMVectorSubtract(ratio, ratio_step);//因为取的只是mask方向的值,所以step在这里没必要乘mask
			*depth = XMVectorGetX(DirectX::XMVector3Dot(ftmp, mask));
			ftmp = XMVectorAdd(XMVectorScale(dir,*depth) , p1);
			XMStoreFloat4(&tmp1, ftmp);
			//需要全部反过来,因为上面的式子没有取反
			*intersectLocation = ftmp;
			result = tmp1;
			result.w = 0;

			XMVECTOR normal;
			normal = XMVectorMultiply(mask, grid_step);
			XMStoreFloat4(&tmp1, normal);
			//需要全部反过来,因为上面的式子没有取反
			if (tmp1.x > 0.5)
			{
				//法向量为1,0,0,后方
				*nResult = XMVectorSetBinaryConstant(1, 0, 0, 0);
			}
			else if (tmp1.x < -0.5)
			{
				//法向量为-1,0,0,前方
				*nResult = XMVectorSetBinaryConstant(-1, 0, 0, 0);
			}
			else if (tmp1.y < -0.5)
			{
				//法向量为0,-1,0,右方
				*nResult = XMVectorSetBinaryConstant(0, -1, 0, 0);
			}
			else if (tmp1.y > 0.5)
			{
				//法向量为0,1,0,左方
				*nResult = XMVectorSetBinaryConstant(0, 1, 0, 0);
			}
			else if (tmp1.z < -0.5)
			{
				//法向量为0,0,-1,上方
				*nResult = XMVectorSetBinaryConstant(0, 0, -1, 0);
			}
			else if (tmp1.z > 0.5)
			{
				//法向量为0,0,1,下方
				*nResult = XMVectorSetBinaryConstant(0, 0, 1, 0);
			}
			return true;
			//return result;
		}
		else
		{
			return false;
		}
		//上面成功的进行了判断,可以得出grid编号了,不过还要算一下相交面(
		return false;
	}
Exemple #21
0
bool WorldEntity::circleAALineIntersect( XMVECTOR start, XMVECTOR end, XMVECTOR circleCenter, float circleRadius )
{
    //A collision function we actually understand...
 
    //Create a vector from the start to the circle position
    XMVECTOR cToStart = circleCenter - start;
    XMVECTOR cToEnd = circleCenter - end;

    XMVECTOR lenToStart = XMVector4Length( cToStart );
    XMVECTOR lenToEnd = XMVector4Length( cToEnd );

    XMFLOAT4 ans;
    XMStoreFloat4( &ans, lenToStart );

    if( ans.x <= circleRadius ){
        return true;
    }

    XMStoreFloat4( &ans, lenToEnd );

    if( ans.x <= circleRadius ){
        return true;
    }

    //Calculate the start to end
    XMVECTOR endToStart = end - start;

    XMVECTOR endToStartLen = XMVector4Length( endToStart );
        
    XMFLOAT4 tmp;
    XMStoreFloat4(&tmp, endToStartLen);
    tmp.x = 1.0f / tmp.x;

    XMVECTOR tmpA = XMVectorScale(endToStart, tmp.x);
    XMVECTOR tmpB = XMVectorScale(cToStart, tmp.x);

    //Project it onto the start -> end vector
    XMVECTOR dot = XMVector4Dot( tmpA, tmpB );

    //Calculate the Perpendicular point
    XMVECTOR per = start + ( endToStart * dot );

    //If the perpendicular point is within range of the circle, there is a collision
    XMVECTOR perDist = XMVector4Length( circleCenter - per );

    XMStoreFloat4( &ans, perDist );

    if( ans.x > circleRadius ){
        return false;
    }
    
    //Store the dot product to see how far down the line the collision happens
    XMStoreFloat4( &ans, dot );

    //If the dot product is negative, the collision is outside the range
    if( ans.x < 0.0f ){
        return false;
    }

    //If the dot product is bigger than 1.0f, meaning it scaled the vector passed the segment, the collision is outside the range
    if( ans.x > 1.0f ){
        return false;
    }

    return true;
}
HRESULT SceneObjectGrid::InitializeMeshStreams(__in ISceneObjectMesh* pMesh, const XMVECTOR xAxis, const XMVECTOR yAxis, const XMFLOAT3& origin, UINT xResolution,
											   UINT yResolution, XMFLOAT4 color)
{
	if (xResolution == 0 || yResolution == 0 || pMesh == NULL)
	{
		return E_INVALIDARG;
	}

	HRESULT hr = S_OK;

    xResolution = max(1, xResolution);
    yResolution = max(1, yResolution);

    // Build grid geometry
    INT iLineCount = xResolution + yResolution + 2;
	VertexType* pLines = new VertexType[2 * iLineCount];

	if (!pLines)
	{
		hr = E_OUTOFMEMORY;
	}
	else
	{
		XMVECTOR vOrigin = XMLoadFloat3(&origin);

		for (UINT i = 0; i <= xResolution; i++)
		{
			FLOAT fPercent = (FLOAT)i / (FLOAT)xResolution;
			fPercent = (fPercent * 2.0f) - 1.0f;
			
            XMVECTOR vScale = XMVectorScale(xAxis, fPercent);
			vScale = XMVectorAdd( vScale, vOrigin );

			XMStoreFloat3(&pLines[(i * 2)].position, XMVectorSubtract(vScale, yAxis));
            pLines[(i * 2)].color = color;

			XMStoreFloat3(&pLines[(i * 2) + 1].position, XMVectorAdd(vScale, yAxis));
            pLines[(i * 2) + 1].color = color;
		}

		UINT iStartIndex = (xResolution + 1) * 2;
		for (UINT i = 0; i <= yResolution; i++)
		{
			FLOAT fPercent = (FLOAT)i / (FLOAT)yResolution;
			fPercent = (fPercent * 2.0f) - 1.0f;
			
            XMVECTOR vScale = XMVectorScale(yAxis, fPercent);
			vScale = XMVectorAdd(vScale, vOrigin);
			
            XMStoreFloat3(&pLines[(i * 2) + iStartIndex].position, XMVectorSubtract(vScale, xAxis));
            pLines[(i * 2) + iStartIndex].color = color;

			XMStoreFloat3(&pLines[(i * 2) + 1 + iStartIndex].position, XMVectorAdd(vScale, xAxis));
            pLines[(i * 2) + 1 + iStartIndex].color = color;
		}

		SmartPtr<IVertexStream> spVertexStream;
		hr = CreateVertexStream(2 * iLineCount, pLines, &spVertexStream);
		if (SUCCEEDED(hr))
		{
			hr = pMesh->SetMeshStream(MeshStreamType::MST_VERTEX_POSITIONS, spVertexStream.CastTo<IMeshStream>());		
		}

		pMesh->SetPrimitiveTopologyType(PrimitiveTopologyType::PTT_LINELIST);
	}

    delete[] pLines;

	return hr;
}
Exemple #23
0
    MeshData(const string& name)
    {
      static Assimp::Importer importer;
      D3DInfo& d3d = *D3DInfo::CurrentInstance();

      // Read the mesh data from file using Asset Importer.
      const aiScene* scene = importer.ReadFile(config::Meshes + name, ImportSetting);
      if (!scene || !scene->mNumMeshes)
      {
        Warn("Mesh read failed for " + name);
        return;
      }

      const aiMesh* mesh = scene->mMeshes[0];
      WarnIf(scene->mNumMeshes > 1, "Mesh " + name + " has more sub-meshes than are currently supported");
      
      // Verify mesh texture coordinates and tangents.
      bool hasTexCoords = true;
      if (!mesh->HasTextureCoords(0))
      {
        hasTexCoords = false;
        Warn("Mesh " + name + " doesn't have texture coordinates");
      }
      bool hasTangents = true;
      if (!mesh->HasTangentsAndBitangents())
      {
        hasTangents = false;
        Warn("Mesh " + name + " doesn't have tangents/bitangents");
      }

      float minFloat = numeric_limits<float>::min();
      float maxFloat = numeric_limits<float>::max();
      boundingBox.max = { minFloat, minFloat, minFloat };
      boundingBox.min = { maxFloat, maxFloat, maxFloat };

      // Copy all vertices.
      vertices.resize(mesh->mNumVertices);
      for (size_t i = 0; i < mesh->mNumVertices; ++i)
      {
        vertices[i].position  = reinterpret_cast<const float3&>(mesh->mVertices[i]);
        vertices[i].normal = reinterpret_cast<const float3&>(mesh->mNormals[i]);
        if (hasTexCoords)
        {
          vertices[i].tex = reinterpret_cast<const float2&>(mesh->mTextureCoords[0][i]);
        }
        if (hasTangents)
        {
          vertices[i].tangent = reinterpret_cast<const float3&>(mesh->mTangents[i]);
          vertices[i].bitangent = reinterpret_cast<const float3&>(mesh->mBitangents[i]);
        }

        // Determine the min and max extents of the mesh.
        if (vertices[i].position.x < boundingBox.min.x) boundingBox.min.x = vertices[i].position.x;
        if (vertices[i].position.y < boundingBox.min.y) boundingBox.min.y = vertices[i].position.y;
        if (vertices[i].position.z < boundingBox.min.z) boundingBox.min.z = vertices[i].position.z;
        if (vertices[i].position.x > boundingBox.max.x) boundingBox.max.x = vertices[i].position.x;
        if (vertices[i].position.y > boundingBox.max.y) boundingBox.max.y = vertices[i].position.y;
        if (vertices[i].position.z > boundingBox.max.z) boundingBox.max.z = vertices[i].position.z;
      }

      // Calculate the centroid of the mesh: centroid = min + ((max - min) / 2)
      XMVECTOR minVector = XMLoadFloat3(&boundingBox.min);
      XMVECTOR cornerToCorner = XMVectorSubtract(XMLoadFloat3(&boundingBox.max), minVector);
      XMStoreFloat3(
        &boundingBox.centroid, 
        XMVectorAdd(
          minVector, 
          XMVectorScale(cornerToCorner, 0.5f)));

      // Center the mesh on (0,0,0) by subtracting the centroid position from all vertex positions.
      for (auto& vertex : vertices)
      {
        vertex.position.x -= boundingBox.centroid.x;
        vertex.position.y -= boundingBox.centroid.y;
        vertex.position.z -= boundingBox.centroid.z;
      }

      // Copy all indices.
      indices.resize(mesh->mNumFaces * 3);
      for (size_t i = 0; i < mesh->mNumFaces; ++i)
      {
        indices[i * 3 + 0] = mesh->mFaces[i].mIndices[0];
        indices[i * 3 + 1] = mesh->mFaces[i].mIndices[1];
        indices[i * 3 + 2] = mesh->mFaces[i].mIndices[2];
      }

      // Free the loaded scene.
      importer.FreeScene();

      // Create the index buffer.
      D3D11_BUFFER_DESC bufferDesc;
      bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
      bufferDesc.ByteWidth = indices.size() * sizeof(indices[0]);
      bufferDesc.CPUAccessFlags = 0;
      bufferDesc.MiscFlags = 0;
      bufferDesc.StructureByteStride = 0;
      bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
      D3D11_SUBRESOURCE_DATA initData;
      initData.pSysMem = indices.data();
      initData.SysMemPitch = 0;
      initData.SysMemSlicePitch = 0;
      DX(d3d.Device->CreateBuffer(&bufferDesc, &initData, indexBuffer));

      // Create the vertex buffer.
      bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
      bufferDesc.ByteWidth = vertices.size() * sizeof(vertices[0]);
      initData.pSysMem = vertices.data();
      DX(d3d.Device->CreateBuffer(&bufferDesc, &initData, vertexBuffer));

      // Create the constant buffer.
      D3D11_BUFFER_DESC cbDesc;
      ZeroMemory(&cbDesc, sizeof(cbDesc));
      cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
      cbDesc.ByteWidth = sizeof(ObjectConstants);
      cbDesc.Usage = D3D11_USAGE_DEFAULT;
      DX(d3d.Device->CreateBuffer(&cbDesc, nullptr, constantBuffer));
    }
// Renders meshes using cascaded shadow mapping
void MeshRenderer::RenderSunShadowMap(ID3D11DeviceContext* context, const Camera& camera)
{
    PIXEvent event(L"Sun Shadow Map Rendering");

    const float MinDistance = reductionDepth.x;
    const float MaxDistance = reductionDepth.y;

    // Compute the split distances based on the partitioning mode
    float CascadeSplits[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

    {
        float lambda = 1.0f;

        float nearClip = camera.NearClip();
        float farClip = camera.FarClip();
        float clipRange = farClip - nearClip;

        float minZ = nearClip + MinDistance * clipRange;
        float maxZ = nearClip + MaxDistance * clipRange;

        float range = maxZ - minZ;
        float ratio = maxZ / minZ;

        for(uint32 i = 0; i < NumCascades; ++i)
        {
            float p = (i + 1) / static_cast<float>(NumCascades);
            float log = minZ * std::pow(ratio, p);
            float uniform = minZ + range * p;
            float d = lambda * (log - uniform) + uniform;
            CascadeSplits[i] = (d - nearClip) / clipRange;
        }
    }

    Float3 c0Extents;
    Float4x4 c0Matrix;

    const Float3 lightDir = AppSettings::SunDirection;

    // Render the meshes to each cascade
    for(uint32 cascadeIdx = 0; cascadeIdx < NumCascades; ++cascadeIdx)
    {
        PIXEvent cascadeEvent((L"Rendering Shadow Map Cascade " + ToString(cascadeIdx)).c_str());

        // Set the viewport
        SetViewport(context, ShadowMapSize, ShadowMapSize);

        // Set the shadow map as the depth target
        ID3D11DepthStencilView* dsv = sunShadowDepthMap.DSView;
        ID3D11RenderTargetView* nullRenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { NULL };
        context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRenderTargets, dsv);
        context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

        // Get the 8 points of the view frustum in world space
        XMVECTOR frustumCornersWS[8] =
        {
            XMVectorSet(-1.0f,  1.0f, 0.0f, 1.0f),
            XMVectorSet( 1.0f,  1.0f, 0.0f, 1.0f),
            XMVectorSet( 1.0f, -1.0f, 0.0f, 1.0f),
            XMVectorSet(-1.0f, -1.0f, 0.0f, 1.0f),
            XMVectorSet(-1.0f,  1.0f, 1.0f, 1.0f),
            XMVectorSet( 1.0f,  1.0f, 1.0f, 1.0f),
            XMVectorSet( 1.0f, -1.0f, 1.0f, 1.0f),
            XMVectorSet(-1.0f, -1.0f, 1.0f, 1.0f),
        };

        float prevSplitDist = cascadeIdx == 0 ? MinDistance : CascadeSplits[cascadeIdx - 1];
        float splitDist = CascadeSplits[cascadeIdx];

        XMVECTOR det;
        XMMATRIX invViewProj = XMMatrixInverse(&det, camera.ViewProjectionMatrix().ToSIMD());
        for(uint32 i = 0; i < 8; ++i)
            frustumCornersWS[i] = XMVector3TransformCoord(frustumCornersWS[i], invViewProj);

        // Get the corners of the current cascade slice of the view frustum
        for(uint32 i = 0; i < 4; ++i)
        {
            XMVECTOR cornerRay = XMVectorSubtract(frustumCornersWS[i + 4], frustumCornersWS[i]);
            XMVECTOR nearCornerRay = XMVectorScale(cornerRay, prevSplitDist);
            XMVECTOR farCornerRay = XMVectorScale(cornerRay, splitDist);
            frustumCornersWS[i + 4] = XMVectorAdd(frustumCornersWS[i], farCornerRay);
            frustumCornersWS[i] = XMVectorAdd(frustumCornersWS[i], nearCornerRay);
        }

        // Calculate the centroid of the view frustum slice
        XMVECTOR frustumCenterVec = XMVectorZero();
        for(uint32 i = 0; i < 8; ++i)
            frustumCenterVec = XMVectorAdd(frustumCenterVec, frustumCornersWS[i]);
        frustumCenterVec = XMVectorScale(frustumCenterVec, 1.0f / 8.0f);
        Float3 frustumCenter = frustumCenterVec;

        // Pick the up vector to use for the light camera
        Float3 upDir = camera.Right();

        Float3 minExtents;
        Float3 maxExtents;

        {
            // Create a temporary view matrix for the light
            Float3 lightCameraPos = frustumCenter;
            Float3 lookAt = frustumCenter - lightDir;
            XMMATRIX lightView = XMMatrixLookAtLH(lightCameraPos.ToSIMD(), lookAt.ToSIMD(), upDir.ToSIMD());

            // Calculate an AABB around the frustum corners
            XMVECTOR mins = XMVectorSet(REAL_MAX, REAL_MAX, REAL_MAX, REAL_MAX);
            XMVECTOR maxes = XMVectorSet(-REAL_MAX, -REAL_MAX, -REAL_MAX, -REAL_MAX);
            for(uint32 i = 0; i < 8; ++i)
            {
                XMVECTOR corner = XMVector3TransformCoord(frustumCornersWS[i], lightView);
                mins = XMVectorMin(mins, corner);
                maxes = XMVectorMax(maxes, corner);
            }

            minExtents = mins;
            maxExtents = maxes;
        }

        // Adjust the min/max to accommodate the filtering size
        float scale = (ShadowMapSize + FilterSize) / static_cast<float>(ShadowMapSize);
        minExtents.x *= scale;
        minExtents.y *= scale;
        maxExtents.x *= scale;
        maxExtents.x *= scale;

        Float3 cascadeExtents = maxExtents - minExtents;

        // Get position of the shadow camera
        Float3 shadowCameraPos = frustumCenter + lightDir * -minExtents.z;

        // Come up with a new orthographic camera for the shadow caster
        OrthographicCamera shadowCamera(minExtents.x, minExtents.y, maxExtents.x,
            maxExtents.y, 0.0f, cascadeExtents.z);
        shadowCamera.SetLookAt(shadowCameraPos, frustumCenter, upDir);

        // Draw the mesh with depth only, using the new shadow camera
        RenderDepth(context, shadowCamera, true, false);

        // Apply the scale/offset matrix, which transforms from [-1,1]
        // post-projection space to [0,1] UV space
        XMMATRIX texScaleBias;
        texScaleBias.r[0] = XMVectorSet(0.5f,  0.0f, 0.0f, 0.0f);
        texScaleBias.r[1] = XMVectorSet(0.0f, -0.5f, 0.0f, 0.0f);
        texScaleBias.r[2] = XMVectorSet(0.0f,  0.0f, 1.0f, 0.0f);
        texScaleBias.r[3] = XMVectorSet(0.5f,  0.5f, 0.0f, 1.0f);
        XMMATRIX shadowMatrix = shadowCamera.ViewProjectionMatrix().ToSIMD();
        shadowMatrix = XMMatrixMultiply(shadowMatrix, texScaleBias);

        // Store the split distance in terms of view space depth
        const float clipDist = camera.FarClip() - camera.NearClip();
        shadowConstants.Data.CascadeSplits[cascadeIdx] = camera.NearClip() + splitDist * clipDist;

        if(cascadeIdx == 0)
        {
            c0Extents = cascadeExtents;
            c0Matrix = shadowMatrix;
            shadowConstants.Data.ShadowMatrix = XMMatrixTranspose(shadowMatrix);
            shadowConstants.Data.CascadeOffsets[0] = Float4(0.0f, 0.0f, 0.0f, 0.0f);
            shadowConstants.Data.CascadeScales[0] = Float4(1.0f, 1.0f, 1.0f, 1.0f);
        }
        else
        {
            // Calculate the position of the lower corner of the cascade partition, in the UV space
            // of the first cascade partition
            Float4x4 invCascadeMat = Float4x4::Invert(shadowMatrix);
            Float3 cascadeCorner = Float3::Transform(Float3(0.0f, 0.0f, 0.0f), invCascadeMat);
            cascadeCorner = Float3::Transform(cascadeCorner, c0Matrix);

            // Do the same for the upper corner
            Float3 otherCorner = Float3::Transform(Float3(1.0f, 1.0f, 1.0f), invCascadeMat);
            otherCorner = Float3::Transform(otherCorner, c0Matrix);

            // Calculate the scale and offset
            Float3 cascadeScale = Float3(1.0f, 1.0f, 1.f) / (otherCorner - cascadeCorner);
            shadowConstants.Data.CascadeOffsets[cascadeIdx] = Float4(-cascadeCorner, 0.0f);
            shadowConstants.Data.CascadeScales[cascadeIdx] = Float4(cascadeScale, 1.0f);
        }

        ConvertToEVSM(context, cascadeIdx, shadowConstants.Data.CascadeScales[cascadeIdx].To3D());
    }
}
Exemple #25
0
EnemyWithStates* EnemyBuilder::AddNewEnemy(const XMFLOAT3 &position, const EnemyTypes typeOfEnemy)
{
	EnemyWithStates* newEnemyWithStates = new EnemyWithStates();
	switch (typeOfEnemy)
	{
	case EnemyTypes::ENEMY_TYPE_NORMAL:
		{
			Entity newEntity;
			newEntity = _builder->EntityC().Create();

			_builder->Light()->BindPointLight(newEntity, XMFLOAT3(0.0f, 0.0f, 0.0f), STARTRANGELIGHT*3.0f, ENEMY_TYPE_NORMAL_COLOR, STARTINTENSITYLIGHT);
			_builder->Light()->SetAsVolumetric(newEntity, true);
			_builder->Light()->ChangeLightBlobRange(newEntity, STARTBLOBRANGELIGHT);
			_builder->Transform()->CreateTransform(newEntity);
			_builder->Bounding()->CreateBoundingSphere(newEntity, STARTBLOBRANGELIGHT*0.5f);
			_builder->Transform()->SetPosition(newEntity, XMVectorSet(position.x, position.y, position.z, 1.0f));
			newEnemyWithStates->_thisEnemy = new Enemy(newEntity, _builder);
			newEnemyWithStates->_thisEnemyStateController = new AIStateController();
			newEnemyWithStates->_thisEnemyStateController->AddState(new AIPatrolState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));
			newEnemyWithStates->_thisEnemyStateController->AddState(new AIAttackState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));
			newEnemyWithStates->_thisEnemyStateController->AddState(new AITransitionState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));

			
			//Add 10 bricks around the light
			XMVECTOR enemyPos = XMVectorSet(position.x, position.y, position.z, 1.0f);
			const int nrOfBricks = 5;
		

			std::vector<string> pro;
			pro.push_back("DiffuseMap");
			pro.push_back("NormalMap");
			pro.push_back("Roughness");

			std::vector<wstring> texs;
			texs.push_back(L"Assets/Textures/Enemy_Brick_Dif_01.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_NM.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_Roughness.png");
			for (int i = 0; i < nrOfBricks; ++i)
			{
				
				XMVECTOR offset = XMVectorSet(static_cast<float>((rand() % 100) - 50), static_cast<float>((rand() % 100) - 50), static_cast<float>((rand() % 100) - 50), 0.0f);
				offset = XMVector3Normalize(offset);
				offset = XMVectorScale(offset, 0.33f);
				
				Entity brick = _builder->EntityC().Create();

				unsigned int br = rand() % 2 + 1;

				_builder->Mesh()->CreateStaticMesh(brick, ("Assets/Models/Enemy_Brick_0" + to_string(br) + ".arf").c_str());
				_builder->Material()->BindMaterial(brick, "Shaders/GBuffer.hlsl");
				_builder->Material()->SetEntityTexture(brick, pro, texs);
				_builder->Bounding()->CreateBoundingSphere(brick, _builder->Mesh()->GetMesh(brick));
				_builder->Transform()->CreateTransform(brick);
				
				_builder->Transform()->SetDirection(brick, -offset);
				if (br == 2)
					_builder->Transform()->RotateRoll(brick, 90.0f);

				_builder->Transform()->SetScale(brick, XMVectorSet(0.1f, 0.1f, 0.1f, 0.0f));
				
				Entity brickRot = _builder->EntityC().Create();
				_builder->Transform()->CreateTransform(brickRot);
				_builder->Transform()->BindChild(newEntity, brickRot);
				_builder->Transform()->BindChild(brickRot, brick);
				unsigned int rot = rand() % 3;

				_builder->Animation()->CreateAnimation(brickRot, "rotate", 90.0f, 
					[this, brickRot, rot](float delta, float amount, float offset) 
				{
					switch (rot)
					{
					case 0:
						_builder->Transform()->RotatePitch(brickRot, delta);
						break;
					case 1:
						_builder->Transform()->RotateYaw(brickRot, delta);
						break;
					case 2:
						_builder->Transform()->RotateRoll(brickRot, delta);
						break;
					default:
						break;
					}
				},
					[this, brickRot]()
				{
					_builder->Animation()->PlayAnimation(brickRot, "rotate", 360.0f*20.0f);
				});
				_builder->Animation()->PlayAnimation(brickRot, "rotate", 360.0f*20.0f);


				_builder->Transform()->SetPosition(brick, offset);
				newEnemyWithStates->_thisEnemy->AddChild(brick);
				newEnemyWithStates->_thisEnemy->AddChild(brickRot);
			}


			break;

		}

		case EnemyTypes::ENEMY_TYPE_TELEPORTER:
		{

			Entity newEntity;
			newEntity = _builder->EntityC().Create();


			Entity emesh = _builder->EntityC().Create();

			_builder->Mesh()->CreateStaticMesh(emesh, "Assets/Models/BallHorizontal.arf");
			_builder->Material()->BindMaterial(emesh, "Shaders/GBuffer.hlsl");

			std::vector<string> pro;
			pro.push_back("DiffuseMap");
			pro.push_back("NormalMap");
			pro.push_back("Roughness");

			std::vector<wstring> texs;
			texs.push_back(L"Assets/Textures/Ball.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_NM.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_Roughness.png");

			_builder->Material()->SetEntityTexture(emesh, pro, texs);

			_builder->Transform()->CreateTransform(emesh);
			_builder->Transform()->CreateTransform(newEntity);
			_builder->Transform()->BindChild(newEntity, emesh);


			_builder->Light()->BindPointLight(newEntity, XMFLOAT3(0.0f, 0.0f, 0.0f), STARTRANGELIGHT*3.0f, ENEMY_TYPE_TELEPORTER_COLOR, STARTINTENSITYLIGHT);
			_builder->Light()->SetAsVolumetric(newEntity, true);
			_builder->Light()->ChangeLightBlobRange(newEntity, STARTBLOBRANGELIGHT);

			_builder->Bounding()->CreateBoundingSphere(newEntity, _builder->Mesh()->GetMesh(emesh));
			_builder->Bounding()->CreateBoundingSphere(emesh, _builder->Mesh()->GetMesh(emesh));

			_builder->Transform()->SetPosition(newEntity, XMVectorSet(position.x, position.y, position.z, 1.0f));
			newEnemyWithStates->_thisEnemy = new Enemy(newEntity, _builder);
			newEnemyWithStates->_thisEnemyStateController = new AIStateController();
			newEnemyWithStates->_thisEnemyStateController->AddState(new AITeleportMoveState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));

			newEnemyWithStates->_thisEnemy->SetScaleFactor(0.0075f);
			_builder->Transform()->SetScale(newEntity, XMFLOAT3(0.005f, 0.005f, 0.005f));


			_builder->Animation()->CreateAnimation(emesh, "rotate", 90.0f,
				[this, emesh](float delta, float amount, float offset)
			{
				_builder->Transform()->RotateYaw(emesh, delta);
			},
				[this, emesh]()
			{
				_builder->Animation()->PlayAnimation(emesh, "rotate", 360.0f*20.0f);
			});
			_builder->Animation()->PlayAnimation(emesh, "rotate", 360.0f*20.0f);
			
			newEnemyWithStates->_thisEnemy->AddChild(emesh);

			break;
		}

		case EnemyTypes::ENEMY_TYPE_MINI_GUN:
		{
			Entity newEntity;
			newEntity = _builder->EntityC().Create();
		
			
			_builder->Mesh()->CreateStaticMesh(newEntity, "Assets/Models/BallFlipped.arf");
			_builder->Material()->BindMaterial(newEntity, "Shaders/GBuffer.hlsl");

			std::vector<string> pro;
			pro.push_back("DiffuseMap");
			pro.push_back("NormalMap");
			pro.push_back("Roughness");

			std::vector<wstring> texs;
			texs.push_back(L"Assets/Textures/Ball.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_NM.png");
			texs.push_back(L"Assets/Textures/Enemy_Brick_Roughness.png");

			_builder->Material()->SetEntityTexture(newEntity, pro, texs);

		
			_builder->Light()->BindPointLight(newEntity, XMFLOAT3(0.0f, 0.0f, 0.0f), STARTRANGELIGHT*3.0f, ENEMY_TYPE_MINI_GUN_COLOR, STARTINTENSITYLIGHT);
			_builder->Light()->SetAsVolumetric(newEntity, true);
			_builder->Light()->ChangeLightBlobRange(newEntity, STARTBLOBRANGELIGHT);
			_builder->Transform()->CreateTransform(newEntity);

			_builder->Bounding()->CreateBoundingSphere(newEntity, _builder->Mesh()->GetMesh(newEntity));
			_builder->Transform()->SetPosition(newEntity, XMVectorSet(position.x, position.y, position.z, 1.0f));
			_builder->Transform()->SetScale(newEntity, XMFLOAT3(0.005f, 0.005f, 0.005f));


			newEnemyWithStates->_thisEnemy = new Enemy(newEntity, _builder);
			newEnemyWithStates->_thisEnemy->SetScaleFactor(0.01f);

			newEnemyWithStates->_thisEnemyStateController = new AIStateController();
			newEnemyWithStates->_thisEnemyStateController->AddState(new AIMiniGunLightState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));
			break;
		}

		case EnemyTypes::ENEMY_TYPE_SHADOW:
		{
			Entity newEntity;
			newEntity = _builder->EntityC().Create();

			_builder->Light()->BindPointLight(newEntity, XMFLOAT3(0.0f, 0.0f, 0.0f), STARTRANGELIGHT*3.0f, ENEMY_TYPE_SHADOW_COLOR, STARTINTENSITYLIGHT);
			_builder->Light()->SetAsVolumetric(newEntity, true);
			_builder->Light()->ChangeLightBlobRange(newEntity, STARTBLOBRANGELIGHT);
			_builder->Transform()->CreateTransform(newEntity);
			_builder->Bounding()->CreateBoundingSphere(newEntity, STARTBLOBRANGELIGHT *0.3f);
			_builder->Transform()->SetPosition(newEntity, XMVectorSet(position.x, position.y, position.z, 1.0f));
			newEnemyWithStates->_thisEnemy = new Enemy(newEntity, _builder);

			newEnemyWithStates->_thisEnemyStateController = new AIStateController();
			newEnemyWithStates->_thisEnemyStateController->AddState(new AIPatrolState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));
			newEnemyWithStates->_thisEnemyStateController->AddState(new AIWalkIntoTheLightAttackState(AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder));

			break;
		}

		case EnemyTypes::ENEMY_TYPE_PROXIMITY_SITH:
		{
			Entity e = _builder->EntityC().Create();

			_builder->Light()->BindPointLight( e, XMFLOAT3( 0.0f, 0.0f, 0.0f ), STARTRANGELIGHT * 3.0f, ENEMY_TYPE_PROXIMITY_SITH_COLOR, STARTINTENSITYLIGHT );
			_builder->Light()->SetAsVolumetric( e, true );
			_builder->Light()->ChangeLightBlobRange( e, STARTBLOBRANGELIGHT );
			_builder->Transform()->CreateTransform( e );
			_builder->Bounding()->CreateBoundingSphere( e, STARTBLOBRANGELIGHT*0.3f );
			_builder->Transform()->SetPosition( e, XMVectorSet( position.x, position.y, position.z, 1.0f ) );
			_builder->ProximityLightning()->Add( e );
			newEnemyWithStates->_thisEnemy = new Enemy( e, _builder );
			newEnemyWithStates->_thisEnemyStateController = new AIStateController();
			newEnemyWithStates->_thisEnemyStateController->AddState( new AIPatrolState( AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder ) );
			newEnemyWithStates->_thisEnemyStateController->AddState( new AIAttackState( AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder ) );
			newEnemyWithStates->_thisEnemyStateController->AddState( new AITransitionState( AI_STATE_NONE, _controller, newEnemyWithStates->_thisEnemy, _builder ) );
		}
	}
	_builder->Transform()->RotateRoll(newEnemyWithStates->_thisEnemy->GetEntity(), 0.0f);
	return newEnemyWithStates;
}
Exemple #26
0
bool DX11::ModelShader::SetParameters(ID3D11DeviceContext * direct3Dcontext, Gpu::Model * model, Gpu::Camera * camera, Gpu::Light ** lights, unsigned numLights, float aspect, Gpu::Effect * effect)
{
	if(!model || !camera) return false;
	if(camera->position == camera->target)
	{
		OutputDebugString(L"Cannot construct view matrix!");
		return false;
	}

	// MATRIX OPS - SIGNIFICANT COST - ~9us //

	glm::mat4 modelMatrix = model->GetMatrix();
	XMMATRIX world((float*)&modelMatrix);

	XMStoreFloat4x4(&vertexConstData.world, world);

	glm::mat4 camMatrix = camera->GetProjMatrix(aspect) * camera->GetViewMatrix();
	XMMATRIX viewProj((float*)&camMatrix);

	XMStoreFloat4x4(&vertexConstData.viewProjection, viewProj);

	XMMATRIX wit = XMMatrixInverse(0, XMMatrixTranspose(world));
	XMStoreFloat4x4(&vertexConstData.worldInverseTranspose, wit);

	vertexConstData.materialColor = XMFLOAT4(model->color.r, model->color.g, model->color.b, model->color.a);

	ID3D11ShaderResourceView * nullResource = 0;

	if(model->texture)
	{
		DX11::Texture* texture = static_cast<DX11::Texture*>(model->texture);
		direct3Dcontext->PSSetShaderResources(0, 1, &texture->shaderView);
	}
	else
	{
		direct3Dcontext->PSSetShaderResources(0, 1, &nullResource);
	}
	
	// BEGIN LIGHTING - VARIABLE COST //

	if(model->cubeMap)
	{
		DX11::CubeMap * cubeMap = static_cast<DX11::CubeMap*>(model->cubeMap);
		direct3Dcontext->PSSetShaderResources(1, 1, &cubeMap->shaderView);
		pixelConstData.cubeMapAlpha = 1.0f;
	}
	else
	{
		direct3Dcontext->PSSetShaderResources(1, 1, &nullResource);
		pixelConstData.cubeMapAlpha = 0.0f;
	}
	if(model->normalMap)
	{
		DX11::Texture * normalMap = static_cast<DX11::Texture*>(model->normalMap);
		direct3Dcontext->PSSetShaderResources(2, 1, &normalMap->shaderView);
	}
	else
	{
		direct3Dcontext->PSSetShaderResources(2, 1, &nullResource);
	}

	pixelConstData.numLights = numLights;
	if(numLights > 0)
	{
		pixelConstData.ambient = 0.0f;
		pixelConstData.cameraPosition = XMFLOAT3(camera->position.x, camera->position.y, camera->position.z);
		pixelConstData.specularPower = model->specPower;
		pixelConstData.specularFactor = model->specFactor;
		pixelConstData.diffuseFactor = model->diffuseFactor;

		for(unsigned i = 0; i < numLights && i < MAX_LIGHTS; ++i)
		{
			// Hmm, really the specular highlight should be calculated
			// from the light's size, position and intensity.
			// Do a little more investigation into Physically Based Lighting

			lightConstData.positionSpecs[i].specPower = 12.0f;

			Gpu::LightType lightType = lights[i]->GetType();
			if(lightType == Gpu::LightType_Directional)
			{
				Gpu::DirectionalLight * dirLight = static_cast<Gpu::DirectionalLight*>(lights[i]);
				XMVECTOR lightDirVec = XMLoadFloat3(&XMFLOAT3(dirLight->direction.x, dirLight->direction.y, dirLight->direction.z));
				XMStoreFloat3(&(lightConstData.positionSpecs[i].position), XMVectorScale(lightDirVec, 10.0e+10f));
				lightConstData.colorAttenuations[i].color = XMFLOAT3(dirLight->color.r, dirLight->color.g, dirLight->color.b);
				lightConstData.colorAttenuations[i].attenuation = 0.0f;
				lightConstData.spotDirPowers[i].direction = XMFLOAT3(0.0f, 0.0f, 0.0f);
				lightConstData.spotDirPowers[i].spotPower = 0.0f;
			}
			if(lightType == Gpu::LightType_Point)
			{
				Gpu::PointLight * pointLight = static_cast<Gpu::PointLight*>(lights[i]);
				lightConstData.positionSpecs[i].position = XMFLOAT3(pointLight->position.x, pointLight->position.y, pointLight->position.z);
				lightConstData.colorAttenuations[i].color = XMFLOAT3(pointLight->color.r, pointLight->color.g, pointLight->color.b);
				lightConstData.colorAttenuations[i].attenuation = pointLight->atten;
				lightConstData.spotDirPowers[i].direction = XMFLOAT3(0.0f, 0.0f, 0.0f);
				lightConstData.spotDirPowers[i].spotPower = 0.0f;
			}
			if(lightType == Gpu::LightType_Spot)
			{
				Gpu::SpotLight * spotLight = static_cast<Gpu::SpotLight*>(lights[i]);
				lightConstData.positionSpecs[i].position = XMFLOAT3(spotLight->position.x, spotLight->position.y, spotLight->position.z);
				lightConstData.colorAttenuations[i].color = XMFLOAT3(spotLight->color.r, spotLight->color.g, spotLight->color.b);
				lightConstData.colorAttenuations[i].attenuation = spotLight->atten;
				XMStoreFloat3(&lightConstData.spotDirPowers[i].direction, XMVector3Normalize(XMLoadFloat3(
					&XMFLOAT3(spotLight->direction.x, spotLight->direction.y, spotLight->direction.z))));
				lightConstData.spotDirPowers[i].spotPower = spotLight->power;

				if(i == 0)
				{
					float lightFOV = XM_PI * 0.15f;

					glm::mat4 lightGlmMatrix = spotLight->GetMatrix(lightFOV, glm::vec3(0.0f, 1.0f, 0.0f));
					XMMATRIX lightXMMatrix((float*)&lightGlmMatrix);

					//XMMATRIX lightView = XMMatrixLookToLH(
					//	XMLoadFloat3(&lightConstData.positionSpecs[i].position),
					//	XMLoadFloat3(&lightConstData.spotDirPowers[i].direction),
					//	XMLoadFloat3(&XMFLOAT3(0.0f, 1.0f, 0.0f)));

					//XMMATRIX lightLens = XMMatrixPerspectiveFovLH(lightFOV, 1.0f, 1.0f, 200.0f);

					XMStoreFloat4x4(&vertexConstData.lightViewProjection, lightXMMatrix);
				}
			}
		}

		static unsigned setCount = 0;

		setCount++;

		direct3Dcontext->UpdateSubresource(lightParamsBuffer, 0, 0, &lightConstData, sizeof(LightConstants), sizeof(LightConstants));

		setCount++;

		direct3Dcontext->PSSetConstantBuffers(1, 1, &lightParamsBuffer);
	}
	else
	{
		pixelConstData.lightPosition = XMFLOAT3(0.0f, 0.0f, 0.0f);
		pixelConstData.lightColor = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
		pixelConstData.cameraPosition = XMFLOAT3(camera->position.x, camera->position.y, camera->position.z);
		pixelConstData.spotPower = 0.0f;
		pixelConstData.specularPower = FLT_MAX;
		pixelConstData.spotDirection = XMFLOAT3(0.0f, 0.0f, 0.0f);
		pixelConstData.ambient = 1.0f;
	}

	// END LIGHTING //

	// UPDATING CONSTANT BUFFERS - SIGNIFICANT COST - 17us //

	direct3Dcontext->UpdateSubresource(pixelConstBuffer, 0, 0, &pixelConstData, sizeof(PixelConstants), sizeof(PixelConstants));
	direct3Dcontext->PSSetConstantBuffers(0, 1, &pixelConstBuffer);

	direct3Dcontext->UpdateSubresource(vertexConstBuffer, 0, 0, &vertexConstData, sizeof(VertexConstants), sizeof(VertexConstants));
	direct3Dcontext->VSSetConstantBuffers(0, 1, &vertexConstBuffer);

	// SETTING EXTRA PARAMS - VARIABLE COST //

	if(effect)
	{
		return currentTechnique->SetExtraParameters(direct3Dcontext, effect);
	}
	else
	{
		return true;
	}
}
Exemple #27
0
void Inky::Update(float dt, bool powerUpActivated, Direction::DIRECTION facingState, XMFLOAT3 blinkyPos, int levelNumber, int pelletCounter)
{
	if (!isDead)
	{
		if (pelletCounter >= 30 && isIdle)
		{
			this->isIdle = false;
			mGhostStates = GHOST_STATES::SCATTER;
		}
		if (!isIdle)
		{
			switch (mGhostStates)
			{
			case SCATTER:
				SetSpeed(levelNumber, GHOST_STATES::SCATTER);
				if (!scatterPathDrawn)
				{
					PrePathFinding(this->mPos.x, this->mPos.z, this->mScatterWaypoints[0]->xPos, this->mScatterWaypoints[0]->zPos);
					if (PostPathFinding())
					{
						this->UpdateCurrentTweenPoint(dt);
						scatterPathDrawn = true;
					}
				}
				if (mTweenPoints.size() != 0)
				{
					if (!this->reachedEnd)
					{
						this->mPos = this->mCurrTweenPoint;
						this->UpdateCurrentTweenPoint(dt);
					}
					else if (this->reachedEnd)
					{
						if (!isLooping)
						{
							this->SetWayPoints(mScatterWaypoints);
							this->isLooping = true;
						}
						if (isLooping == true && this->reachedEnd)
						{
							this->UpdateCurrentTweenPoint(dt);
							this->mPos = this->mCurrTweenPoint;
						}
					}
				}

				if (!powerUpActivated)
				{
					this->mGhostStates = GHOST_STATES::SCATTER;
					mScatterTimer += 5.7142f * dt; //dt currently takes (without mutliplying) 40 seconds to reach 7.0f, 5.7142 comes from 40 / 7 to get the number as accurate as possible.
					if (mScatterTimer >= 7.0f)
					{
						this->mGhostStates = GHOST_STATES::CHASE;
						mScatterTimer = 0.0f;
						reachedEnd = false;
						isLooping = false;
						CleanUpNodesWaypoints();
						mTweenPoints.clear();
					}
				}
				//If the powerup is activated, switch to the FRIGHTENED state
				else if (powerUpActivated)
				{
					SetSpeed(levelNumber, GHOST_STATES::FRIGHTENED);
					CleanUpNodesWaypoints();
					mTweenPoints.clear();
					scatterPathDrawn = false;
					reachedEnd = false;
					isLooping = false;
					mPrevState = mGhostStates;
					this->mGhostStates = GHOST_STATES::FRIGHTENED;
				}
				break;

			case CHASE:
				SetSpeed(levelNumber, GHOST_STATES::CHASE);
				if (!firstChasePathDrawn)
				{
					PrePathFinding(this->mPos.x, this->mPos.z, this->mScatterWaypoints[0]->xPos, this->mScatterWaypoints[0]->zPos);
					if (PostPathFinding())
					{
						this->UpdateCurrentTweenPoint(dt);
						firstChasePathDrawn = true;
					}
				}
				else
				{
					mPathCurrent += dt;
					if (mPathCurrent >= mPathNext)
					{
						if (facingState == Direction::DIRECTION::NORTH || facingState == Direction::DIRECTION::SOUTH)
						{
							//Offset tile = 2 spaces in PuckMan's facing
							offsetTile.xPos = round(MazeLoader::GetPacManData().at(0).pos.x);
							offsetTile.zPos = round(MazeLoader::GetPacManData().at(0).pos.z + (2 * Direction::getDirecitonVector(facingState).m128_f32[2]));
							//Draw a vector from Blinky's current position to the offset tile's position
							XMVECTOR targetTile = XMVectorSet(offsetTile.xPos - blinkyPos.x, 0.0f, offsetTile.zPos - blinkyPos.z, 0.0f);
							//Double the vector length extending forward, this is Inky's target
							targetTile = XMVectorScale(targetTile, 2.0f);

							//Clamp the X and Z value of the targetTile so it cannot choose a tile outside of the level
							float clampedX = MathHelper::Clamp((int)targetTile.m128_f32[0], 0, (int)(MazeLoader::GetMazeWidth()));
							float clampedZ = MathHelper::Clamp((int)targetTile.m128_f32[2], 0, (int)(MazeLoader::GetMazeHeight()));

							//Check if clampedZ is a valid tile, if not move the target tile one more in the opposite direction and try again
							int goalRow = (MazeLoader::GetMazeHeight()) - round(clampedZ + 15.5f);
							int goalCol = round(clampedX + 14.5f) - 1;
							while (MazeLoader::IsBlocked(goalRow, goalCol))
							{
								clampedX -= 1 * Direction::getDirecitonVector(facingState).m128_f32[0];
								clampedZ -= 1 * Direction::getDirecitonVector(facingState).m128_f32[2];
								if (MazeLoader::IsBlocked(clampedZ, clampedX))
								{
									break;
								}
							}

							PrePathFinding(this->mPos.x, this->mPos.z, round(MazeLoader::GetPacManData().at(0).pos.x), round(MazeLoader::GetPacManData().at(0).pos.z));
							if (PostPathFinding())
							{
								this->UpdateCurrentTweenPoint(dt);
								mPathNext += (1.0f / 10.0f);
							}
						}

						else if (facingState == Direction::DIRECTION::WEST || facingState == Direction::DIRECTION::EAST)
						{
							//Offset tile = 2 spaces in PuckMan's facing
							offsetTile.xPos = round(MazeLoader::GetPacManData().at(0).pos.x);
							offsetTile.zPos = round(MazeLoader::GetPacManData().at(0).pos.z + (2 * Direction::getDirecitonVector(facingState).m128_f32[2]));
							//Draw a vector from Blinky's current position to the offset tile's position
							XMVECTOR targetTile = XMVectorSet(offsetTile.xPos - blinkyPos.x, 0.0f, offsetTile.zPos - blinkyPos.z, 0.0f);
							//Double the vector length extending forward, this is Inky's target
							targetTile = XMVectorScale(targetTile, 2.0f);

							//Clamp the X and Z value of the targetTile so it cannot choose a tile outside of the level
							//Subract one from the highest value to zero base it
							float clampedX = MathHelper::Clamp((int)targetTile.m128_f32[0], 0, (int)(MazeLoader::GetMazeWidth()));
							float clampedZ = MathHelper::Clamp((int)targetTile.m128_f32[2], 0, (int)(MazeLoader::GetMazeHeight()));

							//Check if clampedZ is a valid tile, if not move the target tile one more in the opposite direction and try again
							//Because clampedZ and clampedX are already tile based, we can pass it into the function without conversion
							while (MazeLoader::IsBlocked(clampedZ, clampedX))
							{
								clampedX -= 1 * Direction::getDirecitonVector(facingState).m128_f32[0];
								clampedZ -= 1 * Direction::getDirecitonVector(facingState).m128_f32[2];
								if (MazeLoader::IsBlocked(clampedZ, clampedX))
								{
									break;
								}
							}

							PrePathFinding(this->mPos.x, this->mPos.z, round(MazeLoader::GetPacManData().at(0).pos.x), round(MazeLoader::GetPacManData().at(0).pos.z));
							if (PostPathFinding())
							{
								this->UpdateCurrentTweenPoint(dt);
								mPathNext += (1.0f / 10.0f);
							}
						}
					}
				}
				if (mTweenPoints.size() != 0)
				{
					this->mPos = this->mCurrTweenPoint;
					this->UpdateCurrentTweenPoint(dt);
				}

				if (!powerUpActivated)
				{
					mGhostStates = GHOST_STATES::CHASE;
					mChaseTimer += 5.7142f * dt; //dt currently takes (without mutliplying) 40 seconds to reach 7.0f, 5.7142 comes from 40 / 7 to get the number as accurate as possible.
					if (mChaseTimer >= 7.0f) //Chase time is over, time to scatter
					{
						this->mGhostStates = GHOST_STATES::SCATTER;
						mChaseTimer = 0.0f;
						scatterPathDrawn = false;
						reachedEnd = false;
						isLooping = false;
						CleanUpNodesWaypoints();
						mTweenPoints.clear();
					}
				}
				//If the powerup is activated, switch to the FRIGHTENED state
				else if (powerUpActivated)
				{
					SetSpeed(levelNumber, GHOST_STATES::FRIGHTENED);
					CleanUpNodesWaypoints();
					mTweenPoints.clear();
					mPrevState = mGhostStates;
					this->mGhostStates = GHOST_STATES::FRIGHTENED;
					scatterPathDrawn = false;
					firstChasePathDrawn = false;
				}
				break;

				case FRIGHTENED:
					SetSpeed(levelNumber, GHOST_STATES::FRIGHTENED);
					if (!scatterPathDrawn)
					{
						PrePathFinding(this->mPos.x, this->mPos.z, this->mScatterWaypoints[0]->xPos, this->mScatterWaypoints[0]->zPos);
						if (PostPathFinding())
						{
							this->UpdateCurrentTweenPoint(dt);
							scatterPathDrawn = true;
						}
					}
					if (mTweenPoints.size() != 0)
					{
						if (!this->reachedEnd)
						{
							this->mPos = this->mCurrTweenPoint;
							this->UpdateCurrentTweenPoint(dt);

						}
						else if (this->reachedEnd)
						{
							if (!isLooping)
							{
								this->SetWayPoints(mScatterWaypoints);
								this->isLooping = true;
							}
							if (isLooping == true && this->reachedEnd)
							{
								this->UpdateCurrentTweenPoint(dt);
								this->mPos = this->mCurrTweenPoint;
							}
						}
					}
					if (!powerUpActivated)
					{
						mGhostStates = mPrevState;
						mTweenPoints.clear();
					}
					break;
			}
		}
	}
}
Exemple #28
0
    VOID FilterDoubleExponential::Update( const NUI_SKELETON_DATA* pSkeletonData, UINT i, NUI_TRANSFORM_SMOOTH_PARAMETERS smoothingParams )
    {
        XMVECTOR vPrevRawPosition;
        XMVECTOR vPrevFilteredPosition;
        XMVECTOR vPrevTrend;
        XMVECTOR vRawPosition;
        XMVECTOR vFilteredPosition;
        XMVECTOR vPredictedPosition;
        XMVECTOR vDiff;
        XMVECTOR vTrend;
        XMVECTOR vLength;
        FLOAT fDiff;
        BOOL bJointIsValid;

        const XMVECTOR* __restrict pJointPositions = pSkeletonData->SkeletonPositions;

        vRawPosition            = pJointPositions[i];
        vPrevFilteredPosition   = m_History[i].m_vFilteredPosition;
        vPrevTrend              = m_History[i].m_vTrend;
        vPrevRawPosition        = m_History[i].m_vRawPosition;
        bJointIsValid           = JointPositionIsValid(vRawPosition);

        // If joint is invalid, reset the filter
        if (!bJointIsValid)
        {
            m_History[i].m_dwFrameCount = 0;
        }

        // Initial start values
        if (m_History[i].m_dwFrameCount == 0)
        {
            vFilteredPosition = vRawPosition;
            vTrend = XMVectorZero();
            m_History[i].m_dwFrameCount++;
        }
        else if (m_History[i].m_dwFrameCount == 1)
        {
            vFilteredPosition = XMVectorScale(XMVectorAdd(vRawPosition, vPrevRawPosition), 0.5f);
            vDiff = XMVectorSubtract(vFilteredPosition, vPrevFilteredPosition);
            vTrend = XMVectorAdd(XMVectorScale(vDiff, smoothingParams.fCorrection), XMVectorScale(vPrevTrend, 1.0f - smoothingParams.fCorrection));
            m_History[i].m_dwFrameCount++;
        }
        else
        {              
            // First apply jitter filter
            vDiff = XMVectorSubtract(vRawPosition, vPrevFilteredPosition);
            vLength = XMVector3Length(vDiff);
            fDiff = fabs(XMVectorGetX(vLength));

            if (fDiff <= smoothingParams.fJitterRadius)
            {
                vFilteredPosition = XMVectorAdd(XMVectorScale(vRawPosition, fDiff/smoothingParams.fJitterRadius),
                                                XMVectorScale(vPrevFilteredPosition, 1.0f - fDiff/smoothingParams.fJitterRadius));
            }
            else
            {
                vFilteredPosition = vRawPosition;
            }

            // Now the double exponential smoothing filter
            vFilteredPosition = XMVectorAdd(XMVectorScale(vFilteredPosition, 1.0f - smoothingParams.fSmoothing),
                                            XMVectorScale(XMVectorAdd(vPrevFilteredPosition, vPrevTrend), smoothingParams.fSmoothing));


            vDiff = XMVectorSubtract(vFilteredPosition, vPrevFilteredPosition);
            vTrend = XMVectorAdd(XMVectorScale(vDiff, smoothingParams.fCorrection), XMVectorScale(vPrevTrend, 1.0f - smoothingParams.fCorrection));
        }      

        // Predict into the future to reduce latency
        vPredictedPosition = XMVectorAdd(vFilteredPosition, XMVectorScale(vTrend, smoothingParams.fPrediction));

        // Check that we are not too far away from raw data
        vDiff = XMVectorSubtract(vPredictedPosition, vRawPosition);
        vLength = XMVector3Length(vDiff);
        fDiff = fabs(XMVectorGetX(vLength));

        if (fDiff > smoothingParams.fMaxDeviationRadius)
        {
            vPredictedPosition = XMVectorAdd(XMVectorScale(vPredictedPosition, smoothingParams.fMaxDeviationRadius/fDiff),
                                             XMVectorScale(vRawPosition, 1.0f - smoothingParams.fMaxDeviationRadius/fDiff));
        }

        // Save the data from this frame
        m_History[i].m_vRawPosition      = vRawPosition;
        m_History[i].m_vFilteredPosition = vFilteredPosition;
        m_History[i].m_vTrend            = vTrend;
        
        // Output the data
        m_FilteredJoints[i] = vPredictedPosition;
        m_FilteredJoints[i].w = 1.0f;
    }
Exemple #29
0
    //--------------------------------------------------------------------------------------
    // The Taylor Series smooths and removes jitter based on a taylor series expansion
    //--------------------------------------------------------------------------------------
    VOID FilterTaylorSeries::Update( const XMVECTOR* pJointPositions )
    {
        const FLOAT fJitterRadius = 0.05f;
        const FLOAT fAlphaCoef  = 1.0f - m_fSmoothing;
        const FLOAT fBetaCoeff  = (fAlphaCoef * fAlphaCoef ) / ( 2 - fAlphaCoef );

        XMVECTOR vRawPos;
        XMVECTOR vCurFilteredPos, vCurEstVel, vCurEstVel2, vCurEstVel3;
        XMVECTOR vPrevFilteredPos, vPrevEstVel, vPrevEstVel2, vPrevEstVel3;
        XMVECTOR vDiff;
        FLOAT fDiff;

        XMVECTOR vPredicted, vError;
        XMVECTOR vConstants = { 0.0f, 1.0f, 0.5f, 0.1667f };

        for (INT i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)
        {
            vRawPos             = pJointPositions[i];
            vPrevFilteredPos    = m_History[i].vPos;
            vPrevEstVel         = m_History[i].vEstVel;
            vPrevEstVel2        = m_History[i].vEstVel2;
            vPrevEstVel3        = m_History[i].vEstVel3;

            if (!JointPositionIsValid(vPrevFilteredPos))
            {
                vCurFilteredPos = vRawPos;
                vCurEstVel      = XMVectorZero();
                vCurEstVel2     = XMVectorZero();
                vCurEstVel3     = XMVectorZero();
            }
            else if (!JointPositionIsValid(vRawPos))
            {
                vCurFilteredPos = vPrevFilteredPos;
                vCurEstVel      = vPrevEstVel;
                vCurEstVel2     = vPrevEstVel2;
                vCurEstVel3     = vPrevEstVel3;
            }
            else
            {
                // If the current and previous frames have valid data, perform interpolation

                vDiff = XMVectorSubtract(vPrevFilteredPos, vRawPos);
                fDiff = fabs(XMVector3Length(vDiff).x);

                if (fDiff <= fJitterRadius)
                {
                    vCurFilteredPos = XMVectorAdd(XMVectorScale(vRawPos, fDiff/fJitterRadius),
                                                  XMVectorScale(vPrevFilteredPos, 1.0f - fDiff/fJitterRadius));
                }
                else
                {
                    vCurFilteredPos = vRawPos;
                }

                vPredicted  = XMVectorAdd(vPrevFilteredPos, vPrevEstVel);
                vPredicted  = XMVectorAdd(vPredicted, vPrevEstVel2 * (vConstants.y * vConstants.y * vConstants.z));
                vPredicted  = XMVectorAdd(vPredicted, vPrevEstVel3 * (vConstants.y * vConstants.y * vConstants.y * vConstants.w));
                vError      = XMVectorSubtract(vCurFilteredPos, vPredicted);

                vCurFilteredPos = XMVectorAdd(vPredicted, vError * fAlphaCoef);
                vCurEstVel      = XMVectorAdd(vPrevEstVel, vError * fBetaCoeff);
                vCurEstVel2     = XMVectorSubtract(vCurEstVel, vPrevEstVel);
                vCurEstVel3     = XMVectorSubtract(vCurEstVel2, vPrevEstVel2);
            }

            // Update the state
            m_History[i].vPos       = vCurFilteredPos;
            m_History[i].vEstVel    = vCurEstVel;
            m_History[i].vEstVel2   = vCurEstVel2;
            m_History[i].vEstVel3   = vCurEstVel3;
          
            // Output the data
            m_FilteredJoints[i]     = vCurFilteredPos;
            m_FilteredJoints[i].w   = 1.0f;
        }
    }
VOID DebugDraw::DrawConeWireframe( const XMFLOAT3& CenterBase, const XMFLOAT3& Axis, FLOAT fBaseRadius,
                                   FLOAT fTopRadius, D3DCOLOR Color )
{
    XMVECTOR vAxis = XMLoadFloat3( &Axis );
    XMVECTOR vAxisNorm = XMVector3Normalize( vAxis );

    // compute orthogonal vectors for the base of the cone
    XMVECTOR vBaseVectorX = XMVector3Normalize( XMVector3Orthogonal( vAxisNorm ) );
    XMVECTOR vBaseVectorZ = XMVector3Cross( vAxisNorm, vBaseVectorX );
    XMVECTOR vBaseVectorXScale = XMVectorScale( vBaseVectorX, fBaseRadius );
    XMVECTOR vBaseVectorZScale = XMVectorScale( vBaseVectorZ, fBaseRadius );

    // draw base ring
    if( fBaseRadius != 0 )
    {
        XMFLOAT3 BaseRingAxisX, BaseRingAxisZ;
        XMStoreFloat3( &BaseRingAxisX, vBaseVectorXScale );
        XMStoreFloat3( &BaseRingAxisZ, vBaseVectorZScale );
        DrawRing( CenterBase, BaseRingAxisX, BaseRingAxisZ, Color );
    }

    // compute center top location
    XMVECTOR vCenterTop = XMLoadFloat3( &CenterBase );
    vCenterTop = XMVectorAdd( vCenterTop, vAxis );

    // compute orthogonal vectors for the top of the cone
    XMVECTOR vTopVectorXScale = XMVectorScale( vBaseVectorX, fTopRadius );
    XMVECTOR vTopVectorZScale = XMVectorScale( vBaseVectorZ, fTopRadius );

    // build top ring
    if( fTopRadius != 0 )
    {
        XMFLOAT3 CenterTop;
        XMStoreFloat3( &CenterTop, vCenterTop );
        XMFLOAT3 TopRingAxisX, TopRingAxisZ;
        XMStoreFloat3( &TopRingAxisX, vTopVectorXScale );
        XMStoreFloat3( &TopRingAxisZ, vTopVectorZScale );
        DrawRing( CenterTop, TopRingAxisX, TopRingAxisZ, Color );
    }

    // build walls
    XMVECTOR vCenterBase = XMLoadFloat3( &CenterBase );
    const DWORD dwDivisions = 8;
    XMFLOAT3 WallVerts[ dwDivisions * 2 ];
    for( DWORD i = 0; i < dwDivisions; ++i )
    {
        FLOAT fTheta = ( ( FLOAT )i * XM_2PI ) / ( FLOAT )dwDivisions;
        XMVECTOR vSin, vCos;
        XMVectorSinCos( &vSin, &vCos, XMVectorReplicate( fTheta ) );
        XMVECTOR vBottom = vCenterBase + vBaseVectorXScale * vSin + vBaseVectorZScale * vCos;
        XMVECTOR vTop = vCenterTop + vTopVectorXScale * vSin + vTopVectorZScale * vCos;
        XMStoreFloat3( &WallVerts[ i * 2 ], vBottom );
        XMStoreFloat3( &WallVerts[ i * 2 + 1 ], vTop );
    }

    // draw walls
    SimpleShaders::SetDeclPos();
    SimpleShaders::BeginShader_Transformed_ConstantColor( g_matViewProjection, Color );
    g_pd3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, dwDivisions, WallVerts, sizeof( XMFLOAT3 ) );
    SimpleShaders::EndShader();
}