예제 #1
0
NzVector3f NzTerrainQuadTree::GetVertexPosition(const NzTerrainNodeID& nodeID, int x, int y)
{
    ///Les terrains sont centrées en 0
    ///Avec le système de node
    ///Leur position "affichée" peut changer à l'exécution
    ///La configuration ne peut donc pas contenir la position du terrain, ce doit être géré par lee système de node
    ///Néanmoins, pour un terrain infini, les quadtree autres que le central doivent avoir un offset
    ///Par conséquent la configuration contient la taille du terrain en floattant
    ///Et un offset (x,y) en coordonnées entières

    //Note : nodeID.depth should never be < 0
    float power = 1.f/(1 << nodeID.depth);
    NzVector3f position;

    switch(m_type)
    {
        case nzQuadTreeType_terrain:
            position.x = m_terrainConfiguration.terrainSize * (m_commonConfiguration.x_offset + (x * 0.25f + nodeID.locx) * power);
            position.z = m_terrainConfiguration.terrainSize * (m_commonConfiguration.y_offset + (y * 0.25f + nodeID.locy) * power);
            position.y = m_heightSource2D->GetHeight(position.x,position.z) * m_commonConfiguration.maxHeight;
            return m_rotationMatrix.Transform(position);
        break;

        case nzQuadTreeType_planet:
        default:

            //Les coordonnées d'un plan
            position.x = 2.f * (x * 0.25f + nodeID.locx) / std::pow(2,nodeID.depth) - 1.f;
            position.y = 1.f;
            position.z = 2.f * (y * 0.25f + nodeID.locy) / std::pow(2,nodeID.depth) - 1.f;

            //On normalise le vecteur pour obtenir une sphère
            position.Normalize();
            position *= m_planetConfiguration.planetRadius;

            //On l'oriente correctement
            position = m_rotationMatrix.Transform(position);

            //Et applique la hauteur en cette position (A Optimiser)
            float height = m_heightSource3D->GetHeight(position.x, position.y, position.z) * m_commonConfiguration.maxHeight;
            position.Normalize();
            position *= m_planetConfiguration.planetRadius + height;

            ///position += m_commonConfiguration.center;

            return position;

        break;
    }

}
예제 #2
0
void NzPatch::ComputeNormals()
{
    //top, right, bottom, left
    NzVector3f v1,v2,v3,v4;
    NzVector3f v12;
    NzVector3f v23;
    NzVector3f v34;
    NzVector3f v41;
    NzVector3f sum;

    unsigned int i0,j0;

    unsigned int hx,hy;
    NzVector2i normalLocation;

    for(unsigned int j(0) ; j < 5 ; ++j)
        for(unsigned int i(0) ; i < 5 ; ++i)
        {
            i0 = i + 1;
            j0 = j + 1;

            normalLocation.x = (m_id.locx * 4 + i) * std::pow(2,NAZARA_DYNATERRAIN_MAXIMUM_TERRAIN_DEPTH - m_id.depth);
            normalLocation.y = (m_id.locy * 4 + j) * std::pow(2,NAZARA_DYNATERRAIN_MAXIMUM_TERRAIN_DEPTH - m_id.depth);

            if(m_data->normalsManager->IsNormalSet(normalLocation))
            {
                m_data->normalsManager->GetNormal(normalLocation,sum);
            }
            else
            {
                //Compute four vectors
                v1 = m_vertices[i0+1][j0  ].GetPosition();
                v2 = m_vertices[i0  ][j0+1].GetPosition();
                v3 = m_vertices[i0-1][j0  ].GetPosition();
                v4 = m_vertices[i0+1][j0-1].GetPosition();

                v12 = v1.CrossProduct(v2);
                v23 = v2.CrossProduct(v3);
                v34 = v3.CrossProduct(v4);
                v41 = v4.CrossProduct(v1);

                sum = v12 + v23 + v34 + v41;
                sum.Normalize();

                if(sum.y < 0.f)
                    sum *= -1.f;

                m_data->normalsManager->SetNormal(normalLocation,sum,this);
            }
            m_data->normalsManager->AddNormalListenner(normalLocation,this);
            m_vertexNormals.at(i+5*j) = sum;
        }
}
예제 #3
0
void NzSubMesh::GenerateTangents()
{
	NzTriangleIterator iterator(this);
	do
	{
		NzVector3f pos0 = iterator.GetPosition(0);
		NzVector2f uv0 = iterator.GetTexCoord(0);

		NzVector3f dv[2];
		dv[0] = iterator.GetPosition(1) - pos0;
		dv[1] = iterator.GetPosition(2) - pos0;

		NzVector2f duv[2];
		duv[0] = iterator.GetTexCoord(1) - uv0;
		duv[1] = iterator.GetTexCoord(2) - uv0;

		float ds[2];
		ds[0] = iterator.GetTexCoord(1).x - uv0.x;
		ds[1] = iterator.GetTexCoord(2).x - uv0.x;

		NzVector3f ppt;
		ppt.x = ds[0]*dv[1].x - dv[0].x*ds[1];
		ppt.y = ds[0]*dv[1].y - dv[0].y*ds[1];
		ppt.z = ds[0]*dv[1].z - dv[0].z*ds[1];
		ppt.Normalize();

		for (unsigned int i = 0; i < 3; ++i)
		{
			NzVector3f normal = iterator.GetNormal(i);
			float d = ppt.DotProduct(normal);

			NzVector3f tangent = ppt - (d * normal);

			iterator.SetTangent(i, tangent);
		}
	}
	while (iterator.Advance());
}