示例#1
0
// Merges data into a single vertex and index buffer referenced by primitive groups (submeshes).
//
ERet CompileMesh( const TcMeshData& src, const VertexDescription& vertex, RawMeshData &dst )
{
	UINT totalVertexCount = 0;
	UINT totalIndexCount = 0;
	CalculateTotalVertexIndexCount( src, totalVertexCount, totalIndexCount );

	const bool use32indices = (totalVertexCount >= MAX_UINT16);
	const UINT indexStride = use32indices ? 4 : 2;

	VertexStream	streamStorage[8];

	TArray< VertexStream >	streams;
	streams.SetExternalStorage( streamStorage, mxCOUNT_OF(streamStorage) );

	GatherStreams(vertex, streams);

	const UINT numStreams = streams.Num();

	// reserve space in vertex data
	RawVertexData& dstVD = dst.vertexData;
	dstVD.streams.SetNum(numStreams);
	dstVD.count = totalVertexCount;
	dstVD.type = VertexType::Generic;
	for( UINT streamIndex = 0; streamIndex < numStreams; streamIndex++ )
	{
		const UINT32 stride = vertex.streamStrides[ streamIndex ];	// stride of the vertex buffer
		RawVertexStream &dstVB = dstVD.streams[ streamIndex ];
		dstVB.data.SetNum( stride * totalVertexCount );
	}

	// reserve space in index data
	RawIndexData& dstID = dst.indexData;
	dstID.data.SetNum(indexStride * totalIndexCount);
	dstID.stride = indexStride;

	dst.topology = Topology::TriangleList;
	dst.bounds = src.bounds;

	// iterate over all submeshes (primitive groups) and merge vertex/index data
	const UINT numMeshes = src.sets.Num();
	dst.parts.SetNum(numMeshes);

	UINT32  currentVertexIndex = 0;
	UINT32  currentIndexNumber = 0;
	for( UINT meshIndex = 0; meshIndex < numMeshes; meshIndex++ )
	{
		const TcTriMesh& submesh = src.sets[ meshIndex ];
		const UINT32 numVertices = submesh.NumVertices();	// number of vertices in this submesh
		const UINT32 numIndices = submesh.NumIndices();	// number of indices in this submesh

		RawMeshPart &meshPart = dst.parts[ meshIndex ];
		meshPart.baseVertex = currentVertexIndex;
		meshPart.startIndex = currentIndexNumber;
		meshPart.indexCount = numIndices;
		meshPart.vertexCount = numVertices;

		const int maxBoneInfluences = numVertices * MAX_INFLUENCES;

		ScopedStackAlloc	stackAlloc(gCore.frameAlloc);
		int *	boneIndices = stackAlloc.AllocMany< int >( maxBoneInfluences );
		float *	boneWeights = stackAlloc.AllocMany< float >( maxBoneInfluences );

		memset(boneIndices, 0, maxBoneInfluences * sizeof(boneIndices[0]));
		memset(boneWeights, 0, maxBoneInfluences * sizeof(boneWeights[0]));

		if( submesh.weights.NonEmpty() )
		{
			mxASSERT(submesh.weights.Num() == numVertices);
			for( UINT32 vertexIndex = 0; vertexIndex < numVertices; vertexIndex++ )
			{
				const TcWeights& weights = submesh.weights[ vertexIndex ];
				const int numWeights = smallest(weights.Num(), MAX_INFLUENCES);
				for( int weightIndex = 0; weightIndex < numWeights; weightIndex++ )
				{
					const int offset = vertexIndex * MAX_INFLUENCES + weightIndex;
					boneIndices[ offset ] = weights[ weightIndex ].boneIndex;
					boneWeights[ offset ] = weights[ weightIndex ].boneWeight;
				}
			}//for each vertex
		}

		// process each vertex stream
		for( UINT streamIndex = 0; streamIndex < numStreams; streamIndex++ )
		{
			const UINT32 streamStride = vertex.streamStrides[ streamIndex ];	// stride of the vertex buffer
			const VertexStream& stream = streams[ streamIndex ];				
			RawVertexStream &dstVB = dstVD.streams[ streamIndex ];
			dstVB.data.SetNum( streamStride * totalVertexCount );

			const UINT32 currentVertexDataOffset = currentVertexIndex * streamStride;

			// first fill the vertex data with zeros
			void* dstStreamData = mxAddByteOffset( dstVB.data.ToPtr(), currentVertexDataOffset );
			memset(dstStreamData, 0, streamStride * numVertices);

			// process each vertex stream component
			for( UINT elementIndex = 0; elementIndex < stream.components.Num(); elementIndex++ )
			{
				const UINT32 attribIndex = stream.components[ elementIndex ];
				const VertexElement& attrib = vertex.attribsArray[ attribIndex ];
				const UINT32 attribOffset = vertex.attribOffsets[ attribIndex ];	// offset within stream
				const AttributeType::Enum attribType = (AttributeType::Enum) attrib.type;
				const VertexAttribute::Enum semantic = (VertexAttribute::Enum) attrib.semantic;				
				const UINT attribDimension = attrib.dimension + 1;

				// process each vertex
				const void* srcPtr = NULL;
				UINT srcDimension = 0;	// vector dimension: [1,2,3,4]
				bool srcDataIsFloat = true;
				bool srcIsPositive = false;
				bool normalize = attrib.normalized;
				int srcStride = 4; // sizeof(float) == sizeof(int)

				switch( semantic )
				{
				case VertexAttribute::Position :
					srcPtr = (float*) submesh.positions.SafeGetFirstItemPtr();
					srcDimension = 3;
					break;

				case VertexAttribute::Color0 :
					srcPtr = (float*) submesh.colors.SafeGetFirstItemPtr();
					srcDimension = 4;
					srcIsPositive = true;	// RGBA colors are in range [0..1]
					break;
				case VertexAttribute::Color1 :
					ptERROR("Vertex colors > 1 are not supported!\n");
					break;

				case VertexAttribute::Normal :
					srcPtr = (float*) submesh.normals.SafeGetFirstItemPtr();
					srcDimension = 3;
					normalize = true;	// we pack normals and tangents into Ubyte4
					break;
				case VertexAttribute::Tangent :
					srcPtr = (float*) submesh.tangents.SafeGetFirstItemPtr();
					srcDimension = 3;
					normalize = true;	// we pack normals and tangents into Ubyte4
					break;

				case VertexAttribute::TexCoord0 :
					srcPtr = (float*) submesh.texCoords.SafeGetFirstItemPtr();
					srcDimension = 2;
					break;
				case VertexAttribute::TexCoord1 :
				case VertexAttribute::TexCoord2 :
				case VertexAttribute::TexCoord3 :
				case VertexAttribute::TexCoord4 :
				case VertexAttribute::TexCoord5 :
				case VertexAttribute::TexCoord6 :
				case VertexAttribute::TexCoord7 :
					ptWARN("TexCoord > 1 are not supported!\n");
					break;

				case VertexAttribute::BoneIndices :
					srcPtr = boneIndices;
					srcDimension = 4;
					srcDataIsFloat = false;
					srcIsPositive = true;
					break;
				case VertexAttribute::BoneWeights :
					srcPtr = boneWeights;
					srcDimension = 4;
					srcIsPositive = true;	// bone weights are always in range [0..1]
					break;

				default:
					ptERROR("Unknown vertex attrib semantic: %d\n", semantic);
				}

				if( srcPtr && srcDimension > 0 )
				{
					for( UINT32 vertexIndex = 0; vertexIndex < numVertices; vertexIndex++ )
					{
						UINT vertexOffset = currentVertexDataOffset + vertexIndex*streamStride + attribOffset;
						void* dstPtr = mxAddByteOffset( dstVB.data.ToPtr(), vertexOffset );
						if( srcDataIsFloat ) {
 							PackVertexAttribF( (float*)srcPtr, srcDimension, dstPtr, attribType, attribDimension, normalize, srcIsPositive );
						} else {
							mxASSERT2( !attrib.normalized, "Integer data cannot be normalized!" );
							PackVertexAttribI( (int*)srcPtr, srcDimension, dstPtr, attribType, attribDimension );
						}
						srcPtr = mxAddByteOffset( srcPtr, srcDimension * srcStride );
					}//for each vertex
				}
			}//for each component
		}//for each stream

		void* indices = mxAddByteOffset(dstID.data.ToPtr(), currentIndexNumber * indexStride);
		for( UINT32 i = 0; i < numIndices; i++ )
		{
			const UINT32 index = submesh.indices[i];
			if( use32indices ) {
				UINT32* indices32 = (UINT32*) indices;
				indices32[i] = currentVertexIndex + index;
			} else {
				UINT16* indices16 = (UINT16*) indices;
				indices16[i] = currentVertexIndex + index;
			}
		}

		currentVertexIndex += submesh.NumVertices();
		currentIndexNumber += submesh.NumIndices();
	}

	const UINT numBones = src.skeleton.bones.Num();

	Skeleton& skeleton = dst.skeleton;

	skeleton.bones.SetNum(numBones);
	skeleton.boneNames.SetNum(numBones);
	skeleton.invBindPoses.SetNum(numBones);

	for( UINT boneIndex = 0; boneIndex < numBones; boneIndex++ )
	{
		const TcBone& bone = src.skeleton.bones[boneIndex];

		Bone& joint = skeleton.bones[boneIndex];

		joint.orientation = bone.rotation;
		joint.position = bone.translation;
		joint.parent = bone.parent;
#if 0
		if( bone.parent >= 0 )
		{
			const Joint& parent = skeleton.joints[bone.parent];
			UNDONE;			
			//ConcatenateJointTransforms(parent.position, parent.orientation, joint.position, joint.orientation);

			//Float4x4 parentMatrix = CalculateJointMatrix( parent.position, parent.orientation );
			//Float4x4 boneMatrix = CalculateJointMatrix( bone.translation, bone.rotation );
			//Float4x4 localMatrix = boneMatrix * glm::inverse(parentMatrix);

			//glm::vec3 localT(localMatrix[3]);
			//glm::quat localQ(localMatrix);
			//joint.orientation = localQ;
			//joint.position = localT;

			//Float4x4 parentMatrix = CalculateJointMatrix( parent.position, parent.orientation );
			//Float4x4 boneTransform = CalculateJointMatrix( bone.translation, bone.rotation );
			//Float4x4 globalMatrix = parentMatrix * boneTransform;
			//joint.orientation = glm::quat(globalMatrix);
			//joint.position = glm::vec3(globalMatrix[3]);
		}

		//joint.orientation = glm::quat(bone.absolute);
		//joint.position = glm::vec3(bone.absolute[3]);

		joint.orientation = glm::normalize(joint.orientation);

		//ptPRINT("Joint[%u]: '%s', parent = %d  (P = %.3f, %.3f, %.3f, Q = %.3f, %.3f, %.3f, %.3f)\n",
		//	boneIndex, bone.name.ToPtr(), bone.parent,
		//	joint.position.iX, joint.position.iY, joint.position.iZ,
		//	joint.orientation.iX, joint.orientation.iY, joint.orientation.iZ, joint.orientation.w);


		skeleton.jointNames[boneIndex] = bone.name;

		Float4x4 jointMatrix = CalculateJointMatrix( joint.position, joint.orientation );

		skeleton.invBindPoses[boneIndex] = glm::inverse(jointMatrix);


		//ptPRINT("Bone[%u]: '%s', absolute = %s,\ncomputed = %s\n",
		//	boneIndex, bone.name.ToPtr(),
		//	MatrixToString(bone.absolute).ToPtr(),
		//	MatrixToString(jointMatrix).ToPtr());


		//ptPRINT("Bone[%u]: '%s', parent = %d (P = %.3f, %.3f, %.3f, Q = %.3f, %.3f, %.3f, %.3f)\n",
		//	boneIndex, bone.name.ToPtr(),
		//	bone.parent, bone.translation.iX, bone.translation.iY, bone.translation.iZ,
		//	bone.rotation.iX, bone.rotation.iY, bone.rotation.iZ, bone.rotation.w);

#endif

	}

	return ALL_OK;
}
示例#2
0
int main() { 
    Object* objects[liveObjects];
    time_t start;

    memset(objects, 0, sizeof(objects));
    start = time(NULL);
    for (size_t i = 0; i < totalObjects; i++) { 
        delete objects[i % liveObjects];
        objects[i % liveObjects] = new Object();
    }
    for (size_t i = 0; i < liveObjects; i++) { 
        delete objects[i];
    }
    printf("Elapsed time for standard new/delete: %ld\n", time(NULL) - start);

    {
        FixedAllocator<Object> fixedAlloc;
        memset(objects, 0, sizeof(objects));
        start = time(NULL);
        
        for (size_t i = 0; i < totalObjects; i++) { 
            fixedAlloc.free(objects[i % liveObjects]);
            objects[i % liveObjects] = fixedAlloc.allocate();
        }
    }
    printf("Elapsed time for fixed size allocator: %ld\n", time(NULL) - start);
    {
        StackAllocator stackAlloc(64*1024);
        GC::ThreadContext<StackAllocator> ctx;
        ctx.set(&stackAlloc);
        memset(objects, 0, sizeof(objects));
        start = time(NULL);
        for (size_t i = 0; i < totalObjects; i++) { 
            if (i % liveObjects == 0) {
                ctx.get()->reset();
            }
            objects[i % liveObjects] = ctx.get()->allocate<Object>();
        }
    }
    printf("Elapsed time for stack allocator: %ld\n", time(NULL) - start);
   
    {
        boost::shared_ptr<Object> objectRefs[liveObjects];
        start = time(NULL);
        for (size_t i = 0; i < totalObjects; i++) { 
            objectRefs[i % liveObjects] = boost::shared_ptr<Object>(new Object());
        }
    }
    printf("Elapsed time boost::shared_ptr: %ld\n", time(NULL) - start);

    {
        std::shared_ptr<Object> objectRefs[liveObjects];
        start = time(NULL);
        for (size_t i = 0; i < totalObjects; i++) { 
            objectRefs[i % liveObjects] = std::shared_ptr<Object>(new Object());
        }
    }
    printf("Elapsed time std::shared_ptr: %ld\n", time(NULL) - start);

    {
        GC::MemoryAllocator mem(1*Mb, 1*Mb);
        GC::ArrayVar<GCObject,liveObjects> objectRefs;
        start = time(NULL);
        for (size_t i = 0; i < totalObjects; i++) { 
            objectRefs[i % liveObjects] = new GCObject();
        }
    }
    printf("Elapsed time for mark&sweep: %ld\n", time(NULL) - start);
    return 0;
}