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 (); }
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 (); }
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; }
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; }
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(); }
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(); }
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 (); }
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 (); } }