Esempio n. 1
0
void Game::CreateSphere(int latLines, int longLines)
{
	NumSphereVertices = ((latLines - 2) * longLines) + 2;
	NumSphereFaces = ((latLines - 3)*(longLines)* 2) + (longLines * 2);

	float sphereYaw = 0.0f;
	float spherePitch = 0.0f;

	std::vector<Vertex> vertices(NumSphereVertices);

	XMVECTOR currVertPos = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);

	vertices[0].pos.x = 0.0f;
	vertices[0].pos.y = 0.0f;
	vertices[0].pos.z = 1.0f;

	for (DWORD i = 0; i < latLines - 2; ++i)
	{
		spherePitch = (i + 1) * (3.14 / (latLines - 1));

		skyRotationX = XMMatrixRotationX(spherePitch);
		for (DWORD j = 0; j < longLines; ++j)
		{
			sphereYaw = j * (6.28 / (longLines));
			skyRotationY = XMMatrixRotationZ(sphereYaw);
			currVertPos = XMVector3TransformNormal(XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f), (skyRotationX * skyRotationY));
			currVertPos = XMVector3Normalize(currVertPos);
			vertices[i*longLines + j + 1].pos.x = XMVectorGetX(currVertPos);
			vertices[i*longLines + j + 1].pos.y = XMVectorGetY(currVertPos);
			vertices[i*longLines + j + 1].pos.z = XMVectorGetZ(currVertPos);
		}
	}

	vertices[NumSphereVertices - 1].pos.x = 0.0f;
	vertices[NumSphereVertices - 1].pos.y = 0.0f;
	vertices[NumSphereVertices - 1].pos.z = -1.0f;


	D3D11_BUFFER_DESC vertexBufferDesc;
	ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));

	vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	vertexBufferDesc.ByteWidth = sizeof(Vertex)* NumSphereVertices;
	vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexBufferDesc.CPUAccessFlags = 0;
	vertexBufferDesc.MiscFlags = 0;

	D3D11_SUBRESOURCE_DATA vertexBufferData;

	ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
	vertexBufferData.pSysMem = &vertices[0];
	hr = device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &sphereVertBuffer);


	std::vector<DWORD> indices(NumSphereFaces * 3);

	int k = 0;
	for (DWORD l = 0; l < longLines - 1; ++l)
	{
		indices[k] = 0;
		indices[k + 1] = l + 1;
		indices[k + 2] = l + 2;
		k += 3;
	}

	indices[k] = 0;
	indices[k + 1] = longLines;
	indices[k + 2] = 1;
	k += 3;

	for (DWORD i = 0; i < latLines - 3; ++i)
	{
		for (DWORD j = 0; j < longLines - 1; ++j)
		{
			indices[k] = i*longLines + j + 1;
			indices[k + 1] = i*longLines + j + 2;
			indices[k + 2] = (i + 1)*longLines + j + 1;

			indices[k + 3] = (i + 1)*longLines + j + 1;
			indices[k + 4] = i*longLines + j + 2;
			indices[k + 5] = (i + 1)*longLines + j + 2;

			k += 6; // next quad
		}

		indices[k] = (i*longLines) + longLines;
		indices[k + 1] = (i*longLines) + 1;
		indices[k + 2] = ((i + 1)*longLines) + longLines;

		indices[k + 3] = ((i + 1)*longLines) + longLines;
		indices[k + 4] = (i*longLines) + 1;
		indices[k + 5] = ((i + 1)*longLines) + 1;

		k += 6;
	}

	for (DWORD l = 0; l < longLines - 1; ++l)
	{
		indices[k] = NumSphereVertices - 1;
		indices[k + 1] = (NumSphereVertices - 1) - (l + 1);
		indices[k + 2] = (NumSphereVertices - 1) - (l + 2);
		k += 3;
	}

	indices[k] = NumSphereVertices - 1;
	indices[k + 1] = (NumSphereVertices - 1) - longLines;
	indices[k + 2] = NumSphereVertices - 2;

	D3D11_BUFFER_DESC indexBufferDesc;
	ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));

	indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	indexBufferDesc.ByteWidth = sizeof(DWORD)* NumSphereFaces * 3;
	indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	indexBufferDesc.CPUAccessFlags = 0;
	indexBufferDesc.MiscFlags = 0;

	D3D11_SUBRESOURCE_DATA iinitData;

	iinitData.pSysMem = &indices[0];
	device->CreateBuffer(&indexBufferDesc, &iinitData, &sphereIndexBuffer);
}
Esempio n. 2
0
void GeometryGenerator::CreateSphere(float radius, UINT sliceCount, UINT stackCount, MeshData& meshData)
{
    meshData.Vertices.clear();
    meshData.Indices.clear();

    //
    // Compute the vertices stating at the top pole and moving down the stacks.
    //

    // Poles: note that there will be texture coordinate distortion as there is
    // not a unique point on the texture map to assign to the pole when mapping
    // a rectangular texture onto a sphere.
    Vertex topVertex(0.0f, +radius, 0.0f, 0.0f, +1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
    Vertex bottomVertex(0.0f, -radius, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);

    meshData.Vertices.push_back(topVertex);

    float phiStep = XM_PI / stackCount;
    float thetaStep = 2.0f*XM_PI / sliceCount;

    // Compute vertices for each stack ring (do not count the poles as rings).
    for (UINT i = 1; i <= stackCount - 1; ++i)
    {
        float phi = i*phiStep;

        // Vertices of ring.
        for (UINT j = 0; j <= sliceCount; ++j)
        {
            float theta = j*thetaStep;

            Vertex v;

            // spherical to cartesian
            v.Position.x = radius*sinf(phi)*cosf(theta);
            v.Position.y = radius*cosf(phi);
            v.Position.z = radius*sinf(phi)*sinf(theta);

            // Partial derivative of P with respect to theta
            v.TangentU.x = -radius*sinf(phi)*sinf(theta);
            v.TangentU.y = 0.0f;
            v.TangentU.z = +radius*sinf(phi)*cosf(theta);

            XMVECTOR T = XMLoadFloat3(&v.TangentU);
            XMStoreFloat3(&v.TangentU, XMVector3Normalize(T));

            XMVECTOR p = XMLoadFloat3(&v.Position);
            XMStoreFloat3(&v.Normal, XMVector3Normalize(p));

            v.TexC.x = theta / XM_2PI;
            v.TexC.y = phi / XM_PI;

            meshData.Vertices.push_back(v);
        }
    }

    meshData.Vertices.push_back(bottomVertex);

    //
    // Compute indices for top stack.  The top stack was written first to the vertex buffer
    // and connects the top pole to the first ring.
    //

    for (UINT i = 1; i <= sliceCount; ++i)
    {
        meshData.Indices.push_back(0);
        meshData.Indices.push_back(i + 1);
        meshData.Indices.push_back(i);
    }

    //
    // Compute indices for inner stacks (not connected to poles).
    //

    // Offset the indices to the index of the first vertex in the first ring.
    // This is just skipping the top pole vertex.
    UINT baseIndex = 1;
    UINT ringVertexCount = sliceCount + 1;
    for (UINT i = 0; i < stackCount - 2; ++i)
    {
        for (UINT j = 0; j < sliceCount; ++j)
        {
            meshData.Indices.push_back(baseIndex + i*ringVertexCount + j);
            meshData.Indices.push_back(baseIndex + i*ringVertexCount + j + 1);
            meshData.Indices.push_back(baseIndex + (i + 1)*ringVertexCount + j);

            meshData.Indices.push_back(baseIndex + (i + 1)*ringVertexCount + j);
            meshData.Indices.push_back(baseIndex + i*ringVertexCount + j + 1);
            meshData.Indices.push_back(baseIndex + (i + 1)*ringVertexCount + j + 1);
        }
    }

    //
    // Compute indices for bottom stack.  The bottom stack was written last to the vertex buffer
    // and connects the bottom pole to the bottom ring.
    //

    // South pole vertex was added last.
    UINT southPoleIndex = (UINT)meshData.Vertices.size() - 1;

    // Offset the indices to the index of the first vertex in the last ring.
    baseIndex = southPoleIndex - ringVertexCount;

    for (UINT i = 0; i < sliceCount; ++i)
    {
        meshData.Indices.push_back(southPoleIndex);
        meshData.Indices.push_back(baseIndex + i);
        meshData.Indices.push_back(baseIndex + i + 1);
    }
}
	GfxEntityHeightMap::GfxEntityHeightMap(const XMVECTOR& _lowerLeftCorner, float _quadSize, unsigned int _width, unsigned int _length, float* heights)
	{
		//compute how many vertices we have
		m_vertexCount = (_width + 3) * (_length + 3);
		XMVECTOR* verticesPosition = (XMVECTOR*)_aligned_malloc(sizeof(XMVECTOR)* m_vertexCount, 16);// new XMVECTOR[vertexCount];
		XMVECTOR* verticesNormal = (XMVECTOR*)_aligned_malloc(sizeof(XMVECTOR)* m_vertexCount, 16);//new XMVECTOR[vertexCount];

		//fill in the array of vertices
		int vertexId = 0;	
		for (unsigned int row = 0; row <= _length+2; ++row) //loop through each row
		{
			int borderedRow = row - 1;
			XMVECTOR offsetZ = _lowerLeftCorner + (XMVectorSet(0, 0, _quadSize, 0) * (float)borderedRow);
			for (unsigned int column = 0; column <= _width+2; ++column) //loop through each column
			{
				int borderedColumn = column - 1;
				verticesPosition[vertexId] = offsetZ + (XMVectorSet(_quadSize, 0, 0, 0) * (float)(borderedColumn)) + XMVectorSet(0, heights[vertexId], 0, 0);
				verticesNormal[vertexId] = XMVectorSet(0, 0, 0, 0);
				++vertexId;
			}
		}
		
		//compute how many triangle and indices we need
		unsigned int triangleCount = (_width) * (_length) * 2;
		m_indicesCount = triangleCount * 3;

		//create the index buffer
		unsigned int indexId = 0;
		unsigned long* indices = new unsigned long[m_indicesCount];
		unsigned int vertexPerRow = _width + 3;
		for (unsigned int row = 0; row < _length + 2; ++row) //loop through each row
		{
			unsigned int offsetId = row * vertexPerRow;
			for (unsigned int column = 0; column < _width + 2; ++column)//loop through each column
			{
				unsigned int id0 = offsetId + column;
				unsigned int id1 = offsetId + column + vertexPerRow + 1;
				unsigned int id2 = offsetId + column + 1;
				if (row != 0 && row != _length + 1 && column != 0 && column != _width + 1)
				{
					//lower right triangle
					indices[indexId] = id0;
					indices[indexId + 1] = id1;
					indices[indexId + 2] = id2;
					indexId += 3;
				}
				//compute normals
				XMVECTOR v0 = verticesPosition[id0];
				XMVECTOR v1 = verticesPosition[id1];
				XMVECTOR v2 = verticesPosition[id2];

				XMVECTOR normal = XMVector3Cross(v0 - v1, v2 - v1);
				normal = XMVector3Normalize(normal);
				
				verticesNormal[id0] += normal;
				verticesNormal[id1] += normal;
				verticesNormal[id2] += normal;
				
			
				id0 = offsetId + column;
				id1 = offsetId + column + vertexPerRow;
				id2 = offsetId + column + vertexPerRow + 1;
				if (row != 0 && row != _length + 1 && column != 0 && column != _width + 1)
				{
					indices[indexId] = id0;
					indices[indexId + 1] = id1;
					indices[indexId + 2] = id2;
					indexId += 3;
				}
				//compute normals
				v0 = verticesPosition[id0];
				v1 = verticesPosition[id1];
				v2 = verticesPosition[id2];

				normal = XMVector3Cross(v0 - v1, v2 - v1);
				normal = XMVector3Normalize(normal);

				verticesNormal[id0] += normal;
				verticesNormal[id1] += normal;
				verticesNormal[id2] += normal;			
			}
		}
		
		//compute normals
		//unsigned int vertexPerRow = _length + 3;
		//unsigned int vertexPerColumn = _length + 3;

		for (unsigned int row = 0; row <= _length+2; ++row) //loop through each row
		{
			unsigned int offset = row * (_width + 3);
			for (unsigned int column = 0; column <= _width+2; ++column)//loop through each column
			{
				unsigned int vertexId = offset + column;

				//case where a vertex is shared by 1 triangle
				if ((row == 0 && column == _width+2) ||			//bottom right corner
					(row == _length+2 && column == 0))			//top left corner
				{
					//nothing to do
				}
				//case where a vertex is shared by 2 triangles
				else if ((row == 0 && column == 0) ||			//bottom left corner
					(row == _length+2 && column == _width+2))		//top right corner
				{
					verticesNormal[vertexId] = verticesNormal[vertexId] / 2;
				}
				//case where a vertex is shared by 3 triangles
				else if (row == 0 || row == _length+2 || column == 0 || column == _width+2)	//border
				{
					verticesNormal[vertexId] = verticesNormal[vertexId] / 3;
				}
				else //the inside of the height map. Each vertex is shared by 6 triangles
				{
					verticesNormal[vertexId] = verticesNormal[vertexId] / 6;
				}

				verticesNormal[vertexId] = XMVector3Normalize(verticesNormal[vertexId]);
			}

		}

		//fill in dx structures
		VertexPositionNormalColor* vertices = new VertexPositionNormalColor[m_vertexCount];
		for (unsigned int i = 0; i < m_vertexCount; ++i)
		{
			XMStoreFloat3(&vertices[i].position, verticesPosition[i]);
			XMStoreFloat3(&vertices[i].normal, verticesNormal[i]);

			XMFLOAT4 myColor;
			myColor.x = 0.4f;
			myColor.y = 0.4f;
			myColor.z = abs((vertices[i].position.y + 200) / 1000.f)+0.1f;
			myColor.w = 1.f;
			vertices[i].color = myColor;
		}


		// Set up the description of the static vertex buffer.
		D3D11_BUFFER_DESC vertexBufferDesc;
		vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
		vertexBufferDesc.ByteWidth = sizeof(VertexPositionNormalColor)* m_vertexCount;
		vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		vertexBufferDesc.CPUAccessFlags = 0;
		vertexBufferDesc.MiscFlags = 0;
		vertexBufferDesc.StructureByteStride = 0;

		// Give the subresource structure a pointer to the vertex data.
		D3D11_SUBRESOURCE_DATA vertexData;
		vertexData.pSysMem = vertices;
		vertexData.SysMemPitch = 0;
		vertexData.SysMemSlicePitch = 0;

		// Now create the vertex buffer.
		HRESULT result = GRAPHICS->getDirectXWrapper()->getDevice()->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
		if (FAILED(result))
			throw;

		// Set up the description of the static index buffer.
		D3D11_BUFFER_DESC indexBufferDesc;
		indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
		indexBufferDesc.ByteWidth = sizeof(unsigned long)* m_indicesCount;
		indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
		indexBufferDesc.CPUAccessFlags = 0;
		indexBufferDesc.MiscFlags = 0;
		indexBufferDesc.StructureByteStride = 0;

		// Give the subresource structure a pointer to the index data.
		D3D11_SUBRESOURCE_DATA indexData;
		indexData.pSysMem = indices;
		indexData.SysMemPitch = 0;
		indexData.SysMemSlicePitch = 0;
		
		// Create the index buffer.
		result = GRAPHICS->getDirectXWrapper()->getDevice()->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
		if (FAILED(result))
			throw;

		// Release the arrays now that the vertex and index buffers have been created and loaded.
		_aligned_free(verticesPosition);
		_aligned_free(verticesNormal);
		delete[] vertices;
		delete[] indices;

		m_effect = EFFECT->getBasicEffect();
		m_inputLayout = EFFECT->getInputLayout();

	}
Esempio n. 4
0
void GeometryGenerator::CreateGeosphere(float radius, UINT numSubdivisions, MeshData& meshData)
{
    // Put a cap on the number of subdivisions.
    numSubdivisions = MathHelper::Min(numSubdivisions, 5u);

    // Approximate a sphere by tessellating an icosahedron.

    const float X = 0.525731f;
    const float Z = 0.850651f;

    XMFLOAT3 pos[12] =
    {
        XMFLOAT3(-X, 0.0f, Z),  XMFLOAT3(X, 0.0f, Z),
        XMFLOAT3(-X, 0.0f, -Z), XMFLOAT3(X, 0.0f, -Z),
        XMFLOAT3(0.0f, Z, X),   XMFLOAT3(0.0f, Z, -X),
        XMFLOAT3(0.0f, -Z, X),  XMFLOAT3(0.0f, -Z, -X),
        XMFLOAT3(Z, X, 0.0f),   XMFLOAT3(-Z, X, 0.0f),
        XMFLOAT3(Z, -X, 0.0f),  XMFLOAT3(-Z, -X, 0.0f)
    };

    DWORD k[60] =
    {
        1,4,0,  4,9,0,  4,5,9,  8,5,4,  1,8,4,
        1,10,8, 10,3,8, 8,3,5,  3,2,5,  3,7,2,
        3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0,
        10,1,6, 11,0,9, 2,11,9, 5,2,9,  11,2,7
    };

    meshData.Vertices.resize(12);
    meshData.Indices.resize(60);

    for (UINT i = 0; i < 12; ++i)
        meshData.Vertices[i].Position = pos[i];

    for (UINT i = 0; i < 60; ++i)
        meshData.Indices[i] = k[i];

    for (UINT i = 0; i < numSubdivisions; ++i)
        Subdivide(meshData);

    // Project vertices onto sphere and scale.
    for (UINT i = 0; i < meshData.Vertices.size(); ++i)
    {
        // Project onto unit sphere.
        XMVECTOR n = XMVector3Normalize(XMLoadFloat3(&meshData.Vertices[i].Position));

        // Project onto sphere.
        XMVECTOR p = radius*n;

        XMStoreFloat3(&meshData.Vertices[i].Position, p);
        XMStoreFloat3(&meshData.Vertices[i].Normal, n);

        // Derive texture coordinates from spherical coordinates.
        float theta = MathHelper::AngleFromXY(
            meshData.Vertices[i].Position.x,
            meshData.Vertices[i].Position.z);

        float phi = acosf(meshData.Vertices[i].Position.y / radius);

        meshData.Vertices[i].TexC.x = theta / XM_2PI;
        meshData.Vertices[i].TexC.y = phi / XM_PI;

        // Partial derivative of P with respect to theta
        meshData.Vertices[i].TangentU.x = -radius*sinf(phi)*sinf(theta);
        meshData.Vertices[i].TangentU.y = 0.0f;
        meshData.Vertices[i].TangentU.z = +radius*sinf(phi)*cosf(theta);

        XMVECTOR T = XMLoadFloat3(&meshData.Vertices[i].TangentU);
        XMStoreFloat3(&meshData.Vertices[i].TangentU, XMVector3Normalize(T));
    }
}
Esempio n. 5
0
void GeometryGenerator::CreateCylinder(float bottomRadius, float topRadius,
    float height, UINT sliceCount, UINT stackCount, MeshData& meshData)
{
    meshData.Vertices.clear();
    meshData.Indices.clear();

    //
    // Build Stacks.
    // 

    float stackHeight = height / stackCount;

    // Amount to increment radius as we move up each stack level from bottom to top.
    float radiusStep = (topRadius - bottomRadius) / stackCount;

    UINT ringCount = stackCount + 1;

    // Compute vertices for each stack ring starting at the bottom and moving up.
    for (UINT i = 0; i < ringCount; ++i)
    {
        float y = -0.5f*height + i*stackHeight;
        float r = bottomRadius + i*radiusStep;

        // vertices of ring
        float dTheta = 2.0f*XM_PI / sliceCount;
        for (UINT j = 0; j <= sliceCount; ++j)
        {
            Vertex vertex;

            float c = cosf(j*dTheta);
            float s = sinf(j*dTheta);

            vertex.Position = XMFLOAT3(r*c, y, r*s);

            vertex.TexC.x = (float)j / sliceCount;
            vertex.TexC.y = 1.0f - (float)i / stackCount;

            // Cylinder can be parameterized as follows, where we introduce v
            // parameter that goes in the same direction as the v tex-coord
            // so that the bitangent goes in the same direction as the v tex-coord.
            //   Let r0 be the bottom radius and let r1 be the top radius.
            //   y(v) = h - hv for v in [0,1].
            //   r(v) = r1 + (r0-r1)v
            //
            //   x(t, v) = r(v)*cos(t)
            //   y(t, v) = h - hv
            //   z(t, v) = r(v)*sin(t)
            // 
            //  dx/dt = -r(v)*sin(t)
            //  dy/dt = 0
            //  dz/dt = +r(v)*cos(t)
            //
            //  dx/dv = (r0-r1)*cos(t)
            //  dy/dv = -h
            //  dz/dv = (r0-r1)*sin(t)

            // This is unit length.
            vertex.TangentU = XMFLOAT3(-s, 0.0f, c);

            float dr = bottomRadius - topRadius;
            XMFLOAT3 bitangent(dr*c, -height, dr*s);

            XMVECTOR T = XMLoadFloat3(&vertex.TangentU);
            XMVECTOR B = XMLoadFloat3(&bitangent);
            XMVECTOR N = XMVector3Normalize(XMVector3Cross(T, B));
            XMStoreFloat3(&vertex.Normal, N);

            meshData.Vertices.push_back(vertex);
        }
    }

    // Add one because we duplicate the first and last vertex per ring
    // since the texture coordinates are different.
    UINT ringVertexCount = sliceCount + 1;

    // Compute indices for each stack.
    for (UINT i = 0; i < stackCount; ++i)
    {
        for (UINT j = 0; j < sliceCount; ++j)
        {
            meshData.Indices.push_back(i*ringVertexCount + j);
            meshData.Indices.push_back((i + 1)*ringVertexCount + j);
            meshData.Indices.push_back((i + 1)*ringVertexCount + j + 1);

            meshData.Indices.push_back(i*ringVertexCount + j);
            meshData.Indices.push_back((i + 1)*ringVertexCount + j + 1);
            meshData.Indices.push_back(i*ringVertexCount + j + 1);
        }
    }

    BuildCylinderTopCap(bottomRadius, topRadius, height, sliceCount, stackCount, meshData);
    BuildCylinderBottomCap(bottomRadius, topRadius, height, sliceCount, stackCount, meshData);
}
Esempio n. 6
0
bool FireBallParticles::Update(FXMVECTOR newPos, float fireballRadius, float dt, ID3D11DeviceContext* context)
{
	if (!mProperties.isFire || mIsAllParticlesDead)
	{
		return true;
	}

	XMVECTOR nPos = newPos;
	if (mTweenPoints.size() > 0)
	{
		nPos = XMLoadFloat3(&mCurrTweenPoint);
		UpdateCurrentTweenPoint(dt);
	}

	XMFLOAT3 fVel3;
	float pSize;
	bool isParticleStillAlive = false;
	for (int i = 0; i < mFireBallParticles.size(); ++i)
	{
		XMVECTOR pos = XMLoadFloat3(&mFireBallParticles[i].pos);
		XMVECTOR vel = XMLoadFloat3(&mFireBallParticles[i].vel);

		mFireBallParticles[i].age += dt;
		if (mProperties.isOneShot && (mFireBallParticles[i].age >= mFireBallParticles[i].lifetime))
		{
			continue;
		}
		else if (mFireBallParticles[i].age <= mFireBallParticles[i].lifetime)
		{
			isParticleStillAlive = true;
		}
		else if (!mProperties.isOneShot && (mFireBallParticles[i].age >= mFireBallParticles[i].lifetime))
		{
			isParticleStillAlive = true;
			vel = XMVector3Normalize(XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f)) * fireballRadius;
			XMStoreFloat3(&mFireBallParticles[i].pos, nPos + vel);
			fVel3 = GetVelocity();
			vel = XMVector3Normalize(XMVectorSet(fVel3.x, fVel3.y, fVel3.z, 0.0f));
			float speedMult = GetSpeedMultiplier();
			if (MathHelper::RandF() > 0.50f)
			{
				if (MathHelper::RandF() > 0.50f)
				{
					vel.m128_f32[0] += MathHelper::RandF(-0.4f, 0.4f);
					//vel.m128_f32[0] *= MathHelper::RandF(-0.06f, 0.06f);
					//vel.m128_f32[2] *= MathHelper::RandF(-0.06f, 0.06f);
				}
				else
				{
					vel.m128_f32[2] += MathHelper::RandF(-0.4f, 0.4f);
					//vel.m128_f32[0] *= MathHelper::RandF(-0.06f, 0.06f);
					//vel.m128_f32[2] *= MathHelper::RandF(-0.06f, 0.06f);
				}
			}
			XMStoreFloat3(&mFireBallParticles[i].vel, vel * speedMult);
			pSize = GetSize();
			mFireBallParticles[i].size.x = pSize;
			mFireBallParticles[i].size.y = pSize;
			mFireBallParticles[i].age = 0.0f;
			mFireBallParticles[i].lifetime = GetLifetime();
			pos = XMLoadFloat3(&mFireBallParticles[i].pos);
			vel = XMLoadFloat3(&mFireBallParticles[i].vel);
		}
		if (pos.m128_f32[1] < (nPos.m128_f32[1] + (fireballRadius * 0.60f)))
		{
			XMVECTOR s1Center = nPos;
			float s1Radius = fireballRadius;
			float currOverLap = 0.0f;
			XMVECTOR correction = XMVectorZero();

			XMVECTOR d = s1Center - pos;

			float distance = sqrt((d.m128_f32[0] * d.m128_f32[0]) /*+ (d.m128_f32[1] * d.m128_f32[1])*/ + (d.m128_f32[2] * d.m128_f32[2])); //Magnitude of the difference

			float overLap = s1Radius - distance;

			if (overLap > currOverLap) // Have Collision
			{
				currOverLap = overLap;

				correction = XMVector3Normalize(d) * currOverLap; //correct collision by moving sphere out of box
			}
			pos += correction;
		}
		pos = pos + vel;
		XMStoreFloat3(&mFireBallParticles[i].pos, pos);
	}

	if (isParticleStillAlive)
	{
		UpdateFireBallParticleVB(context);
	}
	else
	{
		mIsAllParticlesDead = true;
		if (mProperties.isOneShot)
		{
			ResetParticles();
		}
	}
	return false;
}
Esempio n. 7
0
void Player::HandleInput(float deltatime)
{

	auto i = System::GetInput();
	int x, y;

	XMVECTOR moveVec = XMVectorZero();
	XMVECTOR forward = _builder->GetEntityController()->Transform()->GetDirection(_camera);
	XMVECTOR right = _builder->GetEntityController()->Transform()->GetRight(_camera);
	XMVECTOR up = _builder->GetEntityController()->Transform()->GetUp(_camera);
	bool change = false;
	i->GetMouseDiff(x, y);
	if (x != 0)
		_builder->GetEntityController()->Transform()->RotateYaw(_camera, x  * 0.1f);
	if (y != 0)
		_builder->GetEntityController()->Transform()->RotatePitch(_camera, y  * 0.1f);


	if (i->IsKeyDown(VK_W))
	{
		moveVec += forward;
		change = true;
	}
	if (i->IsKeyDown(VK_S))
	{
		moveVec -= forward;
		change = true;
	}
	if (i->IsKeyDown(VK_A))
	{
		moveVec -= right;
		change = true;
	}
	if (i->IsKeyDown(VK_D))
	{
		moveVec += right;
		change = true;
	}
	//if (i->IsKeyDown(VK_SHIFT))
	//{
	//	moveVec += up;
	//	change = true;
	//}
	//if (i->IsKeyDown(VK_CONTROL))
	//{
	//	moveVec -= up;
	//	change = true;
	//}
	if (change)
	{
		if (i->IsKeyDown(VK_SHIFT) && _currentLight-_dashCost >= 0.0f && !_activeDash)
		{
			_activeDash = true;
			_lightDownBy += _dashCost;
			XMStoreFloat3(&_dashDir, XMVector3Normalize(moveVec));
			_builder->Animation()->PlayAnimation(_camera, "dash", 2.0f);
		}
		else
			_builder->GetEntityController()->Transform()->MoveAlongVector(_camera, XMVector3Normalize(moveVec), _speedFactor*deltatime);



	}

	if (i->IsKeyPushed(VK_T))
	{
		float offset = (_reservedLight * _maxLight / 20.0f)*BAR_MAXSIZE*_screenPercentWidth;
		_reservedLight = 0.5f;
		float delta = (_reservedLight * _maxLight / 20.0f)*BAR_MAXSIZE*_screenPercentWidth - offset;
		_lightDownBy += _maxLight*0.5f;
		_builder->Animation()->PlayAnimation(_lightReservedBar, "update", delta, offset);
	}

	if (i->IsKeyPushed(VK_Q))
	{
		_ChangePower();
	}


	if (i->IsMouseKeyDown(VK_LBUTTON))
	{
		if (_weapons[_currentWep]->Shoot(_camera))
		{
			_shotsFired++;
		}
	}

	if (!_weapons[_currentWep]->HasAmmo())
	{
		_weapons[_currentWep]->setActive(false);
		_currentWep = Weapons::Basic;
		_weapons[_currentWep]->setActive(true);
	}



	int sde = 0;
	if (i->IsScrollUp(sde))
	{
		Weapons c = _currentWep << 1;
		if (c._flags == 0)
			c._flags = 1;
		auto& find = _weapons.find(c);

		while (find == _weapons.end() || !find->second->HasAmmo())
		{
			c._flags = c._flags << 1;
			if (c._flags == 0)
				c._flags = 1;
			find = _weapons.find(c);
		}
		if (!(c == _currentWep))
		{
			_weapons[_currentWep]->setActive(false);
			_currentWep = c;
			_weapons[_currentWep]->setActive(true);
		}
	}
	if(i->IsScrollDown(sde))
	{
		Weapons c = _currentWep >> 1;
		if (c._flags == 0)
			c._flags = 1 << (sizeof(unsigned int)*8-1);
		auto& find = _weapons.find(c);

		while (find == _weapons.end() || !find->second->HasAmmo())
		{
			c._flags = c._flags >> 1;
			if (c._flags == 0)
				c._flags = 1 << (sizeof(unsigned int) * 8 - 1);
			find = _weapons.find(c);
		}
		if (!(c == _currentWep))
		{
			_weapons[_currentWep]->setActive(false);
			_currentWep = c;
			_weapons[_currentWep]->setActive(true);
		}
	}
Esempio n. 8
0
void Camera::Update()
{


	int dMouseX = 0;
	int dMouseY = 0;

	if( InputManager::Instance()->IsMouseButtonDown(0))
	{
		InputManager::Instance()->GetMouseMove(dMouseX, dMouseY);
		m_Yaw += dMouseX * m_RotationSpeed * XM_PI/180;
		m_Pitch += dMouseY * m_RotationSpeed * XM_PI/180;
	}

	CXMVECTOR Forward = XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f);
	CXMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);
	CXMVECTOR Right = XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f);

	//XMMATRIX rotation = XMMatrixRotationAxis(Up, m_Yaw);

	XMMATRIX rotation = XMMatrixRotationRollPitchYaw(m_Pitch, m_Yaw, 0.0f);
	XMVECTOR position = XMLoadFloat3(&m_Position);
	
	//XMVECTOR quaternion = XMVectorSet(0.0f, m_Yaw, 0.0f, 1.0f);

	
	XMVECTOR transformedForward = XMVector3Transform(Forward, rotation);
	XMVector3Normalize(transformedForward);

	XMVECTOR transformedRight = XMVector3Transform(Right, rotation);
	XMVector3Normalize(transformedRight);

	// Compute view matrix.
	
	//XMFLOAT3 lookAt(m_Position);
	//lookAt.z+=1.0f;
	//XMVECTOR At = XMLoadFloat3(&lookAt);
	//XMVectorSet(0.0f, -1.0f, 0.0f, 1.0f);
	/*XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);*/



	if ( InputManager::Instance()->IsKeyDown(DIK_W))
	{
		//m_Position.z += 1.0f;
		position += transformedForward * m_MovementSpeed;
	}

	if ( InputManager::Instance()->IsKeyDown(DIK_S))
	{
		position -= transformedForward * m_MovementSpeed;
	}

	if ( InputManager::Instance()->IsKeyDown(DIK_A))
	{
		position -= transformedRight * m_MovementSpeed;
	}

	if ( InputManager::Instance()->IsKeyDown(DIK_D))
	{
		position += transformedRight * m_MovementSpeed;
	}

	if ( InputManager::Instance()->IsKeyDown(DIK_Q))
	{
		position += Up * m_MovementSpeed;
	}

	if ( InputManager::Instance()->IsKeyDown(DIK_E))
	{
		position -= Up * m_MovementSpeed;
	}

	
	CXMMATRIX view = XMMatrixTranspose(XMMatrixLookAtLH(position, transformedForward + position, Up));

	XMStoreFloat4x4(&m_ViewMatrix, view);

	// Compute projection matrix.
	CXMMATRIX proj = XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PIDIV2, Engine::Instance()->GetWidth()/(FLOAT)Engine::Instance()->GetHeight(), 0.01f, 10000.0f));
	XMStoreFloat4x4(&m_ProjectionMatrix, proj);

	// Compute invert view projection matrix.

	CXMMATRIX invertViewProj = XMMatrixInverse(nullptr, XMMatrixMultiply(view, proj));
	XMStoreFloat4x4(&m_InvertViewProjectionMatrix, invertViewProj);

	XMStoreFloat3(&m_Position, position);
}
Esempio n. 9
0
	EngineState::EngineState() :
#if defined(_PROFILE) | defined(_DEBUG)
		m_displayShadowMaps(false),
		m_displayShadowFrustum(false),
		m_displayShadowBuffer(false),
#endif
		m_BackBufferDesc({ 1280, 720, 
			DXGI_FORMAT_R16G16B16A16_FLOAT, 
			{ 1, 0 } }),
		m_Viewport({ 0.0f, 0.0f, 
			static_cast<float>(m_BackBufferDesc.Width), 
			static_cast<float>(m_BackBufferDesc.Height), 
			0.0f, 1.0f}),
		m_Light(-0.5f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f),
		m_LightDirection(XMVector3Normalize(XMVectorSet(1.f, 0.5f, 0.3f, 0.f))),

		m_fovy(XM_PI / 3.f),
		m_aspect(m_Viewport.Width / m_Viewport.Height),
		m_znear(0.1f),
		m_zfar(200.f),

		m_LightShafts(true),
		m_DepthOfField(true),
		m_Bloom(true),
		m_AmbientOcclusion(true),
		m_Fxaa(true),

		m_ShadowMapSize(2048),
		m_ShadowMapCount(3),
		m_ShadowMapQuality(1),
		m_ShadowMapType(2),

		m_fullScreen(false),
		m_vsync(true),
		m_refreshRate({60,1})
	{
		NvGsaApplication app;
		NvGsaStatus status;

		const NvGsaNamedOption *options = NULL;
		size_t numOptions = 0;

		const NvGsaResolution *resolutions = NULL;
		size_t numResolutions = 0;

		NvGsaVersion runtimeVersion = GFSDK_GSA_GetVersion();

		// Print the GSA compile time version
		wprintf(L"Compiled against GSA version: ");
		printGsaVersion(&NvGsaCurrentVersion);
		wprintf(L"\n");

		// Print the GSA run time version
		wprintf(L"Running against GSA version: ");
		printGsaVersion(&runtimeVersion);
		wprintf(L"\n");

		// Initialize the application
		LPWSTR *szArglist;
		int nArgs = 0;
		szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
		if (nArgs < 1 || !initApplication(&app, szArglist[0])) {
			wprintf(L"Failed to initialize the application, exiting!");
			return;
		}
		GlobalFree(szArglist);

		// Initialize the GSA SDK
		status = GFSDK_GSA_InitializeSDK(&app, &NvGsaCurrentVersion);
		releaseApplication(&app);
		if (status != NV_GSA_STATUS_OK) {
			wprintf(L"Failed to initialize the GSA SDK, exiting!");
			return;
		}

		if (initOptions(&options, &numOptions) &&
			initResolutions(&resolutions, &numResolutions)) {

			//status = GFSDK_GSA_SaveConfigFile(NV_GSA_SAVE_ALL);

			NvGsaResolution currentResolution;
			size_t i;

			// Register the options
			for (i = 0; i < numOptions; ++i) {
				GFSDK_GSA_RegisterOption(&options[i]);
			}

			// Register the resolutions
			GFSDK_GSA_RegisterResolutions(resolutions, (int)numResolutions);

			// Load the config file
			status = GFSDK_GSA_LoadConfigFile();
			if (status == NV_GSA_STATUS_FILENOTFOUND) {
				GFSDK_GSA_SetResolution(&resolutions[0]);
			}

			// Print and cycle the options
			for (i = 0; i < numOptions; ++i) {
				NvGsaVariant value;
				value.type = options[i].value.type;
				status = GFSDK_GSA_GetOptionValue(&value, options[i].name);
				if (status == NV_GSA_STATUS_OK) {

					switch (str2int(options[i].name))
					{
					case str2int(L"Field_Of_View"):
						m_fovy = value.asFloat;
						break;
					case str2int(L"Near_Plane"):
						m_znear = value.asFloat;
						break;
					case str2int(L"Far_Plane"):
						m_zfar = value.asFloat;
						break;
					case str2int(L"LightShafts"):
						m_LightShafts = value.asBool;
						break;
					case str2int(L"DepthOfField"):
						m_DepthOfField = value.asBool;
						break;
					case str2int(L"Bloom"):
						m_Bloom = value.asBool;
						break;
					case str2int(L"AmbientOcclusion"):
						m_AmbientOcclusion = value.asBool;
						break;
					case str2int(L"Fxaa"):
						m_Fxaa = value.asBool;
						break;
					case str2int(L"FullScreen"):
						m_fullScreen = value.asBool;
						break;
					case str2int(L"V-Sync"):
						m_vsync = value.asBool;
						break;
					case str2int(L"ShadowMapSize"):
						switch (str2int(value.asEnum))
						{
						case str2int(L"512"):
							m_ShadowMapSize = 512;
							break;
						case str2int(L"1024"):
							m_ShadowMapSize = 1024;
							break;
						case str2int(L"2048"):
							m_ShadowMapSize = 2048;
							break;
						case str2int(L"4096"):
							m_ShadowMapSize = 4096;
							break;
						}
						break;
					case str2int(L"ShadowMapCount"):
						m_ShadowMapCount = value.asInt;
						break;
					case str2int(L"ShadowMapQuality"):
						switch (str2int(value.asEnum))
						{
						case str2int(L"Low_Hard"):
							m_ShadowMapQuality = 0;
							m_ShadowMapType = 0;
							break;
						case str2int(L"Medium_Hard"):
							m_ShadowMapQuality = 1;
							m_ShadowMapType = 0;
							break;
						case str2int(L"High_Hard"):
							m_ShadowMapQuality = 2;
							m_ShadowMapType = 0;
							break;
						case str2int(L"Low_PCF"):
							m_ShadowMapQuality = 0;
							m_ShadowMapType = 1;
							break;
						case str2int(L"Medium_PCF"):
							m_ShadowMapQuality = 1;
							m_ShadowMapType = 1;
							break;
						case str2int(L"High_PCF"):
							m_ShadowMapQuality = 2;
							m_ShadowMapType = 1;
							break;
						case str2int(L"Low_PCSS"):
							m_ShadowMapQuality = 0;
							m_ShadowMapType = 2;
							break;
						case str2int(L"Medium_PCSS"):
							m_ShadowMapQuality = 1;
							m_ShadowMapType = 2;
							break;
						case str2int(L"High_PCSS"):
							m_ShadowMapQuality = 2;
							m_ShadowMapType = 2;
							break;
						}
						break;
					}
					GFSDK_GSA_ReleaseVariant(&value);
				}
			}

			// Print and increment the resolution
			status = GFSDK_GSA_GetResolution(&currentResolution);
			if (status == NV_GSA_STATUS_OK) {
				m_refreshRate.Numerator = (UINT)round(currentResolution.refreshRate);
				WindowSizeChanged(currentResolution.width, currentResolution.height);
			}
		}

		// Cleanup
		releaseOptions(options);
		releaseResolutions(resolutions);

		m_Camera.SetProjParams(m_fovy, m_aspect, m_znear, m_zfar);
		m_Camera.SetViewParams(XMVectorSet(0.f, 0.f, 0.f, 1.f), XMVectorSet(0.f, 0.f, 1.f, 1.f));
	}
Esempio n. 10
0
void CalcTangentAndBinormal(
	SimpleVertexNormal& p0,
	SimpleVertexNormal& p1,
	SimpleVertexNormal& p2
	) {
	// 5次元→3次元頂点に
	XMVECTOR CP0[3] = {
		XMVectorSet(p0.Pos.x, p0.Tex.x, p0.Tex.y,1),
		XMVectorSet(p0.Pos.y, p0.Tex.x, p0.Tex.y,1),
		XMVectorSet(p0.Pos.z, p0.Tex.x, p0.Tex.y,1),
	};
	XMVECTOR CP1[3] = {
		XMVectorSet(p1.Pos.x, p1.Tex.x, p1.Tex.y, 1),
		XMVectorSet(p1.Pos.y, p1.Tex.x, p1.Tex.y, 1),
		XMVectorSet(p1.Pos.z, p1.Tex.x, p1.Tex.y, 1),
	};
	XMVECTOR CP2[3] = {
		XMVectorSet(p2.Pos.x, p2.Tex.x, p2.Tex.y, 1),
		XMVectorSet(p2.Pos.y, p2.Tex.x, p2.Tex.y, 1),
		XMVectorSet(p2.Pos.z, p2.Tex.x, p2.Tex.y, 1),
	};

	// 平面パラメータからUV軸座標算出
	float U[3], V[3];
	for (int i = 0; i < 3; ++i) {
		XMVECTOR V1 = CP1[i] - CP0[i];
		XMVECTOR V2 = CP2[i] - CP1[i];
		XMVECTOR ABC;
		ABC = XMVector3Cross(V1, V2);

		if (ABC.x == 0.0f) {
			// やばいす!
			// ポリゴンかUV上のポリゴンが縮退してます!
			//_ASSERT(0);
			//memset(outTangent, 0, sizeof(D3DXVECTOR3));
			//memset(outBinormal, 0, sizeof(D3DXVECTOR3));
			p0.Binormal = XMFLOAT3(1, 0, 0);
			p1.Binormal = XMFLOAT3(1, 0, 0);
			p2.Binormal = XMFLOAT3(1, 0, 0);
			p0.Tangent = XMFLOAT3(0,1,0);
			p1.Tangent = XMFLOAT3(0,1,0);
			p2.Tangent = XMFLOAT3(0,1,0);
			return;
		}
		U[i] = -ABC.y / ABC.x;
		V[i] = -ABC.z / ABC.x;
	}


	XMVECTOR tan = XMVectorSet(U[0], U[1], U[2], 1);
	XMVECTOR bin = -XMVectorSet(V[0], V[1], V[2], 1);

	// 正規化します
	tan = XMVector3Normalize(tan);
	bin = XMVector3Normalize(bin);

	p0.Binormal = XMFLOAT3(bin.x, bin.y, bin.z);
	p1.Binormal = XMFLOAT3(bin.x, bin.y, bin.z);
	p2.Binormal = XMFLOAT3(bin.x, bin.y, bin.z);
	p0.Tangent = XMFLOAT3(tan.x, tan.y, tan.z);
	p1.Tangent = XMFLOAT3(tan.x, tan.y, tan.z);
	p2.Tangent = XMFLOAT3(tan.x, tan.y, tan.z);
}
Esempio n. 11
0
 Vector Vector::normalize(const Vector& vec)
 {
     return Vector(XMVector3Normalize(vec.getXMVector()));
 }
void AmbientOcclusionApp::BuildVertexAmbientOcclusion(
	std::vector<Vertex::AmbientOcclusion>& vertices,
	const std::vector<UINT>& indices)
{
	UINT vcount = vertices.size();
	UINT tcount = indices.size()/3;

	std::vector<XMFLOAT3> positions(vcount);
	for(UINT i = 0; i < vcount; ++i)
		positions[i] = vertices[i].Pos;

	Octree octree;
	octree.Build(positions, indices);

	// For each vertex, count how many triangles contain the vertex.
	std::vector<int> vertexSharedCount(vcount);
	for(UINT i = 0; i < tcount; ++i)
	{
		UINT i0 = indices[i*3+0];
		UINT i1 = indices[i*3+1];
		UINT i2 = indices[i*3+2];

		XMVECTOR v0 = XMLoadFloat3(&vertices[i0].Pos);
		XMVECTOR v1 = XMLoadFloat3(&vertices[i1].Pos);
		XMVECTOR v2 = XMLoadFloat3(&vertices[i2].Pos);

		XMVECTOR edge0 = v1 - v0;
		XMVECTOR edge1 = v2 - v0;

		XMVECTOR normal = XMVector3Normalize(XMVector3Cross(edge0, edge1));

		XMVECTOR centroid = (v0 + v1 + v2)/3.0f;

		// Offset to avoid self intersection.
		centroid += 0.001f*normal;

		const int NumSampleRays = 32;
		float numUnoccluded = 0;
		for(int j = 0; j < NumSampleRays; ++j)
		{
			XMVECTOR randomDir = MathHelper::RandHemisphereUnitVec3(normal);

			// TODO: Technically we should not count intersections that are far 
			// away as occluding the triangle, but this is OK for demo.
			if( !octree.RayOctreeIntersect(centroid, randomDir) )
			{
				numUnoccluded++;
			}
		}
		
		float ambientAccess = numUnoccluded / NumSampleRays;

		// Average with vertices that share this face.
		vertices[i0].AmbientAccess += ambientAccess;
		vertices[i1].AmbientAccess += ambientAccess;
		vertices[i2].AmbientAccess += ambientAccess;

		vertexSharedCount[i0]++;
		vertexSharedCount[i1]++;
		vertexSharedCount[i2]++;
	}

	// Finish average by dividing by the number of samples we added.
	for(UINT i = 0; i < vcount; ++i)
	{
		vertices[i].AmbientAccess /= vertexSharedCount[i];
	}
}
Esempio n. 13
0
//jingz //todo
void Waves::Update(float dt)
{
	static float t = 0.0f;

	// Accumulate time
	t += dt;

	if ( t>= m_fTimeStep)
	{
		for (UINT i = 1; i < m_uRows - 1;++i)
		{
			for (UINT j = 1; j < m_uCols - 1;++j)
			{
				// After this update we will be discarding the old previous
				// buffer, so overwrite that buffer with the new update.
				// Note how we can do this inplace (read/write to same element) 
				// because we won't need prev_ij again and the assignment happens last.

				// Note j indexes x and i indexes z: h(x_j, z_i, t_k)
				// Moreover, our +z axis goes "down"; this is just to 
				// keep consistent with our row indices going down.

				m_pPreSolution[i*m_uCols + j].y =
					m_fK1 * m_pPreSolution[i*m_uCols + j].y +
					m_fK2 * m_pCurSolution[i*m_uCols + j].y +
					m_fK3 * (
					m_pCurSolution[(i + 1)*m_uCols + j].y +
					m_pCurSolution[(i - 1)*m_uCols + j].y +
					m_pCurSolution[i*m_uCols + j + 1].y + 
					m_pCurSolution[i*m_uCols + j - 1].y
					);
			}
		}

		std::swap(m_pCurSolution, m_pPreSolution);

		//t -= m_fTimeStep;
		t = 0.0f;
		
		//jingz 感觉原作者的代码不是给人看的,有种行列故意倒换的感觉
		//
		// Compute normals using finite difference scheme.
		//
		for (UINT i = 1; i < m_uRows - 1;++i)
		{
			for (UINT j = 1; j < m_uCols - 1;++j)
			{
				float left = m_pCurSolution[i*m_uCols + j - 1].y;
				float right = m_pCurSolution[i*m_uCols + j + 1].y;
				float top = m_pCurSolution[(i-1)*m_uCols + j].y;
				float bottom = m_pCurSolution[(i+1)*m_uCols + j].y;

				m_pNormals[i*m_uCols + j].x = -right + left;
				m_pNormals[i*m_uCols + j].y = 2.0f*m_fSpatialStep;
				m_pNormals[i*m_uCols + j].z = bottom - top;

				XMVECTOR n = XMVector3Normalize(XMLoadFloat3((&m_pNormals[i*m_uCols + j])));
				XMStoreFloat3(&m_pNormals[i*m_uCols + j], n);

				m_pTangents[i*m_uCols + j] = XMFLOAT3(2.0f*m_fSpatialStep, right - left, 0.0f);
				XMVECTOR t = XMVector3Normalize(XMLoadFloat3(&m_pTangents[i*m_uCols + j]));
				XMStoreFloat3(&m_pTangents[i*m_uCols + j], t);
			}
		}

	}
}
Esempio n. 14
0
void LightingApp::UpdateScene(float dt)
{
	// Convert Spherical to Cartesian coordinates.
	float x = mRadius*sinf(mPhi)*cosf(mTheta);
	float z = mRadius*sinf(mPhi)*sinf(mTheta);
	float y = mRadius*cosf(mPhi);

	mEyePosW = XMFLOAT3(x, y, z);

	// Build the view matrix.
	XMVECTOR pos    = XMVectorSet(x, y, z, 1.0f);
	XMVECTOR target = XMVectorZero();
	XMVECTOR up     = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

	XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
	XMStoreFloat4x4(&mView, V);

	//
	// Every quarter second, generate a random wave.
	//
	static float t_base = 0.0f;
	if( (mTimer.TotalTime() - t_base) >= 0.25f )
	{
		t_base += 0.25f;
 
		DWORD i = 5 + rand() % (mWaves.RowCount()-10);
		DWORD j = 5 + rand() % (mWaves.ColumnCount()-10);

		float r = MathHelper::RandF(1.0f, 2.0f);

		mWaves.Disturb(i, j, r);
	}

	mWaves.Update(dt);

	//
	// Update the wave vertex buffer with the new solution.
	//
	
	D3D11_MAPPED_SUBRESOURCE mappedData;
	HR(md3dImmediateContext->Map(mWavesVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData));

	Vertex* v = reinterpret_cast<Vertex*>(mappedData.pData);
	for(UINT i = 0; i < mWaves.VertexCount(); ++i)
	{
		v[i].Pos    = mWaves[i];
		v[i].Normal = mWaves.Normal(i);
	}

	md3dImmediateContext->Unmap(mWavesVB, 0);

	//
	// Animate the lights.
	//

	// Circle light over the land surface.
	mPointLight.Position.x = 70.0f*cosf( 0.2f*mTimer.TotalTime() );
	mPointLight.Position.z = 70.0f*sinf( 0.2f*mTimer.TotalTime() );
	mPointLight.Position.y = MathHelper::Max(GetHillHeight(mPointLight.Position.x, 
		mPointLight.Position.z), -3.0f) + 10.0f;


	// The spotlight takes on the camera position and is aimed in the
	// same direction the camera is looking.  In this way, it looks
	// like we are holding a flashlight.
	mSpotLight.Position = mEyePosW;
	XMStoreFloat3(&mSpotLight.Direction, XMVector3Normalize(target - pos));
}
bool CollisionMesh::CheckCollisionsCustom(CollisionMesh &otherMesh)
{
  bool collision = false;
  std::vector<XMFLOAT3> convexHull;

  std::vector<VPCNTDesc> vertices = GetVertices();
  std::vector<VPCNTDesc> otherVertices = otherMesh.GetVertices();
  XMMATRIX otherWorld = otherMesh.GetWorldTransform();
  XMMATRIX world = GetWorldTransform();
  XMFLOAT3 origin = XMFLOAT3(0.0f, 0.0f, 0.0f);

  // Create a vector to ease the inversion calculation (we want the opposite direction for the translation vector).
  XMVECTOR inverse = XMVectorSet(-1.0f, -1.0f, -1.0f, 0.0f);
  
  XMVECTOR ourOriginDisplacement = XMVector3Transform(XMVectorSet(origin.x, origin.y, origin.z, 0.0f), world);
  XMMATRIX ourOriginTransform = XMMatrixTranslationFromVector(XMVectorMultiply(ourOriginDisplacement, inverse));

  // This is used for the purposes of moving the normals of the other object back to around (0, 0, 0).
  XMVECTOR theirOriginDisplacement = XMVector3Transform(XMVectorSet(origin.x, origin.y, origin.z, 0.0f), otherWorld);
  XMMATRIX theirOriginTransform = XMMatrixTranslationFromVector(XMVectorMultiply(theirOriginDisplacement, inverse));

  XMMATRIX ourOriginTranslatedWorld = world * ourOriginTransform;
  XMMATRIX theirOriginTranslatedWorld = otherWorld * ourOriginTransform;
  XMMATRIX theirOriginTranslatedWorldNormalAdjustment = theirOriginTransform * otherWorld;

  // Pre-multiply the model's vertices so as to avoid transforming them during comparison.
  for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
  {
    XMStoreFloat3(&vertices[vertIndex].Position, XMVector3Transform(XMLoadFloat3(&vertices[vertIndex].Position), ourOriginTranslatedWorld));
    XMStoreFloat3(&vertices[vertIndex].Normal, XMVector3Transform(XMLoadFloat3(&vertices[vertIndex].Normal), ourOriginTranslatedWorld));
  }

  for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
  {
    XMStoreFloat3(&otherVertices[otherVertIndex].Position, XMVector3Transform(XMLoadFloat3(&otherVertices[otherVertIndex].Position), theirOriginTranslatedWorld));
    XMStoreFloat3(&otherVertices[otherVertIndex].Normal, XMVector3Transform(XMLoadFloat3(&otherVertices[otherVertIndex].Normal), theirOriginTranslatedWorldNormalAdjustment));
  }

  int potentialCollisions = 0;
  std::vector<XMFLOAT3> positions;

  // Now that the pre-multiplication is done, time to do our first-case checking: are we inside of it?
  for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
  {
    bool localCollision = true;
    XMVECTOR ourVertex = XMLoadFloat3(&vertices[vertIndex].Position);
    XMVECTOR ourNormal = XMLoadFloat3(&vertices[vertIndex].Normal);

    // For each vertex in our mesh, we'll check to see if it resides inside our other mesh.
    for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
    {
      XMVECTOR otherVertex = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
      XMVECTOR otherNormal = XMLoadFloat3(&otherVertices[otherVertIndex].Normal);

      XMVECTOR difference = XMVectorSubtract(ourVertex, otherVertex);
      XMFLOAT3 differenceDotValue, normalDotValue;
      XMVECTOR diffLength = XMVector3Length(difference);
      XMVECTOR normLength = XMVector3Length(otherNormal);
      XMVECTOR magnitude = XMVectorMultiply(diffLength, normLength);

      XMStoreFloat3(&differenceDotValue, XMVectorDivide(XMVector3Dot(difference, otherNormal), magnitude));
      // At this point, we should have the cosine of the angle.
      float angleInRads = acosf(differenceDotValue.x);
      float angleInDegs = XMConvertToDegrees(angleInRads);

      XMStoreFloat3(&normalDotValue, XMVector3Dot(ourNormal, otherNormal));

      if (angleInDegs < 90.0f)
      {
        localCollision = false;
      }
    }

    if (localCollision)
    {
      positions.push_back(vertices[vertIndex].Position);
    }
  }

  if (positions.empty())
  {
    // Time to do our second-case checking: is it inside of us?
    for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
    {
      bool localCollision = true;
      XMVECTOR otherVertex = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
      XMVECTOR otherNormal = XMVector3Normalize(XMLoadFloat3(&otherVertices[otherVertIndex].Normal));

      // For each vertex in our mesh, we'll check to see if it resides inside our other mesh.
      for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
      {
        XMVECTOR ourVertex = XMLoadFloat3(&vertices[vertIndex].Position);
        XMVECTOR ourNormal = XMVector3Normalize(XMLoadFloat3(&vertices[vertIndex].Normal));

        XMVECTOR difference = XMVectorSubtract(otherVertex, ourVertex);
        XMFLOAT3 differenceDotValue, normalDotValue;
        XMVECTOR diffLength = XMVector3Length(difference);
        XMVECTOR normLength = XMVector3Length(ourNormal);
        XMVECTOR magnitude = XMVectorMultiply(diffLength, normLength);

        XMStoreFloat3(&differenceDotValue, XMVectorDivide(XMVector3Dot(difference, ourNormal), magnitude));
        // At this point, we should have the cosine of the angle.
        float angleInRads = acosf(differenceDotValue.x);
        float angleInDegs = XMConvertToDegrees(angleInRads);

        XMStoreFloat3(&normalDotValue, XMVector3Dot(ourNormal, otherNormal));

        if (angleInDegs < 90.0f)
        {
          localCollision = false;
        }
      }

      if (localCollision)
      {
        positions.push_back(otherVertices[otherVertIndex].Position);
      }
    }
  }

  if(positions.size())
  {
    mDelegate->CollisionOccurred(otherMesh.mDelegate);
    otherMesh.mDelegate->CollisionOccurred(mDelegate);
  }
  return positions.size();
}
bool CollisionMesh::CheckCollisionsGJK1(CollisionMesh& otherMesh)
{
  std::vector<XMFLOAT3> convexHull;
  bool foundOrigin = false;

  std::vector<VPCNTDesc> vertices = GetVertices();
  std::vector<VPCNTDesc> otherVertices = otherMesh.GetVertices();
  XMMATRIX otherWorld = otherMesh.GetWorldTransform();
  XMMATRIX world = GetWorldTransform();

  // Pre-multiply the model's vertices so as to avoid transforming them during comparison.
  for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
  {
    XMVECTOR vertexTransform = XMLoadFloat3(&vertices[vertIndex].Position);
    XMStoreFloat3(&vertices[vertIndex].Position, XMVector3Transform(vertexTransform, world));
  }

  for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
  {
    XMVECTOR vertexTransform = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
    XMStoreFloat3(&otherVertices[otherVertIndex].Position, XMVector3Transform(vertexTransform, otherWorld));
  }

  // Now we get to the fun part; the subtraction.
  for (int vertIndex = 0; vertIndex < vertices.size() && !foundOrigin; vertIndex++)
  {
    XMFLOAT3 vertexValue = vertices[vertIndex].Position;
    XMVECTOR vertexTransform = XMLoadFloat3(&vertexValue);

    for (int otherVertIndex = 0; otherVertIndex < otherVertices.size() && !foundOrigin; otherVertIndex++)
    {
      XMVECTOR otherVertexTransform = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
      XMFLOAT3 convexHullPoint;

      XMVECTOR difference = XMVectorSubtract(vertexTransform, otherVertexTransform);
      XMStoreFloat3(&convexHullPoint, difference);
      convexHull.push_back(convexHullPoint);

      foundOrigin = XMVector3Equal(difference, XMVectorZero());
    }

    convexHull.push_back(vertexValue);
  }

  if (!foundOrigin)
  {
    XMFLOAT3 collisionLine = XMFLOAT3(0.0f, 1250.0f, 500.0f);
    printf("We ain't found shit!");
    bool collision = true;
    int intersections = 0;
    for (int hullVertexIndex = 0; hullVertexIndex < convexHull.size() && convexHull.size() > 3; hullVertexIndex += 3)
    {
      int secondIndex = (hullVertexIndex + 1) % (convexHull.size() - 1);
      int thirdIndex = (hullVertexIndex + 2) % (convexHull.size() - 1);

      XMFLOAT3 firstVert = convexHull[hullVertexIndex];
      XMFLOAT3 secondVert = convexHull[secondIndex];
      XMFLOAT3 thirdVert = convexHull[thirdIndex];
      XMFLOAT3 origin = XMFLOAT3(0.0f, 0.0f, 0.0f);

      // we need to check the normal. Calculate using cross product.
      XMVECTOR firstVector = XMVectorSet(secondVert.x - firstVert.x, secondVert.y - firstVert.y, secondVert.z - firstVert.z, 0.0f);
      XMVECTOR secondVector = XMVectorSet(thirdVert.x - secondVert.x, thirdVert.y - secondVert.y, thirdVert.z - secondVert.z, 0.0f);

      XMFLOAT3 normal;
      XMStoreFloat3(&normal, XMVector3Normalize(XMVector3Cross(firstVector, secondVector)));

      // check to ensure no parallels are detected.
      float firstDot = (normal.x * collisionLine.x) + (normal.y * collisionLine.y) + (normal.z * collisionLine.z);
      if (firstDot < 0)
      {
        float delta = -((normal.x * (origin.x - firstVert.x)) + (normal.y * (origin.y - firstVert.y)) + (normal.z * (origin.z - firstVert.y))) /
          firstDot;

        if (delta < 0)
        {
          break;
        }

        XMFLOAT3 pointToCheck = XMFLOAT3(origin.x - (collisionLine.x * delta), origin.y - (collisionLine.y * delta), origin.z * (collisionLine.z * delta));

        bool firstCheck = CheckWinding(firstVert, secondVert, pointToCheck, normal);
        bool secondCheck = CheckWinding(secondVert, thirdVert, pointToCheck, normal);
        bool thirdCheck = CheckWinding(thirdVert, firstVert, pointToCheck, normal);

        if (firstCheck && secondCheck && thirdCheck)
        {
          intersections++;
        }
        else
        {
          collision = false;
        }
      }
    }

    if ((intersections % 2) == 1)
    {
      foundOrigin = true;
    }
  }

  return foundOrigin;
}