示例#1
0
文件: UnitTest.cpp 项目: jackhui/GE
TEST(Matrix, Translate)
{
	Matrix4 trans;
	trans.CreateTranslation(Vector3(5.0f, 10.0f, -4.0f));
	Vector3 v(Vector3::Zero);
	v.Transform(trans);

	EXPECT_NEAR(5.0f, v.GetX(), 0.01f);
	EXPECT_NEAR(10.0f, v.GetY(), 0.01f);
	EXPECT_NEAR(-4.0f, v.GetZ(), 0.01f);
}
示例#2
0
	void SpaceShooter::UpdatePlayerShip()
	{
		if ( InputManager::Get().GetKeyState( Key::W ) )
		{
			mPlayerObject->MoveForward();
			playerJetParticles->SetEmitterState( true );
		}
		else
		{
			mPlayerObject->StopAcceleration();
			playerJetParticles->SetEmitterState( false );
		}

		if ( InputManager::Get().GetKeyState( Key::A ) )
		{
			mPlayerObject->RotateLeft();
		}
		if ( InputManager::Get().GetKeyState( Key::D ) )
		{
			mPlayerObject->RotateRight();
		}

		// Update player's particles
		Matrix4 jetFuelTranspose = Matrix4::Identity;

		Matrix4 jetFuelOffset;
		jetFuelOffset.CreateTranslation( Vector3(0.f, 0.f, -5.5f) );

		Matrix4 jetFuelRotation;
		jetFuelRotation.CreateFromQuaternion( mPlayerObject->GetRotation() );

		Matrix4 jetFuelTranslation;
		jetFuelTranslation.CreateTranslation( mPlayerObject->GetTranslation() );

		jetFuelTranspose.Multiply( jetFuelTranslation );
		jetFuelTranspose.Multiply( jetFuelRotation );
		jetFuelTranspose.Multiply( jetFuelOffset );

		playerJetParticles->SetTranslationMatrix( jetFuelTranspose );
	}
void EditorBodyControl::ApplyTransform(float32 x, float32 y, float32 z)
{
	if (!InModificationMode())
		return;

    Entity *selectedNode = scene->GetProxy();
    if(selectedNode)
	{
		Matrix4 modification;
		modification.Identity();

		Matrix4 t1, t2;
		t1.CreateTranslation(-selectedNode->GetWorldTransform().GetTranslationVector());
		t2.CreateTranslation(selectedNode->GetWorldTransform().GetTranslationVector());

		switch (GetModificationMode())
		{
			case ResourceEditor::MODIFY_MOVE:
				modification.CreateTranslation(Vector3(x, y, z));
				break;

			case ResourceEditor::MODIFY_ROTATE:
				modification.CreateRotation(Vector3(1, 0, 0), DegToRad(x));
				modification *= Matrix4::MakeRotation(Vector3(0, 1, 0), DegToRad(y));
				modification *= Matrix4::MakeRotation(Vector3(0, 0, 1), DegToRad(z));

				modification = (t1 * modification) * t2;
				break;

			case ResourceEditor::MODIFY_SCALE:
				modification.CreateScale(Vector3(1, 1, 1) + Vector3(x + y + z, x + y + z, x + y + z) / 100.f);
				modification = (t1 * modification) * t2;
				break;

			default:
				break;
		}

		Matrix4 originalTransform = selectedNode->GetLocalTransform();
		modification = originalTransform * modification;

		if (IsLandscapeRelative())
		{
			modification = modification * GetLandscapeOffset(modification);
		}

		CommandsManager::Instance()->ExecuteAndRelease(new CommandTransformObject(selectedNode,
																				  originalTransform,
																				  modification),
													   scene);
	}
}
示例#4
0
void ModificationPopUp::OnFloatPropertyChanged(PropertyList *forList, const String &forKey, float newValue)
{
	if (selection)
	{
		Matrix4 modification;
		modification.Identity();
	
		modification.CreateTranslation(Vector3(forList->GetFloatPropertyValue("x"), 
                                               forList->GetFloatPropertyValue("y"), 
                                               forList->GetFloatPropertyValue("z")));	
		selection->SetLocalTransform(selection->GetLocalTransform() * modification);

		forList->SetFloatPropertyValue("x", 0.0f);
		forList->SetFloatPropertyValue("y", 0.0f);
		forList->SetFloatPropertyValue("z", 0.0f);
	}
}
void EditorBodyControl::UpdateArrowsNode(Entity* node)
{
	ArrowsNode* arrowsNode = GetArrowsNode(false);
	if (node && arrowsNode)
	{
		if (node == arrowsNode)
		{
			arrowsNode->SetVisible(false);
			return;
		}

		Matrix4 nodeWT = node->GetWorldTransform();
		Matrix4 arrowsNodeTransform;
		arrowsNodeTransform.CreateTranslation(nodeWT.GetTranslationVector());
		arrowsNode->SetLocalTransform(arrowsNodeTransform);
		arrowsNode->SetVisible(true);
		arrowsNode->SetActive(InModificationMode());
	}
}
Matrix4 EditorBodyControl::GetLandscapeOffset(const Matrix4& transform)
{
	Matrix4 resTransform;
	resTransform.Identity();

	Landscape* landscape = FindLandscape(scene);
	if(!landscape) return resTransform;

	Vector3 p = Vector3(0, 0, 0) * transform;

	Vector3 result;
	bool res = landscape->PlacePoint(p, result);
	if (res)
	{
		Vector3 offset = result - p;
		resTransform.CreateTranslation(offset);
	}

	return resTransform;
}
示例#7
0
GameObject* Terrain::CreateGameObject(const char* diffuseTxt_filename, const char* normalTxt_filename, const char* heightTxt_filemane)
{
	std::vector<float2> texture_coordinate = calculateTextureCoordiate();
	std::vector<float2> boundsY = CalcAllPatchBoundsY();

	const int iNumVertices = m_initInfo.HeightmapWidth / 8 * (m_initInfo.HeightmapHeight) / 8 * 4;
	const int iNumIndices = iNumVertices;
	VertexTerrain* vertices = new VertexTerrain[iNumVertices];
	unsigned int* indices = new unsigned int[iNumIndices];

	// Translate the terrain, so that the mid-point of terrain is at (0, 0, 0)
	Matrix4 translate;
	translate.CreateTranslation(Vector3(-GetWidth() / 2.0f, 0.0f, -GetDepth() / 2.0f));

	// Initialize the index to the vertex buffer.
	int indexCounter = 0;

	// Load the vertex and index array with the terrain data.
	for (int j = 0; j < m_initInfo.HeightmapHeight - 8; j += 8)
	{
		for (int i = 0; i < m_initInfo.HeightmapWidth - 8; i += 8)
		{
			const int index_bl = m_initInfo.HeightmapWidth * j + i;
			const int index_br = m_initInfo.HeightmapWidth * j + (i + 8);
			const int index_ul = m_initInfo.HeightmapWidth * (j + 8) + i;
			const int index_ur = m_initInfo.HeightmapWidth * (j + 8) + (i + 8);

			const float2 bl_uv(
				texture_coordinate[index_bl].x, texture_coordinate[index_bl].y
				);
			const float2 br_uv(
				(texture_coordinate[index_br].x == 0.0f ? 1.0f : texture_coordinate[index_br].x),
				texture_coordinate[index_br].y
				);
			const float2 ul_uv(
				texture_coordinate[index_ul].x,
				(texture_coordinate[index_ul].y == 1.0f ? 0.0f : texture_coordinate[index_ul].y)
				);
			const float2 ur_uv(
				(texture_coordinate[index_ur].x == 0.0f ? 1.0f : texture_coordinate[index_ur].x),
				(texture_coordinate[index_ur].y == 1.0f ? 0.0f : texture_coordinate[index_ur].y)
				);

			Vector3 bl(i * m_initInfo.CellSpacing, m_HeightMap[index_bl] * m_initInfo.CellSpacing, j* m_initInfo.CellSpacing);
			Vector3 br((i + 8)* m_initInfo.CellSpacing, m_HeightMap[index_br] * m_initInfo.CellSpacing, j* m_initInfo.CellSpacing);
			Vector3 ul(i* m_initInfo.CellSpacing, m_HeightMap[index_ul] * m_initInfo.CellSpacing, (j + 8)* m_initInfo.CellSpacing);
			Vector3 ur((i + 8)* m_initInfo.CellSpacing, m_HeightMap[index_ur] * m_initInfo.CellSpacing, (j + 8)* m_initInfo.CellSpacing);

			const int patch_id = j + (i / m_initInfo.CellsPerPatch);
			// bottom left
			{
				vertices[indexCounter].m_pos = bl;
				vertices[indexCounter].m_UV[0] = bl_uv.x;
				vertices[indexCounter].m_UV[1] = bl_uv.y;
				vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x;
				vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y;
				indices[indexCounter] = indexCounter;
				indexCounter++;
			}

			// bottom right
			{
				vertices[indexCounter].m_pos = br;
				vertices[indexCounter].m_UV[0] = br_uv.x;
				vertices[indexCounter].m_UV[1] = br_uv.y;
				vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x;
				vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y;
				indices[indexCounter] = indexCounter;
				indexCounter++;
			}

			// upper left
			{
				vertices[indexCounter].m_pos = ul;
				vertices[indexCounter].m_UV[0] = ul_uv.x;
				vertices[indexCounter].m_UV[1] = ul_uv.y;
				vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x;
				vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y;
				indices[indexCounter] = indexCounter;
				indexCounter++;
			}

			// upper right
			{
				vertices[indexCounter].m_pos = ur;
				vertices[indexCounter].m_UV[0] = ur_uv.x;
				vertices[indexCounter].m_UV[1] = ur_uv.y;
				vertices[indexCounter].m_boundsY[0] = boundsY[patch_id].x;
				vertices[indexCounter].m_boundsY[1] = boundsY[patch_id].y;
				indices[indexCounter] = indexCounter;
				indexCounter++;
			}
		}
	}

	std::string diffuseTxt_filepath = std::string("../Assets/") + diffuseTxt_filename;
	std::string normalTxt_filepath = std::string("../Assets/") + normalTxt_filename;
	std::string heightTxt_filepath = std::string("../Assets/") + heightTxt_filemane;

	MeshData* meshData = new MeshData(vertices, iNumVertices, indices, iNumIndices, sizeof(VertexTerrain));
	meshData->SetBoundingBox(AABB(Vector3(0, 0, 0), Vector3(m_initInfo.HeightmapHeight, 0, m_initInfo.HeightmapWidth)));
	Handle hMeshComp(sizeof(MeshComponent));
	new (hMeshComp) MeshComponent(meshData);
	SceneGraph::GetInstance()->AddComponent((MeshComponent*) hMeshComp.Raw());

	RenderPass* renderPass = new RenderPass;
	renderPass->SetVertexShader("../DEngine/Shaders/VS_terrain.hlsl");
	renderPass->SetHullShader("../DEngine/Shaders/HS_terrain.hlsl");
	renderPass->SetDomainShader("../DEngine/Shaders/DS_terrain.hlsl");
	renderPass->SetPixelShader("../DEngine/Shaders/PS_terrain.hlsl");
	Handle hTexture1(sizeof(Texture));
	new (hTexture1) Texture(Texture::SHADER_RESOURCES, 1, diffuseTxt_filepath.c_str());
	Handle hTexture2(sizeof(Texture));
	new (hTexture2) Texture(Texture::SHADER_RESOURCES, 1, normalTxt_filepath.c_str());
	Handle hTexture3(sizeof(Texture));
	new (hTexture3) Texture(Texture::SHADER_RESOURCES, 1, heightTxt_filepath.c_str());
	renderPass->AddTexture(hTexture1);
	renderPass->AddTexture(hTexture2);
	renderPass->AddTexture(hTexture3);
	renderPass->SetTopology(D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
	renderPass->SetBlendState(State::NULL_STATE);
	renderPass->SetRenderTargets(D3D11Renderer::GetInstance()->m_pRTVArray, 2);
	renderPass->SetDepthStencilView(D3D11Renderer::GetInstance()->m_depth->GetDSV());
	renderPass->SetDepthStencilState(State::DEFAULT_DEPTH_STENCIL_DSS);
	renderPass->SetRasterizerState(State::CULL_BACK_RS);
	((MeshComponent*) hMeshComp.Raw())->m_pMeshData->m_Material.AddPassToTechnique(renderPass);

	GameObject* terrain = new GameObject;
	terrain->AddComponent((Component*) hMeshComp.Raw());

	delete[] vertices;
	delete[] indices;

	return terrain;
}
void EditorBodyControl::PrepareModMatrix(const Vector2 & point)
{
	float32 winx = point.x - touchStart.x;
	float32 winy = point.y - touchStart.y;
	
	Matrix4 modification;
	modification.Identity();

	ArrowsNode* arrowsNode = GetArrowsNode(false);
	if (!arrowsNode)
		return;

	if (GetModificationMode() == ResourceEditor::MODIFY_MOVE)
	{
		Vector3 from, dir;
		GetCursorVectors(&from, &dir, point);
		
		Vector3 currPoint;
		bool result = GetIntersectionVectorWithPlane(from, dir, planeNormal, rotationCenter, currPoint);
		
		if (result)
		{
			
			if (arrowsNode)
			{
				switch (arrowsNode->GetModAxis())
				{
					case ArrowsNode::AXIS_X:
						currPoint.y = startDragPoint.y;
						currPoint.z = startDragPoint.z;
						break;
					case ArrowsNode::AXIS_Y:
						currPoint.x = startDragPoint.x;
						currPoint.z = startDragPoint.z;
						break;
					case ArrowsNode::AXIS_Z:
						currPoint.x = startDragPoint.x;
						currPoint.y = startDragPoint.y;
						break;
                    
					default:
						break;
				}
				modification.CreateTranslation(currPoint - startDragPoint);
			}
		}
	}
	else if (GetModificationMode() == ResourceEditor::MODIFY_ROTATE)
	{
		Matrix4 d;
		switch (arrowsNode->GetModAxis())
		{
			case ArrowsNode::AXIS_X:
			case ArrowsNode::AXIS_Y:
				modification.CreateRotation(vect[arrowsNode->GetModAxis()], winy / 100.0f);
				break;
			case ArrowsNode::AXIS_Z:
				modification.CreateRotation(vect[arrowsNode->GetModAxis()], winx / 100.0f);
				break;
			case ArrowsNode::AXIS_XY:
				modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Y], winy / 100.0f);
				modification *= d;
				break;
			case ArrowsNode::AXIS_YZ:
				modification.CreateRotation(vect[ArrowsNode::AXIS_Y], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f);
				modification *= d;
				break;
			case ArrowsNode::AXIS_XZ:
				modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f);
				modification *= d;
				break;
			default:
				break;
		}
		modification = (translate1 * modification) * translate2;
		
	}
	else if (GetModificationMode() == ResourceEditor::MODIFY_SCALE)
	{
		float kf = winx / 100.0f;
		if (kf < -1.0)
			kf = - kf - 2.0;
		modification.CreateScale(Vector3(1,1,1) + Vector3(1,1,1) * kf);
		modification = (translate1 * modification) * translate2;
	}
	currTransform = startTransform * modification;
}
示例#9
0
void SceneNode::Update(float32 timeElapsed)
{
    inUpdate = true;
	// TODO - move node update to render because any of objects can change params of other objects
	if (nodeAnimations.size() != 0)
	{
		Quaternion blendedRotation;
		Vector3 blendedTranslation;
		float32 accumWeight = 0.0f;
		std::deque<SceneNodeAnimation*>::const_iterator end = nodeAnimations.end();
		for (std::deque<SceneNodeAnimation*>::iterator it = nodeAnimations.begin(); it != end; ++it)
		{
			SceneNodeAnimation * animation = *it;
			SceneNodeAnimationKey & key = animation->Intepolate(animation->GetCurrentTime());
			if (accumWeight == 0.0f)
			{
				blendedTranslation = key.translation;
				blendedRotation = key.rotation;
				accumWeight = animation->weight;
			}else
			{
				float32 factor = animation->weight / (accumWeight + animation->weight);
				accumWeight += accumWeight;
				blendedTranslation.Lerp(blendedTranslation, key.translation, factor);
				blendedRotation.Slerp(blendedRotation, key.rotation, factor);
			}
			//key.GetMatrix(localTransform);
		}
		Matrix4 localTransformTrans;
		Matrix4 localTransformRot;
		Matrix4 localTransformFinal;
		localTransformTrans.CreateTranslation(blendedTranslation);
		localTransformRot = blendedRotation.GetMatrix();
		
		localTransform = localTransformRot * localTransformTrans;
		
//		if (nodeAnimations.size() != 1)
//		{
//			printf("-- blended node: %s\n", name.c_str());
//			std::deque<SceneNodeAnimation*>::const_iterator end = nodeAnimations.end();
//			for (std::deque<SceneNodeAnimation*>::iterator it = nodeAnimations.begin(); it != end; ++it)
//			{
//				SceneNodeAnimation * animation = *it;
//				printf(">>> blend: %s wei: %f inDelay: %f\n", animation->GetParent()->name.c_str(), animation->weight, animation->delayTime);
//			}
//		}
	}
	
    // update world transform only in case if 
    if (!(flags & NODE_WORLD_MATRIX_ACTUAL))  
	{
		if (parent)
        {
            worldTransform = localTransform * parent->worldTransform;
        }else 
		{
            worldTransform = localTransform;
        }
        
        // need propagate changes to child nodes
        flags |= NODE_WORLD_MATRIX_ACTUAL;
        uint32 size = (uint32)childs.size();
        for (uint32 c = 0; c < size; ++c)
        {
            childs[c]->InvalidateLocalTransform();
            childs[c]->Update(timeElapsed);
        }
        
	}
    else 
    {
        uint32 size = (uint32)childs.size();
        for (uint32 c = 0; c < size; ++c)
        {
            childs[c]->Update(timeElapsed);
        }
    }

	//printf("- node: %s tr: %f %f %f\n", name.c_str(), localTransform.data[12], localTransform.data[13], localTransform.data[14]); 
	
	
	inUpdate = false;

    if (!removedCache.empty()) 
    {
        for (std::deque<SceneNode*>::iterator t = removedCache.begin(); t != removedCache.end(); ++t)
        {
            RemoveNode(*t);
        }
        removedCache.clear();
    }
}