void TaxiPathGraph::Initialize()
{
    if (GetVertexCount() > 0)
        return;

    std::vector<std::pair<edge, EdgeCost>> edges;

    // Initialize here
    for (TaxiPathEntry const* path : sTaxiPathStore)
    {
        TaxiNodesEntry const* from = sTaxiNodesStore.LookupEntry(path->From);
        TaxiNodesEntry const* to = sTaxiNodesStore.LookupEntry(path->To);
        if (from && to && from->Flags & (TAXI_NODE_FLAG_ALLIANCE | TAXI_NODE_FLAG_HORDE) && to->Flags & (TAXI_NODE_FLAG_ALLIANCE | TAXI_NODE_FLAG_HORDE))
            AddVerticeAndEdgeFromNodeInfo(from, to, path->ID, edges);
    }

    // create graph
    m_graph = Graph(GetVertexCount());
    WeightMap weightmap = boost::get(boost::edge_weight, m_graph);

    for (std::size_t j = 0; j < edges.size(); ++j)
    {
        edge_descriptor e = boost::add_edge(edges[j].first.first, edges[j].first.second, m_graph).first;
        weightmap[e] = edges[j].second;
    }
}
示例#2
0
void AasRenderer::RenderGeometryShadow(gfx::AnimatedModel * model, 
	const gfx::AnimatedModelParams & params, 
	const gfx::Light3d & globalLight,
	float alpha)
{
	
	// Find or create render caching data for the submesh
	auto &renderData = mRenderDataCache[model->GetHandle()];
	if (!renderData) {
		renderData = std::make_unique<AasRenderData>();
	}

	mDevice.SetMaterial(mGeometryShadowMaterial);

	auto d3d = mDevice.GetDevice();
	d3d->SetVertexShaderConstantF(0, &mDevice.GetCamera().GetViewProj()._11, 4);
	d3d->SetVertexShaderConstantF(4, &globalLight.dir.x, 1);
	XMFLOAT4 floats{ params.offsetZ, 0, 0, 0 };
	d3d->SetVertexShaderConstantF(5, &floats.x, 1);
	floats.x = alpha;
	d3d->SetVertexShaderConstantF(6, &floats.x, 1);

	auto materialIds(model->GetSubmeshes());
	for (size_t i = 0; i < materialIds.size(); ++i) {
		auto submesh(model->GetSubmesh(params, i));
		
		auto &submeshData = GetSubmeshData(*renderData, i, *submesh);
		submeshData.binding.Bind();
				
		d3d->SetIndices(submeshData.idxBuffer->GetBuffer());
		D3DLOG(d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, submesh->GetVertexCount(), 0, submesh->GetPrimitiveCount()));
	}

}
示例#3
0
unsigned int NzSubMesh::GetTriangleCount() const
{
	const NzIndexBuffer* indexBuffer = GetIndexBuffer();
	unsigned int indexCount;
	if (indexBuffer)
		indexCount = indexBuffer->GetIndexCount();
	else
		indexCount = GetVertexCount();

	switch (m_primitiveMode)
	{
		case nzPrimitiveMode_LineList:
		case nzPrimitiveMode_LineStrip:
		case nzPrimitiveMode_PointList:
			return 0;

		case nzPrimitiveMode_TriangleFan:
			return (indexCount - 1) / 2;

		case nzPrimitiveMode_TriangleList:
			return indexCount / 3;

		case nzPrimitiveMode_TriangleStrip:
			return indexCount - 2;
	}

	NazaraError("Primitive mode not handled (0x" + NzString::Number(m_primitiveMode, 16) + ')');
	return 0;
}
示例#4
0
文件: Mesh.cpp 项目: tecan/Luna
// TODO: exploit a better algorithm, use vertex hash table/map.
//
void mxRenderMesh::WeldVertices()
{
	TArray< mxVertex >	newVerts;
	newVerts.Resize( GetVertexCount() );

	for ( u32 triIdx = 0; triIdx < GetTriangleCount(); triIdx++ )
	{
		IndexTriple & rTri = Triangles[ triIdx ];

		for ( TIndex i = 0; i < 3; i++ )
		{
			const mxVertex & rCurrVertex = Vertices[ rTri[i] ];

			s32  iExistingVertex = -1;
			for ( TIndex iVtx = 0; iVtx < newVerts.Num(); iVtx++ )
			{
				if ( VectorsEqual( newVerts[ iVtx ].Pos, rCurrVertex.Pos ) )
				{
					iExistingVertex = iVtx;
					break;
				}
			}

			if ( iExistingVertex != -1 ) {
				rTri[ i ] = iExistingVertex;
			} else {
				rTri[ i ] = newVerts.Append( mxVertex( rCurrVertex ) );
			}
		}
	}

	Vertices = newVerts;
}
示例#5
0
文件: Mesh.cpp 项目: tecan/Luna
void mxRenderMesh::TransformVertices( const TMatrix4& matrix )
{
	for ( u32 i = 0; i < GetVertexCount(); ++i )
	{
		matrix.transformVect( Vertices[ i ].Pos );
	}
}
示例#6
0
文件: Mesh.cpp 项目: tecan/Luna
void mxRenderMesh::ScaleVertices( const Vec3D& value )
{
	for ( u32 i = 0; i < GetVertexCount(); ++i )
	{
		Vertices[ i ].Pos *= value;
	}
}
示例#7
0
文件: Mesh.cpp 项目: tecan/Luna
void mxRenderMesh::ScaleTextureCoordinates( const f32 factorU, const f32 factorV )
{
	for ( u32 i = 0; i < GetVertexCount(); ++i )
	{
		Vertices[ i ].U *= factorU;
		Vertices[ i ].V *= factorV;
	}
}
void dgCollisionBVH::GetVertexListIndexList (const dgVector& p0, const dgVector& p1, dgGetVertexListIndexList &data) const
{
	ForAllSectors (p0, p1, CollectVertexListIndexList, &data);

	data.m_veterxArray = GetLocalVertexPool(); 
	data.m_vertexCount = GetVertexCount(); 
	data.m_vertexStrideInBytes = GetStrideInBytes(); 

}
示例#9
0
文件: Mesh.cpp 项目: tecan/Luna
void mxRenderMesh::ComputeBoundingBox( AABB &bbox ) const
{
	bbox.reset( 0.0f, 0.0f, 0.0f );

	for ( u32 i = 0; i < GetVertexCount(); i++ )
	{
		bbox.addInternalPoint( GetPos( i ) );
	}
}
示例#10
0
void dgCollisionBVH::GetVertexListIndexList (const dgVector& p0, const dgVector& p1, dgMeshVertexListIndexList &data) const
{
	dgFastAABBInfo box (p0, p1);
	ForAllSectors (box, dgVector (dgFloat32 (0.0f)), dgFloat32 (1.0f), CollectVertexListIndexList, &data);

	data.m_veterxArray = GetLocalVertexPool(); 
	data.m_vertexCount = GetVertexCount(); 
	data.m_vertexStrideInBytes = GetStrideInBytes(); 

}
示例#11
0
void CSceneObject::OnFrame()
{
	inherited::OnFrame();
	if (!m_pReference) return;
	if (m_pReference) m_pReference->OnFrame();
	if (psDeviceFlags.is(rsStatistic)){
    	if (IsStatic()||IsMUStatic()||Selected()){
            Device.Statistic->dwLevelSelFaceCount 	+= GetFaceCount();
            Device.Statistic->dwLevelSelVertexCount += GetVertexCount();
        }
    }
}
示例#12
0
inline void
ParametricSurface::GenerateVertices(vector<float>& vertices,
                                    unsigned char flags) const
{
    int floatsPerVertex = 3;
    if (flags & VertexFlagsNormals)
        floatsPerVertex += 3;
    if (flags & VertexFlagsTexCoords)
        floatsPerVertex += 2;

    vertices.resize(GetVertexCount() * floatsPerVertex);
    float* attribute = &vertices[0];

    for (int j = 0; j < m_divisions.y; j++) {
        for (int i = 0; i < m_divisions.x; i++) {

            // Compute Position
            vec2 domain = ComputeDomain(i, j);
            vec3 range = Evaluate(domain);
            attribute = range.Write(attribute);

            // Compute Normal
            if (flags & VertexFlagsNormals) {
                float s = i, t = j;

                // Nudge the point if the normal is indeterminate.
                if (i == 0) s += 0.01f;
                if (i == m_divisions.x - 1) s -= 0.01f;
                if (j == 0) t += 0.01f;
                if (j == m_divisions.y - 1) t -= 0.01f;
                
                // Compute the tangents and their cross product.
                vec3 p = Evaluate(ComputeDomain(s, t));
                vec3 u = Evaluate(ComputeDomain(s + 0.01f, t)) - p;
                vec3 v = Evaluate(ComputeDomain(s, t + 0.01f)) - p;
                vec3 normal = u.Cross(v).Normalized();
                if (InvertNormal(domain))
                    normal = -normal;
                attribute = normal.Write(attribute);
            }
            
            // Compute Texture Coordinates
            if (flags & VertexFlagsTexCoords) {
                float s = m_textureCount.x * i / m_slices.x;
                float t = m_textureCount.y * j / m_slices.y;
                attribute = vec2(s, t).Write(attribute);
            }
        }
    }
}
示例#13
0
	bool OGLRenderSystem::DrawPrimitiveUP( PrimitiveType::PrimitiveType type, int count, void* data, int stride )
	{
		if( !ApplyVertexDeclaration( stride, (char*)data ) )
			return false;

		glDrawArrays( type, 0, GetVertexCount( type, count ) );

		ResetClientState( );

		++mBatchCount;
		mPrimCount += count;

		return true;
	};
示例#14
0
//--------------------------------------------------------------------------------
void VertexBuffer_DX11::Init(const void* in_pData)
{
	//If buffer is constant, it needs to be initialized with data.
	AssertMsg(!(m_uiBufferType & eUT_Constant && in_pData == nullptr), L("Constant Buffers need to be initialized with data."));
	AssertMsg(!(m_uiBufferType & eUT_Constant && m_uiVertexCount == 0), L("Constant Buffers need to be initialized with data."));

	//If buffer is not CPU writable, it needs to be initialized with data. (at least until GPU write support/use)
	AssertMsg(!(!(m_uiBufferType & eUT_CPU_Writable) && in_pData == nullptr), L("Non-CPU Writable Buffers need to be initialized with data."));
	AssertMsg(!(!(m_uiBufferType & eUT_CPU_Writable) && m_uiVertexCount == 0), L("Non-CPU Writable Buffers need to be initialized with data."));

	if (GetVertexCount() == 0)
		return;

	Renderer_DX11* pDX11Renderer = (Renderer_DX11*)GetOwner();

	D3D11_BUFFER_DESC vertexBufferDesc;
	vertexBufferDesc.ByteWidth = GetVertexCount() * GetVertexSize();
	vertexBufferDesc.Usage = GetD3D11Usage(m_uiBufferType);
	vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexBufferDesc.CPUAccessFlags = GetCPUAccessFlags(m_uiBufferType);
	vertexBufferDesc.MiscFlags = 0;
	vertexBufferDesc.StructureByteStride = 0;

	D3D11_SUBRESOURCE_DATA vertexBufferInitData;
	vertexBufferInitData.pSysMem = in_pData;
	vertexBufferInitData.SysMemPitch = 0;
	vertexBufferInitData.SysMemSlicePitch = 0;

	SAFE_RELEASE(m_pD3D11VertexBuffer);

	if(in_pData == nullptr)
		HResult hr = pDX11Renderer->GetDevice()->CreateBuffer(&vertexBufferDesc, nullptr, &m_pD3D11VertexBuffer);
	else
		HResult hr = pDX11Renderer->GetDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferInitData, &m_pD3D11VertexBuffer);

	SET_D3D11_OBJECT_NAME(m_pD3D11VertexBuffer);
}
示例#15
0
//----------------------------------------------------------------------------
// Skeleton functions
//----------------------------------------------------------------------------
bool CEditableObject::ImportMAXSkeleton(CExporter* E)
{
	bool bResult				= true;
	CEditableMesh* MESH			= xr_new<CEditableMesh>(this);
	m_Meshes.push_back(MESH);
	// import mesh
	if (!MESH->Convert(E))		return FALSE;
	// BONES
	m_Bones.reserve(E->m_Bones.size());
	for (int B=0; B!=E->m_Bones.size(); B++){
		m_Bones.push_back(xr_new<CBone>());
		CBone* BONE				= m_Bones.back(); 
		CBoneDef* bone			= E->m_Bones[B];
		CBoneDef* parent_bone	= bone->parent;

		Fvector offset,rotate;
		float length= 0.1f;

		Fmatrix m;
		if (parent_bone)	m.mul(parent_bone->matOffset,bone->matInit);
		else				m.set(bone->matInit);

		m.getXYZi			(rotate);
		offset.set			(m.c);

		BONE->SetWMap		(bone->name.c_str());
		BONE->SetName		(bone->name.c_str());
		BONE->SetParentName	(Helper::ConvertSpace(string(bone->pBone->GetParentNode()->GetName())).c_str());
		BONE->SetRestParams	(length,offset,rotate);
	}

	// DEFAULT BONE PART
	m_BoneParts.push_back(SBonePart());
	SBonePart& BP = m_BoneParts.back();
	BP.alias = "default";
	for (int b_i=0; b_i<(int)m_Bones.size(); b_i++)
		BP.bones.push_back(Bones()[b_i]->Name());

	m_objectFlags.set(CEditableObject::eoDynamic,TRUE);

	if ((0==GetVertexCount())||(0==GetFaceCount())){ 
		bResult = false;
	}else{
		ELog.Msg(mtInformation,"Model '%s' contains: %d points, %d faces, %d bones", E->m_MeshNode->GetName(), GetVertexCount(), GetFaceCount(), Bones().size());
	}

	return bResult;
}
示例#16
0
void ProceduralQuad::GetNormals(void * data_start, unsigned int byte_stride)
{
	Eigen::Vector3f normal = (corners[1]-corners[0]).cross(corners[2]-corners[0]);
	normal.normalize();

	float * dest = (float *) data_start;

	unsigned int vertex_count = GetVertexCount();
	for (unsigned int i = 0; i < vertex_count; ++i)
	{
		dest[0] = normal[0];
		dest[1] = normal[1];
		dest[2] = normal[2];
		dest = (float *) ((char *) dest + byte_stride);
	}
}
示例#17
0
	bool OGLRenderSystem::DrawPrimitive( PrimitiveType::PrimitiveType type, int start, int count )
	{
		glBindBuffer( GL_ARRAY_BUFFER, mRenderState.mVertexBuffer );

		if( !ApplyVertexDeclaration( mRenderState.mVDeclaration->GetStride( 0 ) ) )
			return false;

		glDrawArrays( type, 0, GetVertexCount( type, count ) );

		ResetClientState( );

		++mBatchCount;
		mPrimCount += count;

		return true;
	};
示例#18
0
	bool OGLRenderSystem::DrawIndexedPrimitive( PrimitiveType::PrimitiveType type, int vstart, int istart, int vcount, int count )
	{
		glBindBuffer( GL_ARRAY_BUFFER, mRenderState.mVertexBuffer );

		int stride = mRenderState.mVDeclaration->GetStride( 0 );
		if( !ApplyVertexDeclaration( stride, (char*)(vstart * stride) ) )
			return false;

		glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mRenderState.mIndexBuffer );
		glDrawElements( type, GetVertexCount( type, count ), GL_UNSIGNED_SHORT, 0 );

		ResetClientState( );

		++mBatchCount;
		mPrimCount += count;

		return true;
	};
示例#19
0
void dgCollisionBVH::GetCollisionInfo(dgCollisionInfo* const info) const
{
	dgCollision::GetCollisionInfo(info);
		
	dgMeshVertexListIndexList data;
	data.m_indexList = NULL;
	data.m_userDataList = NULL;
	data.m_maxIndexCount = 1000000000;
	data.m_triangleCount = 0; 
//	dgVector p0 (-1.0e10f, -1.0e10f, -1.0e10f, 1.0f);
//	dgVector p1 ( 1.0e10f,  1.0e10f,  1.0e10f, 1.0f);
	dgVector zero (dgFloat32 (0.0f));
	dgFastAABBInfo box (dgGetIdentityMatrix(), dgVector (dgFloat32 (1.0e15f)));
	ForAllSectors (box, zero, dgFloat32 (1.0f), GetTriangleCount, &data);

	info->m_bvhCollision.m_vertexCount = GetVertexCount();
	info->m_bvhCollision.m_indexCount = data.m_triangleCount * 3;
}
void dgCollisionBVH::GetCollisionInfo(dgCollisionInfo* info) const
{
	dgCollision::GetCollisionInfo(info);

	info->m_offsetMatrix = GetOffsetMatrix();
	info->m_collisionType = m_collsionId;
		
	dgGetVertexListIndexList data;
	data.m_indexList = NULL;
	data.m_userDataList = NULL;
	data.m_maxIndexCount = 1000000000;
	data.m_triangleCount = 0; 
	dgVector p0 (-1.0e10f, -1.0e10f, -1.0e10f, 1.0f);
	dgVector p1 ( 1.0e10f,  1.0e10f,  1.0e10f, 1.0f);
	ForAllSectors (p0, p1, GetTriangleCount, &data);

	info->m_bvhCollision.m_vertexCount = GetVertexCount();
	info->m_bvhCollision.m_indexCount = data.m_triangleCount * 3;
}
示例#21
0
void AasRenderer::RenderWithoutMaterial(gfx::AnimatedModel *model, 
	const gfx::AnimatedModelParams& params) {

	// Find or create render caching data for the model
	auto &renderData = mRenderDataCache[model->GetHandle()];
	if (!renderData) {
		renderData = std::make_unique<AasRenderData>();
	}

	auto materialIds(model->GetSubmeshes());
	for (size_t i = 0; i < materialIds.size(); ++i) {
		auto submesh(model->GetSubmesh(params, i));

		auto &submeshData = GetSubmeshData(*renderData, i, *submesh);
		submeshData.binding.Bind();

		auto d3d = mDevice.GetDevice();
		d3d->SetIndices(submeshData.idxBuffer->GetBuffer());
		D3DLOG(d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, submesh->GetVertexCount(), 0, submesh->GetPrimitiveCount()));
	}
}
示例#22
0
		bool IShape::ContainsPoint(const glm::vec2& point)
		{
			// For each triangle.
			for (unsigned int t = 0; t < GetVertexCount() / 3; ++t)
			{
				// Index for the first vertex that composes triangle.
				const unsigned int triangleStartIndex = t * 3;

				// Get the viewport coordinates of the three vertices that
				// compose the triangle.
				glm::vec2 A = TransformPoint(GetVertexPosition(triangleStartIndex));
				glm::vec2 B = TransformPoint(GetVertexPosition(triangleStartIndex + 1));
				glm::vec2 C = TransformPoint(GetVertexPosition(triangleStartIndex + 2));

				// Compute barycentric coordinates for the specified point with
				// respect to the triangle ABC.
				const glm::vec2 v0(C - A);
				const glm::vec2 v1(B - A);
				const glm::vec2 v2(point - A);
				float dot00 = glm::dot(v0, v0);
				float dot01 = glm::dot(v0, v1);
				float dot02 = glm::dot(v0, v2);
				float dot11 = glm::dot(v1, v1);
				float dot12 = glm::dot(v1, v2);
				float recipDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
				float u = (dot11 * dot02 - dot01 * dot12) * recipDenom;
				float v = (dot00 * dot12 - dot01 * dot02) * recipDenom;

				// Return true if the point is inside of the triangle.
				if (u >= 0.0f && v >= 0.0f && (u + v) < 1.0f) return true;
			}

			// The point was not contained by any of the triangles that compose
			// the shape.
			return false;
		}
示例#23
0
//--------------------------------------------------------------------------------
void GeometryDX11::LoadToBuffers( ID3D11Device* pDevice )
{
	// Check the size of the assembled vertices
	CalculateVertexSize();

	// Load the vertex buffer first by calculating the required size
	unsigned int vertices_length = GetVertexSize() * GetVertexCount();

	char* pBytes = new char[vertices_length];

	for ( int j = 0; j < m_iVertexCount; j++ )
	{
		int iElemOffset = 0;
		for ( int i = 0; i < m_vElements.count(); i++ )
		{
			memcpy( pBytes + j * m_iVertexSize + iElemOffset, m_vElements[i]->GetPtr(j), m_vElements[i]->SizeInBytes() );
			iElemOffset += m_vElements[i]->SizeInBytes();
		}
	}


	D3D11_SUBRESOURCE_DATA data;
	data.pSysMem = reinterpret_cast<void*>( pBytes );
	data.SysMemPitch = 0;
	data.SysMemSlicePitch = 0;

	D3D11_BUFFER_DESC vbuffer;
	vbuffer.ByteWidth = vertices_length;
    vbuffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbuffer.MiscFlags = 0;
    vbuffer.StructureByteStride = 0;
	vbuffer.Usage = D3D11_USAGE_IMMUTABLE;
	vbuffer.CPUAccessFlags = 0;
    vbuffer.StructureByteStride = 0;

	pDevice->CreateBuffer( &vbuffer, &data, &m_pVertexBuffer );

	delete [] pBytes; 
	// TODO: add error checking here!

	
	// Load the index buffer by calculating the required size
	// based on the number of indices.

	data.pSysMem = reinterpret_cast<void*>( &m_vIndices[0] );
	data.SysMemPitch = 0;
	data.SysMemSlicePitch = 0;
	
	D3D11_BUFFER_DESC ibuffer;

	ibuffer.ByteWidth = sizeof( unsigned int ) * GetIndexCount();
    ibuffer.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibuffer.MiscFlags = 0;
    ibuffer.StructureByteStride = 0;
	ibuffer.Usage = D3D11_USAGE_IMMUTABLE;
	ibuffer.CPUAccessFlags = 0;
    ibuffer.StructureByteStride = 0;

	pDevice->CreateBuffer( &ibuffer, &data, &m_pIndexBuffer );
	//m_iIB = RendererDX11::Get()->CreateIndexBuffer( &ibuffer, &data );
}
示例#24
0
UInt TriangleStripMesh::GetTriangleCount() const
{
    if ( m_pIB == NULL )
        return ( GetVertexCount() - 2 );
    return ( GetIndexCount() - 2 );
}
示例#25
0
    void ModelDefinition::Serialize(Serializer &serializer) const
    {
        BasicSerializer intermediarySerializer;


        /////////////////////////////////////
        // Bones

        intermediarySerializer.Write(static_cast<uint32_t>(m_bones.count));
        
        // Local information.
        for (size_t iBone = 0; iBone < m_bones.count; ++iBone)
        {
            auto bone = m_bones[iBone];
            assert(bone != nullptr);
            {
                // Name.
                intermediarySerializer.WriteString(bone->GetName());

                // Relative transformation.
                intermediarySerializer.Write(bone->GetPosition());
                intermediarySerializer.Write(bone->GetRotation());
                intermediarySerializer.Write(bone->GetScale());

                // 4x4 offset matrix.
                intermediarySerializer.Write(bone->GetOffsetMatrix());
            }
        }

        // Parents. -1 for bones without parents.
        for (size_t iBone = 0; iBone < m_bones.count; ++iBone)
        {
            auto bone = m_bones[iBone];
            assert(bone != nullptr);
            {
                auto parentBone = bone->GetParent();
                if (parentBone != nullptr)
                {
                    size_t parentBoneIndex;
                    if (!this->FindBoneIndex(parentBone, parentBoneIndex))
                    {
                        assert(false);
                    }
                    
                    intermediarySerializer.Write(static_cast<uint32_t>(parentBoneIndex));
                }
                else
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(-1));
                }
            }
        }

        Serialization::ChunkHeader header;
        header.id          = Serialization::ChunkID_Model_Bones;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Meshes
        //
        // Vertex data is always saved in P3T2N3T3B3 format. Bones are referenced using an integer to index into the list of bones defined above.

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(this->meshes.count));

        for (size_t iMesh = 0; iMesh < this->meshes.count; ++iMesh)
        {
            // Name.
            intermediarySerializer.WriteString(this->meshes[iMesh].name);


            // Material.
            intermediarySerializer.WriteString(this->meshes[iMesh].material->GetDefinition().relativePath);


            // Vertices.
            auto vertexArray = this->meshes[iMesh].geometry;
            assert(vertexArray != nullptr);
            {
                // Vertex Format.
                vertexArray->GetFormat().Serialize(intermediarySerializer);


                // Vertices.
                intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount()));

                if (vertexArray->GetVertexCount() > 0)
                {
                    intermediarySerializer.Write(vertexArray->GetVertexDataPtr(), vertexArray->GetFormat().GetSizeInBytes() * vertexArray->GetVertexCount());
                }


                // Indices.
                intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetIndexCount()));

                if (vertexArray->GetIndexCount() > 0)
                {
                    intermediarySerializer.Write(vertexArray->GetIndexDataPtr(), sizeof(uint32_t) * vertexArray->GetIndexCount());
                }


                // Skinning Vertex Attributes.
                if (this->meshes[iMesh].skinningVertexAttributes != nullptr)
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount()));

                    if (vertexArray->GetVertexCount() > 0)
                    {
                        uint32_t totalBoneWeights = 0;


                        // Bone Counts.
                        for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex)
                        {
                            uint16_t count = static_cast<uint16_t>(this->meshes[iMesh].skinningVertexAttributes[iVertex].bones.count);
                            intermediarySerializer.Write(count);

                            totalBoneWeights += count;
                        }

                            
                        // Bone/Weight Pairs.
                        intermediarySerializer.Write(totalBoneWeights);

                        for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex)
                        {
                            auto &bones = this->meshes[iMesh].skinningVertexAttributes[iVertex].bones;
                            {
                                for (size_t iBone = 0; iBone < bones.count; ++iBone)
                                {
                                    auto &bone = bones[iBone];

                                    intermediarySerializer.Write(static_cast<uint32_t>(bone.boneIndex));
                                    intermediarySerializer.Write(static_cast<float   >(bone.weight));
                                }
                            }
                        }
                    }
                }
                else
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(0));
                }


                // Default uniforms.
                this->meshes[iMesh].defaultUniforms.Serialize(intermediarySerializer);
            }
        }

        header.id          = Serialization::ChunkID_Model_Meshes;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetKeyFrameCount()));

        for (uint32_t iKeyFrame = 0; iKeyFrame < m_animation.GetKeyFrameCount(); ++iKeyFrame)
        {
            // Time.
            intermediarySerializer.Write(static_cast<float>(m_animation.GetKeyFrameTimeByIndex(iKeyFrame)));
            
            
            // Channels.
            intermediarySerializer.Write(static_cast<uint32_t>(this->animationChannelBones.count));

            for (size_t iChannel = 0; iChannel < this->animationChannelBones.count; ++iChannel)
            {
                auto channel = this->animationChannelBones.buffer[iChannel]->value;
                auto bone    = this->animationChannelBones.buffer[iChannel]->key;

                assert(channel != nullptr);
                assert(bone    != nullptr);
                {
                    // Bone Index.
                    size_t boneIndex;
                    this->FindBoneIndex(bone, boneIndex);

                    intermediarySerializer.Write(static_cast<uint32_t>(boneIndex));


                    // Bone Transformation.
                    glm::vec3 position;
                    glm::quat rotation;
                    glm::vec3 scale;

                    auto key = static_cast<TransformAnimationKey*>(channel->GetKey(iKeyFrame));
                    if (key != nullptr)
                    {
                        position = key->position;
                        rotation = key->rotation;
                        scale    = key->scale;
                    }
                    else
                    {
                        // We should never actually get here, but for completeness we'll just write identities.
                        position = bone->GetPosition();
                        rotation = bone->GetRotation();
                        scale    = bone->GetScale();
                    }

                    intermediarySerializer.Write(position);
                    intermediarySerializer.Write(rotation);
                    intermediarySerializer.Write(scale);
                }
            }
        }

        intermediarySerializer.Write(this->animationAABBPadding);


        header.id          = Serialization::ChunkID_Model_Animation;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation Segments

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetNamedSegmentCount()));

        for (size_t iSegment = 0; iSegment < m_animation.GetNamedSegmentCount(); ++iSegment)
        {
            auto segment = m_animation.GetNamedSegmentByIndex(iSegment);
            assert(segment != nullptr);
            {
                intermediarySerializer.WriteString(segment->name);
                intermediarySerializer.Write(static_cast<uint32_t>(segment->startKeyFrame));
                intermediarySerializer.Write(static_cast<uint32_t>(segment->endKeyFrame));
            }
        }

        header.id          = Serialization::ChunkID_Model_AnimationSegments;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation Sequences

        /*
        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(this->animationSequences.count));

        for (size_t iSequence = 0; iSequence < this->animationSequences.count; ++iSequence)
        {
        }

        header.id          = Serialization::ChunkID_Model_AnimationSequences;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);
        */


        /////////////////////////////////////
        // Convex Hulls

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_convexHulls.count));

        Vector<uint32_t> vertexCounts(m_convexHulls.count);
        Vector<uint32_t> indexCounts( m_convexHulls.count);
        Vector<float>    vertices;
        Vector<uint32_t> indices;

        for (size_t iConvexHull = 0; iConvexHull < m_convexHulls.count; ++iConvexHull)
        {
            auto convexHull = m_convexHulls[iConvexHull];
            assert(convexHull != nullptr);
            {
                uint32_t vertexCount = static_cast<uint32_t>(convexHull->GetVertexCount());
                uint32_t indexCount  = static_cast<uint32_t>(convexHull->GetIndexCount());

                vertexCounts.PushBack(vertexCount);
                indexCounts.PushBack( indexCount);

                for (uint32_t iVertex = 0; iVertex < vertexCount; ++iVertex)
                {
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 0]);
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 1]);
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 2]);
                }

                for (uint32_t iIndex = 0; iIndex < indexCount; ++iIndex)
                {
                    indices.PushBack(convexHull->GetIndices()[iIndex]);
                }
            }
        }

        intermediarySerializer.Write(vertexCounts.buffer, vertexCounts.count * 4);
        intermediarySerializer.Write(indexCounts.buffer,  indexCounts.count  * 4);

        intermediarySerializer.Write(static_cast<uint32_t>(vertices.count));
        intermediarySerializer.Write(static_cast<uint32_t>(indices.count));

        intermediarySerializer.Write(vertices.buffer, vertices.count * 4);
        intermediarySerializer.Write(indices.buffer,  indices.count  * 4);

        intermediarySerializer.Write(this->convexHullBuildSettings);


        header.id          = Serialization::ChunkID_Model_ConvexHulls;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Null Chunk

        header.id          = Serialization::ChunkID_Null;
        header.version     = 1;
        header.sizeInBytes = 0;
        serializer.Write(header);
    }
示例#26
0
BYTE* D3DXMeshVertexEnumer::GetVertexByteHead( UINT uIndex )
{
	_ASSERTE(IsValid());
	_ASSERTE(uIndex < GetVertexCount());
	return m_pBuffer + m_dwNumBytePerVertex * uIndex;
}
示例#27
0
bool CEditableMesh::Convert( INode *node )
{
	// prepares & checks
	BOOL bDeleteObj;
	bool bResult = true;
	TriObject *obj = ExtractTriObject( node, bDeleteObj );

	if( !obj ){
		ELog.Msg(mtError,"%s -> Can't convert to TriObject", node->GetName() );
		return false; }

	if( obj->mesh.getNumFaces() <=0 ){
		ELog.Msg(mtError,"%s -> There are no faces ?", node->GetName() );
		if (bDeleteObj) delete (obj);
		return false; }

	Mtl *pMtlMain = node->GetMtl();
	DWORD cSubMaterials=0;

	if (pMtlMain){
		// There is at least one material. We're in case 1) or 2)
		cSubMaterials = pMtlMain->NumSubMtls();
		if (cSubMaterials < 1){
			// Count the material itself as a submaterial.
			cSubMaterials = 1;
		}
	}

	// build normals
	obj->mesh.buildRenderNormals();

	// vertices
	m_VertCount = obj->mesh.getNumVerts();
	m_Vertices = xr_alloc<Fvector>(m_VertCount);
	for (int v_i=0; v_i<m_VertCount; v_i++){
		Point3* p = obj->mesh.verts+v_i;
		m_Vertices[v_i].set(p->x,p->y,p->z);
	}

	// set smooth group MAX type
	m_Flags.set(flSGMask,TRUE);

	// faces
	m_FaceCount		= obj->mesh.getNumFaces();
	m_Faces			= xr_alloc<st_Face>	(m_FaceCount);
	m_SmoothGroups	= xr_alloc<u32>		(m_FaceCount);

	m_VMRefs.reserve(m_FaceCount*3);
	if (0==obj->mesh.mapFaces(1))
	{
		bResult = false;
		ELog.Msg(mtError,"'%s' hasn't UV mapping!", node->GetName());
	}
	if (bResult)
	{
		CSurface* surf=0;
		for (int f_i=0; f_i<m_FaceCount; ++f_i)
		{
			Face*	vf = obj->mesh.faces+f_i;
			TVFace* tf = obj->mesh.mapFaces(1) + f_i;
			if (!tf)
			{
				bResult = false;
				ELog.Msg(mtError,"'%s' hasn't UV mapping!", node->GetName());
				break;
			}
			m_SmoothGroups[f_i]					= vf->getSmGroup();
			for (int k=0; k<3; ++k)
			{
				m_Faces[f_i].pv[k].pindex = vf->v[k];
				m_VMRefs.push_back(st_VMapPtLst());
				st_VMapPtLst&	vm_lst = m_VMRefs.back();
				vm_lst.count	= 1;
				vm_lst.pts		= xr_alloc<st_VMapPt>(vm_lst.count);
				for (DWORD vm_i=0; vm_i<vm_lst.count; ++vm_i)
				{
					vm_lst.pts[vm_i].vmap_index	= 0;
					vm_lst.pts[vm_i].index 		= tf->t[k];
				}
				m_Faces[f_i].pv[k].vmref	= m_VMRefs.size()-1;
				if (!bResult) break;
			}
			if (pMtlMain)
			{
				int m_id = obj->mesh.getFaceMtlIndex(f_i);
				if (cSubMaterials == 1)
				{
					m_id = 0;
				}else
				{
					// SDK recommends mod'ing the material ID by the valid # of materials, 
					// as sometimes a material number that's too high is returned.
					m_id %= cSubMaterials;
				}
				surf = m_Parent->CreateSurface(pMtlMain,m_id);
				if (!surf) bResult = false;
			}
			if (!bResult) break;
			m_SurfFaces[surf].push_back(f_i);
		}
	}

	// vmaps
	if( bResult ){
		int vm_cnt = obj->mesh.getNumTVerts();
		m_VMaps.resize(1);
		st_VMap*& VM = m_VMaps.back();
		VM = xr_new<st_VMap>("Texture",vmtUV,false);
		for (int tx_i=0; tx_i<vm_cnt; tx_i++){
			UVVert* tv = obj->mesh.tVerts + tx_i;
			VM->appendUV(tv->x,1-tv->y);
		}
	}

	if ((GetVertexCount()<4)||(GetFaceCount()<2))
	{
		ELog.Msg(mtError,"Invalid mesh: '%s'. Faces<2 or Verts<4");
		bResult = false;
	}

	if (bResult ){
		ELog.Msg(mtInformation,"Model '%s' contains: %d points, %d faces",
			node->GetName(), m_VertCount, m_FaceCount);
	}

	if (bResult)
	{
		RecomputeBBox	();
		OptimizeMesh	(false);
		RebuildVMaps	();
		ELog.Msg(mtInformation,"Model '%s' converted: %d points, %d faces",
			node->GetName(), GetVertexCount(), GetFaceCount());
	}

	if (bDeleteObj) delete (obj);
	return bResult;
}
示例#28
0
bool CEditableMesh::Convert(CExporter* E)
{
	bool bResult		= true;

	m_Name				= E->m_MeshNode->GetName();

	// maps
	// Weight maps 
	m_VMaps.resize(E->m_Bones.size()+1);
	for (DWORD b_i=0; b_i<E->m_Bones.size(); b_i++)
		m_VMaps[b_i]	= xr_new<st_VMap>(E->m_Bones[b_i]->name.c_str(),vmtWeight,false);;
	// UV map
	int VM_UV_idx		= m_VMaps.size()-1;
	st_VMap*& VM_UV		= m_VMaps[VM_UV_idx];
	VM_UV				= xr_new<st_VMap>("texture",vmtUV,false);

	// points
	{
		m_VertCount		= E->m_ExpVertices.size();
		m_Vertices		= xr_alloc<Fvector>(m_VertCount);
		Fvector* p_it	= m_Vertices;

		for (ExpVertIt ev_it=E->m_ExpVertices.begin(); ev_it!=E->m_ExpVertices.end(); ev_it++,p_it++){
			p_it->set		((*ev_it)->P);
			VM_UV->appendUV	((*ev_it)->uv.x,(*ev_it)->uv.y);
		}
	}
	// faces 
	{
		// set smooth group MAX type
		m_Flags.set(flSGMask,TRUE);
		// reserve space for faces and references
		m_FaceCount		= E->m_ExpFaces.size();
		m_Faces			= xr_alloc<st_Face>	(m_FaceCount);
		m_SmoothGroups	= xr_alloc<u32>		(m_FaceCount);
		m_VMRefs.resize	(m_VertCount);

		int f_id=0;
		for (ExpFaceIt ef_it=E->m_ExpFaces.begin(); ef_it!=E->m_ExpFaces.end(); ef_it++,f_id++){
			// FACES
			m_SmoothGroups[f_id]	= (*ef_it)->sm_group;
			st_Face& F				= m_Faces[f_id];
			for (int k=0; k<3; ++k)
			{
				int v_idx			= (*ef_it)->v[k];
				st_FaceVert& vt		= F.pv[k];
				st_VERT* V			= E->m_ExpVertices[v_idx];
				vt.pindex			= v_idx;
				st_VMapPtLst& vm_lst= m_VMRefs[vt.pindex];
				vm_lst.count		= V->data.size()+1;
				vm_lst.pts			= xr_alloc<st_VMapPt>(vm_lst.count);
				vm_lst.pts[0].vmap_index= VM_UV_idx;
				vm_lst.pts[0].index 	= vt.pindex;
				for (VDIt vd_it=V->data.begin(); vd_it!=V->data.end(); vd_it++){
					DWORD idx		= vd_it-V->data.begin()+1;
					st_VMap* vm		= m_VMaps[vd_it->bone];
					vm->appendW		(vd_it->weight);
					vm_lst.pts[idx].vmap_index	= vd_it->bone;
					vm_lst.pts[idx].index 		= vm->size()-1;
				}
				vt.vmref			= vt.pindex;
			}
			CSurface* surf = m_Parent->CreateSurface(E->m_MtlMain,(*ef_it)->m_id);
			if (!surf){
				bResult = FALSE;
				break;
			}
			m_SurfFaces[surf].push_back(f_id);
		}
	}
	if ((GetVertexCount()<4)||(GetFaceCount()<2))
	{
		Log("!Invalid mesh: '%s'. Faces<2 or Verts<4",*Name());
		bResult = false;
	}
	if (bResult)
	{
		RecomputeBBox	();
		OptimizeMesh	(true);//false);
		RebuildVMaps	();
	}
	return bResult;
}
示例#29
0
void SS3OPiece::SetVertexTangents()
{
	if (isEmpty || primitiveType == S3O_PRIMTYPE_QUADS) {
		return;
	}

	sTangents.resize(GetVertexCount(), ZeroVector);
	tTangents.resize(GetVertexCount(), ZeroVector);

	unsigned stride = 0;

	switch (primitiveType) {
		case S3O_PRIMTYPE_TRIANGLES: {
			stride = 3;
		} break;
		case S3O_PRIMTYPE_TRIANGLE_STRIP: {
			stride = 1;
		} break;
	}

	// for triangle strips, the piece vertex _indices_ are defined
	// by the draw order of the vertices numbered <v, v + 1, v + 2>
	// for v in [0, n - 2]
	const unsigned vrtMaxNr = (stride == 1)?
		vertexDrawOrder.size() - 2:
		vertexDrawOrder.size();

	// set the triangle-level S- and T-tangents
	for (unsigned vrtNr = 0; vrtNr < vrtMaxNr; vrtNr += stride) {
		bool flipWinding = false;

		if (primitiveType == S3O_PRIMTYPE_TRIANGLE_STRIP) {
			flipWinding = ((vrtNr & 1) == 1);
		}

		const int v0idx = vertexDrawOrder[vrtNr                      ];
		const int v1idx = vertexDrawOrder[vrtNr + (flipWinding? 2: 1)];
		const int v2idx = vertexDrawOrder[vrtNr + (flipWinding? 1: 2)];

		if (v1idx == -1 || v2idx == -1) {
			// not a valid triangle, skip
			// to start of next tri-strip
			vrtNr += 3; continue;
		}

		const SS3OVertex* vrt0 = &vertices[v0idx];
		const SS3OVertex* vrt1 = &vertices[v1idx];
		const SS3OVertex* vrt2 = &vertices[v2idx];

		const float3& p0 = vrt0->pos;
		const float3& p1 = vrt1->pos;
		const float3& p2 = vrt2->pos;

		const float2 tc0(vrt0->textureX, vrt0->textureY);
		const float2 tc1(vrt1->textureX, vrt1->textureY);
		const float2 tc2(vrt2->textureX, vrt2->textureY);

		const float x1x0 = p1.x - p0.x, x2x0 = p2.x - p0.x;
		const float y1y0 = p1.y - p0.y, y2y0 = p2.y - p0.y;
		const float z1z0 = p1.z - p0.z, z2z0 = p2.z - p0.z;

		const float s1 = tc1.x - tc0.x, s2 = tc2.x - tc0.x;
		const float t1 = tc1.y - tc0.y, t2 = tc2.y - tc0.y;

		// if d is 0, texcoors are degenerate
		const float d = (s1 * t2 - s2 * t1);
		const bool  b = (d > -0.0001f && d < 0.0001f);
		const float r = b? 1.0f: 1.0f / d;

		// note: not necessarily orthogonal to each other
		// or to vertex normal (only to the triangle plane)
		const float3 sdir((t2 * x1x0 - t1 * x2x0) * r, (t2 * y1y0 - t1 * y2y0) * r, (t2 * z1z0 - t1 * z2z0) * r);
		const float3 tdir((s1 * x2x0 - s2 * x1x0) * r, (s1 * y2y0 - s2 * y1y0) * r, (s1 * z2z0 - s2 * z1z0) * r);

		sTangents[v0idx] += sdir;
		sTangents[v1idx] += sdir;
		sTangents[v2idx] += sdir;

		tTangents[v0idx] += tdir;
		tTangents[v1idx] += tdir;
		tTangents[v2idx] += tdir;
	}

	// set the smoothed per-vertex tangents
	for (int vrtIdx = vertices.size() - 1; vrtIdx >= 0; vrtIdx--) {
		float3& n = vertices[vrtIdx].normal;
		float3& s = sTangents[vrtIdx];
		float3& t = tTangents[vrtIdx];
		int h = 1;

		if (math::isnan(n.x) || math::isnan(n.y) || math::isnan(n.z)) {
			n = float3(0.0f, 0.0f, 1.0f);
		}
		if (s == ZeroVector) { s = float3(1.0f, 0.0f, 0.0f); }
		if (t == ZeroVector) { t = float3(0.0f, 1.0f, 0.0f); }

		h = ((n.cross(s)).dot(t) < 0.0f)? -1: 1;
		s = (s - n * n.dot(s));
		s = s.SafeANormalize();
		t = (s.cross(n)) * h;

		// t = (s.cross(n));
		// h = ((s.cross(t)).dot(n) >= 0.0f)? 1: -1;
		// t = t * h;
	}
}
示例#30
0
void AasRenderer::Render(gfx::AnimatedModel *model,
	const gfx::AnimatedModelParams& params,
	gsl::span<Light3d> lights,
	const MdfRenderOverrides *materialOverrides) {

	// Find or create render caching data for the model
	auto &renderData = mRenderDataCache[model->GetHandle()];
	if (!renderData) {
		renderData = std::make_unique<AasRenderData>();
	}
	
	auto materialIds(model->GetSubmeshes());
	for (size_t i = 0; i < materialIds.size(); ++i) {
		auto materialId = materialIds[i];
		auto submesh(model->GetSubmesh(params, i));
		
		// Remove special material marker in the upper byte and only 
		// use the actual shader registration id
		materialId &= 0x00FFFFFF;

		// Usually this should not happen, since it means there's  
		// an unbound replacement material
		if (materialId == 0) {
			continue;
		}

		// if material was not found
		if (materialId == 0x00FFFFFF) {
			continue;
		}

		auto material = mMdfFactory.GetById(materialId);
		
		if (!material) {
			logger->error("Legacy shader with id {} wasn't found.", materialId);
			continue;
		}

		material->Bind(mDevice, lights, materialOverrides);

		// Do we have to recalculate the normals?
		if (material->GetSpec()->recalculateNormals) {
			RecalcNormals(
				submesh->GetVertexCount(),
				submesh->GetPositions().data(),
				submesh->GetNormals().data(),
				submesh->GetPrimitiveCount(),
				submesh->GetIndices().data()
			);
		}

		auto &submeshData = GetSubmeshData(*renderData, i, *submesh);
		submeshData.binding.Bind();

		auto d3d = mDevice.GetDevice();
		d3d->SetIndices(submeshData.idxBuffer->GetBuffer());
		D3DLOG(d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, submesh->GetVertexCount(), 0, submesh->GetPrimitiveCount()));

	}

}