예제 #1
0
DemoMesh::DemoMesh(const DemoMesh& mesh)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	AllocVertexData(mesh.m_vertexCount);
	memcpy (m_vertex, mesh.m_vertex, 3 * m_vertexCount * sizeof (dFloat));
	memcpy (m_normal, mesh.m_normal, 3 * m_vertexCount * sizeof (dFloat));
	memcpy (m_uv, mesh.m_uv, 2 * m_vertexCount * sizeof (dFloat));

	for (dListNode* nodes = mesh.GetFirst(); nodes; nodes = nodes->GetNext()) {
		DemoSubMesh* const segment = AddSubMesh();
		DemoSubMesh& srcSegment = nodes->GetInfo();

		segment->AllocIndexData (srcSegment.m_indexCount);
		memcpy (segment->m_indexes, srcSegment.m_indexes, srcSegment.m_indexCount * sizeof (unsigned));

		segment->m_shiness = srcSegment.m_shiness;
		segment->m_ambient = srcSegment.m_ambient;
		segment->m_diffuse = srcSegment.m_diffuse;
		segment->m_specular = srcSegment.m_specular;
		segment->m_textureHandle = srcSegment.m_textureHandle;
		segment->m_textureName = srcSegment.m_textureName;
		if (segment->m_textureHandle) {
			AddTextureRef (srcSegment.m_textureHandle);
		}
	}

	// see if this mesh can be optimized
	OptimizeForRender ();
}
예제 #2
0
DemoMesh::DemoMesh(NewtonMesh* const mesh)
	:DemoMeshInterface()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	// extract vertex data  from the newton mesh		
	AllocVertexData(NewtonMeshGetPointCount (mesh));

	// a valid newton mesh always has a vertex channel
	NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex);
	if (NewtonMeshHasNormalChannel(mesh)) {
		NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal);
	}
	if (NewtonMeshHasUV0Channel(mesh)) {
		NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv);
	}

	// extract the materials index array for mesh
	void* const meshCookie = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, meshCookie); handle != -1; handle = NewtonMeshNextMaterial (mesh, meshCookie, handle)) {
		int textureId = NewtonMeshMaterialGetMaterial (mesh, meshCookie, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, meshCookie, handle); 
		DemoSubMesh* const segment = AddSubMesh();

		segment->m_shiness = 1.0f;
		segment->m_ambient = dVector (0.8f, 0.8f, 0.8f, 1.0f);
		segment->m_diffuse = dVector (0.8f, 0.8f, 0.8f, 1.0f);
		segment->m_specular = dVector (0.0f, 0.0f, 0.0f, 1.0f);
		segment->m_textureHandle = textureId;

		segment->AllocIndexData (indexCount);
		// for 16 bit indices meshes
		//NewtonMeshMaterialGetIndexStreamShort (mesh, meshCookie, handle, (short int*)segment->m_indexes); 

		// for 32 bit indices mesh
		NewtonMeshMaterialGetIndexStream (mesh, meshCookie, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, meshCookie); 

	// see if this mesh can be optimized
	OptimizeForRender ();
}
예제 #3
0
	SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params)
	{
		#if NAZARA_UTILITY_SAFE
		if (!m_impl)
		{
			NazaraError("Mesh not created");
			return nullptr;
		}

		if (m_impl->animationType != AnimationType_Static)
		{
			NazaraError("Mesh must be static");
			return nullptr;
		}

		if (!params.IsValid())
		{
			NazaraError("Parameters must be valid");
			return nullptr;
		}
		#endif

		Boxf aabb;
		IndexBufferRef indexBuffer;
		VertexBufferRef vertexBuffer;

		Matrix4f matrix(primitive.matrix);
		matrix.ApplyScale(params.scale);

		VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent);

		switch (primitive.type)
		{
			case PrimitiveType_Box:
			{
				unsigned int indexCount;
				unsigned int vertexCount;
				ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount);

				indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
				vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

				VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly);

				VertexPointers pointers;
				pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
				pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
				pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
				pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

				IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
				GenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
				break;
			}

			case PrimitiveType_Cone:
			{
				unsigned int indexCount;
				unsigned int vertexCount;
				ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount);

				indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
				vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

				VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly);

				VertexPointers pointers;
				pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
				pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
				pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
				pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

				IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
				GenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
				break;
			}

			case PrimitiveType_Plane:
			{
				unsigned int indexCount;
				unsigned int vertexCount;
				ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount);

				indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
				vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

				VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly);

				VertexPointers pointers;
				pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
				pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
				pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
				pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

				IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
				GeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
				break;
			}

			case PrimitiveType_Sphere:
			{
				switch (primitive.sphere.type)
				{
					case SphereType_Cubic:
					{
						unsigned int indexCount;
						unsigned int vertexCount;
						ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount);

						indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
						vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

						VertexMapper vertexMapper(vertexBuffer, BufferAccess_ReadWrite);

						VertexPointers pointers;
						pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
						pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
						pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
						pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

						IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
						GenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
						break;
					}

					case SphereType_Ico:
					{
						unsigned int indexCount;
						unsigned int vertexCount;
						ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount);

						indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
						vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

						VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly);

						VertexPointers pointers;
						pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
						pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
						pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
						pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

						IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
						GenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
						break;
					}

					case SphereType_UV:
					{
						unsigned int indexCount;
						unsigned int vertexCount;
						ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount);

						indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.storage, BufferUsage_Static);
						vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static);

						VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly);

						VertexPointers pointers;
						pointers.normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
						pointers.positionPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
						pointers.tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
						pointers.uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);

						IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
						GenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb);
						break;
					}
				}
				break;
			}
		}

		StaticMeshRef subMesh = StaticMesh::New(this);
		if (!subMesh->Create(vertexBuffer))
		{
			NazaraError("Failed to create StaticMesh");
			return nullptr;
		}

		if (params.optimizeIndexBuffers)
			indexBuffer->Optimize();

		subMesh->SetAABB(aabb);
		subMesh->SetIndexBuffer(indexBuffer);

		AddSubMesh(subMesh);
		return subMesh;
	}
예제 #4
0
HRESULT KG3DMeshBone::Attach(KG3DModel* pModel, KG3DScene* pScene)
{
    HRESULT hResult  = E_FAIL;
    HRESULT hRetCode = E_FAIL;

    KG3DModelST* pModelST  = NULL;
    KG3DModel *pModelInVector = NULL;
    
    KG_PROCESS_ERROR(pModel);
    KG_PROCESS_ERROR(pScene);


    m_pAttachScene = pScene;
    m_pAttachModel = pModel;

    m_matWorld = m_pAttachModel->m_matWorld;
    m_vecSubMeshInfo.clear();

    SAFE_RELEASE(m_pSysMesh);
    pModelST = dynamic_cast<KG3DModelST*>(pModel);
    if (pModelST)
    {
        KG3DBip* pBip = const_cast<KG3DBip*>(pModelST->GetBip());
        int nNumBonew = 0;
       
        KG_PROCESS_ERROR(pBip);
        nNumBonew = pBip->GetNumBones();
        for (int i = 0; i < nNumBonew; i++)
        {
            int nParentIndex = 0;
            D3DXVECTOR3 v1;
            D3DXVECTOR3 v2;
            D3DXMATRIX matObj = pBip->GetBoneObjMatrix(i);
            v1.x = matObj._41;
            v1.y = matObj._42;
            v1.z = matObj._43;
            nParentIndex = pBip->GetParentIndex(i);
            matObj = pBip->GetBoneObjMatrix(nParentIndex);
            v2.x = matObj._41;
            v2.y = matObj._42;
            v2.z = matObj._43;

            if (v1 == v2)
                continue;

            AddSubMesh(v2, v1, const_cast<TCHAR*>(pBip->GetBoneName(i)), 0);
        }

        int nCount = pModelST->GetNumModel();

        for (int s = 0; s < nCount; s++)
        {
            IKG3DModel *piModel = NULL;
            pModelST->GetModel(s, &piModel);

            pModelInVector = dynamic_cast<KG3DModel *>(piModel);
            KGLOG_PROCESS_ERROR(pModelInVector);
            
            KG3DMesh *pMesh = pModelInVector->GetMesh();
            if (NULL == pMesh)
                continue;
            DWORD dwNumSocket = 0;
            dwNumSocket = pMesh->m_dwNumSocket;
            for (DWORD i = 0; i < dwNumSocket; i++)
            {
                D3DXVECTOR3 v1 = D3DXVECTOR3(-15.0f, 0.0f, 0.0f);
                D3DXVECTOR3 v2 = D3DXVECTOR3( 15.0f, 0.0f, 0.0f);
                //D3DXMATRIX* pMatSocket = pMesh->GetSocketMatrix(i);
                D3DXMATRIX matSocket;
                pModelInVector->GetSocketMatrix(i, matSocket);
                D3DXVec3TransformCoord(&v1, &v1, &matSocket);
                D3DXVec3TransformCoord(&v2, &v2, &matSocket);

                AddSubMesh(
                    v2, v1,
                    pMesh->m_pSockets[i].strSocketName,
                    2
                );
            }
            //pMesh->Release();//原来GetMesh是加引用计数的,现在不加
        }

        {
            D3DXVECTOR3 v1 = D3DXVECTOR3(0.0f,  10.0f, 0.0f);
            D3DXVECTOR3 v2 = D3DXVECTOR3(0.0f,   0.0f, 0.0f);
            //D3DXVec3TransformCoord(&v1, &v1, &pModelST->m_matWorld);
            //D3DXVec3TransformCoord(&v2, &v2, &pModelST->m_matWorld);

            AddSubMesh(v2, v1, TEXT("Origin"), 0);
       
        }
    }
    else
    {
        KG3DMesh* pMesh = pModel->GetMesh();
		KG_PROCESS_ERROR(NULL != pMesh);

        int nNumBonew = 0;

        nNumBonew = pMesh->GetNumBones();
        for (int i = 0; i < nNumBonew; i++)
        {
            D3DXVECTOR3 v1;
            D3DXVECTOR3 v2;
            D3DXMATRIX matObj = pModel->m_pBoneMatricesForRender[i];
            v1.x = matObj._41;
            v1.y = matObj._42;
            v1.z = matObj._43;

            if (pMesh->m_pBoneInfo[i].dwNumChild > 0)
            {
                for (DWORD s = 0; s < pMesh->m_pBoneInfo[i].dwNumChild; ++s)
                {
                    DWORD childIndex = pMesh->m_pBoneInfo[i].dwChildIndex[s];
                    matObj = pModel->m_pBoneMatricesForRender[childIndex];
                    v2.x = matObj._41;
                    v2.y = matObj._42;
                    v2.z = matObj._43;

                    if (v1 == v2)
                        continue;

                    AddSubMesh(v1, v2, const_cast<TCHAR*>(pMesh->GetBoneName(i)), 0);
                }
            }
            else
            {
                D3DXVECTOR3 v = D3DXVECTOR3(matObj._11, matObj._12, matObj._13);
                v2 = v1 + v * 10.f;
                AddSubMesh(v1, v2, const_cast<TCHAR*>(pMesh->GetBoneName(i)), 0);
            }

            /*
            int nParentIndex = 0;
            D3DXVECTOR3 v1;
            D3DXVECTOR3 v2;
            D3DXMATRIX matObj = pModel->m_pBoneMatricesForRender[i];// pBip->GetBoneObjMatrix(i);
            v1.x = matObj._41;
            v1.y = matObj._42;
            v1.z = matObj._43;
            nParentIndex = static_cast<int>(pMesh->m_pBoneInfo[i].dwParentIndex);
            matObj = pModel->m_pBoneMatricesForRender[nParentIndex];
            v2.x = matObj._41;
            v2.y = matObj._42;
            v2.z = matObj._43;

            if (v1 == v2)
                continue;

            AddSubMesh(v2, v1, const_cast<TCHAR*>(pMesh->GetBoneName(i)), 0);
            */
        }       
        
        DWORD dwNumSocket = 0;
        dwNumSocket = pMesh->m_dwNumSocket;
        for (DWORD i = 0; i < dwNumSocket; i++)
        {
            D3DXVECTOR3 v1 = D3DXVECTOR3(-15.0f, 0.0f, 0.0f);
            D3DXVECTOR3 v2 = D3DXVECTOR3( 15.0f, 0.0f, 0.0f);
            D3DXMATRIX* pMatSocket = pMesh->GetSocketMatrix(i);
            D3DXVec3TransformCoord(&v1, &v1, pMatSocket);
            D3DXVec3TransformCoord(&v2, &v2, pMatSocket);

            AddSubMesh(
                v2, v1,
                pMesh->m_pSockets[i].strSocketName,
                2
                );
        }
    }

    hRetCode = _CreateMesh();
    KGLOG_COM_PROCESS_ERROR(hRetCode);

    hResult = S_OK;
Exit0:
    return hResult;
}
예제 #5
0
NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params)
{
	#if NAZARA_UTILITY_SAFE
	if (!m_impl)
	{
		NazaraError("Mesh not created");
		return nullptr;
	}

	if (m_impl->animationType != nzAnimationType_Static)
	{
		NazaraError("Mesh must be static");
		return nullptr;
	}

	if (!params.IsValid())
	{
		NazaraError("Parameters must be valid");
		return nullptr;
	}
	#endif

	NzBoxf aabb;
	std::unique_ptr<NzIndexBuffer> indexBuffer;
	std::unique_ptr<NzVertexBuffer> vertexBuffer;

	NzMatrix4f matrix(primitive.matrix);
	matrix.ApplyScale(params.scale);

	NzVertexDeclaration* declaration = NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent);

	switch (primitive.type)
	{
		case nzPrimitiveType_Box:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Cone:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Plane:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Sphere:
		{
			switch (primitive.sphere.type)
			{
				case nzSphereType_Cubic:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}

				case nzSphereType_Ico:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}

				case nzSphereType_UV:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}
			}
			break;
		}
	}

	std::unique_ptr<NzStaticMesh> subMesh(new NzStaticMesh(this));
	if (!subMesh->Create(vertexBuffer.get()))
	{
		NazaraError("Failed to create StaticMesh");
		return nullptr;
	}
	vertexBuffer.release();

	if (params.optimizeIndexBuffers)
		indexBuffer->Optimize();

	subMesh->SetIndexBuffer(indexBuffer.get());
	indexBuffer.release();

	subMesh->SetAABB(aabb);
	AddSubMesh(subMesh.get());

	return subMesh.release();
}
예제 #6
0
DemoMesh::DemoMesh(const char* const name, dFloat* const elevation, int size, dFloat cellSize, dFloat texelsDensity, int tileSize)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	dFloat* elevationMap[4096];
	dVector* normalMap[4096];
	dFloat* const normalsPtr = new dFloat [size * size * 4];
//	dVector* const normals = new dVector [size * size];
	dVector* const normals = (dVector*)normalsPtr;

	for (int i = 0; i < size; i ++) {
		elevationMap[i] = &elevation[i * size];
		normalMap[i] = &normals[i * size];
	}

	memset (normals, 0, (size * size) * sizeof (dVector));
	for (int z = 0; z < size - 1; z ++) {
		for (int x = 0; x < size - 1; x ++) {
			dVector p0 ((x + 0) * cellSize, elevationMap[z + 0][x + 0], (z + 0) * cellSize);
			dVector p1 ((x + 1) * cellSize, elevationMap[z + 0][x + 1], (z + 0) * cellSize);
			dVector p2 ((x + 1) * cellSize, elevationMap[z + 1][x + 1], (z + 1) * cellSize);
			dVector p3 ((x + 0) * cellSize, elevationMap[z + 1][x + 0], (z + 1) * cellSize);

			dVector e10 (p1 - p0);
			dVector e20 (p2 - p0);
			dVector n0 (e20.CrossProduct(e10));
			n0 = n0.Scale ( 1.0f / dSqrt (n0.DotProduct3(n0)));
			normalMap [z + 0][x + 0] += n0;
			normalMap [z + 0][x + 1] += n0;
			normalMap [z + 1][x + 1] += n0;

			dVector e30 (p3 - p0);
			dVector n1 (e30.CrossProduct(e20));
			n1 = n1.Scale ( 1.0f / dSqrt (n1.DotProduct3(n1)));
			normalMap [z + 0][x + 0] += n1;
			normalMap [z + 1][x + 0] += n1;
			normalMap [z + 1][x + 1] += n1;
		}
	}

	for (int i = 0; i < size * size; i ++) {
		normals[i] = normals[i].Scale (1.0f / dSqrt (normals[i].DotProduct3(normals[i])));
	}
	
	AllocVertexData (size * size);

	dFloat* const vertex = m_vertex;
	dFloat* const normal = m_normal;
	dFloat* const uv = m_uv;

	int index0 = 0;
	for (int z = 0; z < size; z ++) {
		for (int x = 0; x < size; x ++) {
			vertex[index0 * 3 + 0] = x * cellSize;
			vertex[index0 * 3 + 1] = elevationMap[z][x];
			vertex[index0 * 3 + 2] = z * cellSize;

			normal[index0 * 3 + 0] = normalMap[z][x].m_x;
			normal[index0 * 3 + 1] = normalMap[z][x].m_y;
			normal[index0 * 3 + 2] = normalMap[z][x].m_z;

			uv[index0 * 2 + 0] = x * texelsDensity;
			uv[index0 * 2 + 1] = z * texelsDensity;
			index0 ++;
		}
	}

	int segmentsCount = (size - 1) / tileSize;
	for (int z0 = 0; z0 < segmentsCount; z0 ++) {
		int z = z0 * tileSize;
		for (int x0 = 0; x0 < segmentsCount; x0 ++ ) {
			int x = x0 * tileSize;

			DemoSubMesh* const tile = AddSubMesh();
			tile->AllocIndexData (tileSize * tileSize * 6);
			unsigned* const indexes = tile->m_indexes;

			//strcpy (tile->m_textureName, "grassanddirt.tga");
			tile->m_textureName = "grassanddirt.tga";
			tile->m_textureHandle = LoadTexture(tile->m_textureName.GetStr());

			int index1 = 0;
			int x1 = x + tileSize;
			int z1 = z + tileSize;
			for (int z2 = z; z2 < z1; z2 ++) {
				for (int x2 = x; x2 < x1; x2 ++) {
					int i0 = x2 + 0 + (z2 + 0) * size;
					int i1 = x2 + 1 + (z2 + 0) * size;
					int i2 = x2 + 1 + (z2 + 1) * size;
					int i3 = x2 + 0 + (z2 + 1) * size;

					indexes[index1 + 0] = i0;
					indexes[index1 + 1] = i2;
					indexes[index1 + 2] = i1;

					indexes[index1 + 3] = i0;
					indexes[index1 + 4] = i3;
					indexes[index1 + 5] = i2;
					index1 += 6;
				}
			}
		}
	}
	delete[] normalsPtr; 
	OptimizeForRender();
}
예제 #7
0
DemoMesh::DemoMesh(const char* const name, const NewtonCollision* const collision, const char* const texture0, const char* const texture1, const char* const texture2, dFloat opacity, const dMatrix& uvMatrix)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	// create a helper mesh from the collision collision
	NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision);

	// apply the vertex normals
	NewtonMeshCalculateVertexNormals(mesh, 30.0f * dDegreeToRad);

	dMatrix aligmentUV(uvMatrix);
//	NewtonCollisionGetMatrix(collision, &aligmentUV[0][0]);
	aligmentUV = aligmentUV.Inverse();

	// apply uv projections
	NewtonCollisionInfoRecord info;
	NewtonCollisionGetInfo (collision, &info);
	switch (info.m_collisionType) 
	{
		case SERIALIZE_ID_SPHERE:
		{
			NewtonMeshApplySphericalMapping(mesh, LoadTexture (texture0), &aligmentUV[0][0]);
			break;
		}

		case SERIALIZE_ID_CONE:
		case SERIALIZE_ID_CAPSULE:
		case SERIALIZE_ID_CYLINDER:
		case SERIALIZE_ID_CHAMFERCYLINDER:
		{
			//NewtonMeshApplySphericalMapping(mesh, LoadTexture(texture0));
			NewtonMeshApplyCylindricalMapping(mesh, LoadTexture(texture0), LoadTexture(texture1), &aligmentUV[0][0]);
			break;
		}

		default:
		{
			int tex0 = LoadTexture(texture0);
			int tex1 = LoadTexture(texture1);
			int tex2 = LoadTexture(texture2);
			NewtonMeshApplyBoxMapping(mesh, tex0, tex1, tex2, &aligmentUV[0][0]);
			break;
		}
	}

	// extract vertex data  from the newton mesh		
	int vertexCount = NewtonMeshGetPointCount (mesh); 
	AllocVertexData(vertexCount);
	NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex);
	NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal);
	NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv);

	// extract the materials index array for mesh
	void* const geometryHandle = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial (mesh, geometryHandle, handle)) {
		int material = NewtonMeshMaterialGetMaterial (mesh, geometryHandle, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, geometryHandle, handle); 

		DemoSubMesh* const segment = AddSubMesh();

		segment->m_textureHandle = (GLuint)material;
		segment->SetOpacity(opacity);

		segment->AllocIndexData (indexCount);
		NewtonMeshMaterialGetIndexStream (mesh, geometryHandle, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, geometryHandle); 

	// destroy helper mesh
	NewtonMeshDestroy(mesh);

	// optimize this mesh for hardware buffers if possible
	OptimizeForRender ();
}
예제 #8
0
DemoMesh::DemoMesh(const dScene* const scene, dScene::dTreeNode* const meshNode)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)
	,m_optimizedTransparentDiplayList(0)
{
	dMeshNodeInfo* const meshInfo = (dMeshNodeInfo*)scene->GetInfoFromNode(meshNode);
	m_name = meshInfo->GetName();
	
	NewtonMesh* const mesh = meshInfo->GetMesh();

	// extract vertex data  from the newton mesh		
	AllocVertexData(NewtonMeshGetPointCount (mesh));
	NewtonMeshGetVertexChannel (mesh, 3 * sizeof (dFloat), (dFloat*) m_vertex);
	NewtonMeshGetNormalChannel (mesh, 3 * sizeof (dFloat), (dFloat*) m_normal);
	NewtonMeshGetUV0Channel (mesh, 2 * sizeof (dFloat), (dFloat*) m_uv);

	// bake the matrix into the vertex array
	dMatrix matrix (meshInfo->GetPivotMatrix());
	matrix.TransformTriplex(m_vertex, 3 * sizeof (dFloat), m_vertex, 3 * sizeof (dFloat), m_vertexCount);
	matrix.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f);
	matrix = (matrix.Inverse4x4()).Transpose();
	matrix.TransformTriplex(m_normal, 3 * sizeof (dFloat), m_normal, 3 * sizeof (dFloat), m_vertexCount);

	bool hasModifiers = false;
	dTree<dScene::dTreeNode*, dCRCTYPE> materialMap;
	for (void* ptr = scene->GetFirstChildLink(meshNode); ptr; ptr = scene->GetNextChildLink (meshNode, ptr)) {
		dScene::dTreeNode* const node = scene->GetNodeFromLink(ptr);
		dNodeInfo* const info = scene->GetInfoFromNode(node);
		if (info->GetTypeId() == dMaterialNodeInfo::GetRttiType()) {
			dMaterialNodeInfo* const material = (dMaterialNodeInfo*)info;
			dCRCTYPE id = material->GetId();
			materialMap.Insert(node, id);
		} else if (info->IsType(dGeometryNodeModifierInfo::GetRttiType())) {
			hasModifiers = true;
		}
	}

	// extract the materials index array for mesh
	void* const meshCookie = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, meshCookie); handle != -1; handle = NewtonMeshNextMaterial (mesh, meshCookie, handle)) {
		int materialIndex = NewtonMeshMaterialGetMaterial (mesh, meshCookie, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, meshCookie, handle); 
		DemoSubMesh* const segment = AddSubMesh();

		dTree<dScene::dTreeNode*, dCRCTYPE>::dTreeNode* matNodeCache = materialMap.Find(materialIndex);
		if (matNodeCache) {
			dScene::dTreeNode* const matNode = matNodeCache->GetInfo();
			dMaterialNodeInfo* const material = (dMaterialNodeInfo*) scene->GetInfoFromNode(matNode);

			if (material->GetDiffuseTextId() != -1) {
				dScene::dTreeNode* const node = scene->FindTextureByTextId(matNode, material->GetDiffuseTextId());
				dAssert (node);
				if (node) {
					dTextureNodeInfo* const texture = (dTextureNodeInfo*)scene->GetInfoFromNode(node);
					segment->m_textureHandle = LoadTexture(texture->GetPathName());
					segment->m_textureName = texture->GetPathName();
				}
			}
			segment->m_shiness = material->GetShininess();
			segment->m_ambient = material->GetAmbientColor();
			segment->m_diffuse = material->GetDiffuseColor();
			segment->m_specular = material->GetSpecularColor();
			segment->SetOpacity(material->GetOpacity());
		}

		segment->AllocIndexData (indexCount);
		// for 16 bit indices meshes
		//NewtonMeshMaterialGetIndexStreamShort (mesh, meshCookie, handle, (short int*)segment->m_indexes); 

		// for 32 bit indices mesh
		NewtonMeshMaterialGetIndexStream (mesh, meshCookie, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, meshCookie); 

	if (!hasModifiers) {
		// see if this mesh can be optimized
		OptimizeForRender ();
	}
}