コード例 #1
0
ファイル: tr_model_psk.cpp プロジェクト: DerSaidin/OpenWolf
/*
=================
R_LoadPSK
=================
*/
qboolean R_LoadPSK(model_t * mod, byte *buffer, int bufferSize, const char *modName)
{
	int             i, j, k;
	memStream_t    *stream;

	axChunkHeader_t	chunkHeader;

	int				numPoints;
	axPoint_t      *point;
	axPoint_t      *points;

	int				numVertexes;
	axVertex_t     *vertex;
	axVertex_t     *vertexes;

	//int				numSmoothGroups;
	int				numTriangles;
	axTriangle_t   *triangle;
	axTriangle_t   *triangles;

	int				numMaterials;
	axMaterial_t   *material;
	axMaterial_t   *materials;

	int				numReferenceBones;
	axReferenceBone_t *refBone;
	axReferenceBone_t *refBones;

	int				numWeights;
	axBoneWeight_t *axWeight;
	axBoneWeight_t *axWeights;

	md5Model_t     *md5;
	md5Bone_t      *md5Bone;
	md5Weight_t    *weight;

	vec3_t          boneOrigin;
	quat_t          boneQuat;
	//matrix_t        boneMat;

	int				materialIndex, oldMaterialIndex;

	int				numRemaining;

	growList_t		sortedTriangles;
	growList_t      vboVertexes;
	growList_t      vboTriangles;
	growList_t      vboSurfaces;

	int				numBoneReferences;
	int				boneReferences[MAX_BONES];

	matrix_t		unrealToQuake;

	//MatrixSetupScale(unrealToQuake, 1, -1, 1);
	MatrixFromAngles(unrealToQuake, 0, 90, 0);

	stream = AllocMemStream(buffer, bufferSize);
	GetChunkHeader(stream, &chunkHeader);

	// check indent again
	if(Q_stricmpn(chunkHeader.ident, "ACTRHEAD", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "ACTRHEAD");
		FreeMemStream(stream);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	mod->type = MOD_MD5;
	mod->dataSize += sizeof(md5Model_t);
	md5 = mod->md5 = (md5Model_t*)ri.Hunk_Alloc(sizeof(md5Model_t), h_low);

	// read points
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "PNTS0000", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "PNTS0000");
		FreeMemStream(stream);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axPoint_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axPoint_t));
		FreeMemStream(stream);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numPoints = chunkHeader.numData;
	points = (axPoint_t*)Com_Allocate(numPoints * sizeof(axPoint_t));
	for(i = 0, point = points; i < numPoints; i++, point++)
	{
		point->point[0] = MemStreamGetFloat(stream);
		point->point[1] = MemStreamGetFloat(stream);
		point->point[2] = MemStreamGetFloat(stream);

#if 0
		// Tr3B: HACK convert from Unreal coordinate system to the Quake one
		MatrixTransformPoint2(unrealToQuake, point->point);
#endif
	}

	// read vertices
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "VTXW0000", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "VTXW0000");
		FreeMemStream(stream);
		Com_Dealloc(points);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axVertex_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axVertex_t));
		FreeMemStream(stream);
		Com_Dealloc(points);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numVertexes = chunkHeader.numData;
	vertexes = (axVertex_t*)Com_Allocate(numVertexes * sizeof(axVertex_t));
	for(i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		vertex->pointIndex = MemStreamGetShort(stream);
		if(vertex->pointIndex < 0 || vertex->pointIndex >= numPoints)
		{
			ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has vertex with point index out of range (%i while max %i)\n", modName, vertex->pointIndex, numPoints);
			FreeMemStream(stream);
			Com_Dealloc(points);
			Com_Dealloc(vertexes);
			return qfalse;
		}

		vertex->unknownA = MemStreamGetShort(stream);
		vertex->st[0] = MemStreamGetFloat(stream);
		vertex->st[1] = MemStreamGetFloat(stream);
		vertex->materialIndex = MemStreamGetC(stream);
		vertex->reserved = MemStreamGetC(stream);
		vertex->unknownB = MemStreamGetShort(stream);

#if 0
		ri.Printf(PRINT_ALL, "R_LoadPSK: axVertex_t(%i):\n"
				"axVertex:pointIndex: %i\n"
				"axVertex:unknownA: %i\n"
				"axVertex::st: %f %f\n"
				"axVertex:materialIndex: %i\n"
				"axVertex:reserved: %d\n"
				"axVertex:unknownB: %d\n",
				i,
				vertex->pointIndex,
				vertex->unknownA,
				vertex->st[0], vertex->st[1],
				vertex->materialIndex,
				vertex->reserved,
				vertex->unknownB);
#endif
	}

	// read triangles
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "FACE0000", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "FACE0000");
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axTriangle_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axTriangle_t));
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numTriangles = chunkHeader.numData;
	triangles = (axTriangle_t*)Com_Allocate(numTriangles * sizeof(axTriangle_t));
	for(i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		for(j = 0; j < 3; j++)
		//for(j = 2; j >= 0; j--)
		{
			triangle->indexes[j] = MemStreamGetShort(stream);
			if(triangle->indexes[j] < 0 || triangle->indexes[j] >= numVertexes)
			{
				ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has triangle with vertex index out of range (%i while max %i)\n", modName, triangle->indexes[j], numVertexes);
				FreeMemStream(stream);
				Com_Dealloc(points);
				Com_Dealloc(vertexes);
				Com_Dealloc(triangles);
				return qfalse;
			}
		}

		triangle->materialIndex = MemStreamGetC(stream);
		triangle->materialIndex2 = MemStreamGetC(stream);
		triangle->smoothingGroups = MemStreamGetLong(stream);
	}

	// read materials
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "MATT0000", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "MATT0000");
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axMaterial_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axMaterial_t));
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numMaterials = chunkHeader.numData;
	materials = (axMaterial_t*)Com_Allocate(numMaterials * sizeof(axMaterial_t));
	for(i = 0, material = materials; i < numMaterials; i++, material++)
	{
		MemStreamRead(stream, material->name, sizeof(material->name));

		ri.Printf(PRINT_ALL, "R_LoadPSK: material name: '%s'\n", material->name);

		material->shaderIndex = MemStreamGetLong(stream);
		material->polyFlags = MemStreamGetLong(stream);
		material->auxMaterial = MemStreamGetLong(stream);
		material->auxFlags = MemStreamGetLong(stream);
		material->lodBias = MemStreamGetLong(stream);
		material->lodStyle = MemStreamGetLong(stream);
	}

	for(i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		if(vertex->materialIndex < 0 || vertex->materialIndex >= numMaterials)
		{
			ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has vertex with material index out of range (%i while max %i)\n", modName, vertex->materialIndex, numMaterials);
			FreeMemStream(stream);
			Com_Dealloc(points);
			Com_Dealloc(vertexes);
			Com_Dealloc(triangles);
			Com_Dealloc(materials);
			return qfalse;
		}
	}

	for(i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		if(triangle->materialIndex < 0 || triangle->materialIndex >= numMaterials)
		{
			ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has triangle with material index out of range (%i while max %i)\n", modName, triangle->materialIndex, numMaterials);
			FreeMemStream(stream);
			Com_Dealloc(points);
			Com_Dealloc(vertexes);
			Com_Dealloc(triangles);
			Com_Dealloc(materials);
			return qfalse;
		}
	}

	// read reference bones
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "REFSKELT", 8))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "REFSKELT");
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axReferenceBone_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axReferenceBone_t));
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numReferenceBones = chunkHeader.numData;
	refBones = (axReferenceBone_t*)Com_Allocate(numReferenceBones * sizeof(axReferenceBone_t));
	for(i = 0, refBone = refBones; i < numReferenceBones; i++, refBone++)
	{
		MemStreamRead(stream, refBone->name, sizeof(refBone->name));

		//ri.Printf(PRINT_ALL, "R_LoadPSK: reference bone name: '%s'\n", refBone->name);

		refBone->flags = MemStreamGetLong(stream);
		refBone->numChildren = MemStreamGetLong(stream);
		refBone->parentIndex = MemStreamGetLong(stream);

		GetBone(stream, &refBone->bone);

#if 0
		ri.Printf(PRINT_ALL, "R_LoadPSK: axReferenceBone_t(%i):\n"
				"axReferenceBone_t::name: '%s'\n"
				"axReferenceBone_t::flags: %i\n"
				"axReferenceBone_t::numChildren %i\n"
				"axReferenceBone_t::parentIndex: %i\n"
				"axReferenceBone_t::quat: %f %f %f %f\n"
				"axReferenceBone_t::position: %f %f %f\n"
				"axReferenceBone_t::length: %f\n"
				"axReferenceBone_t::xSize: %f\n"
				"axReferenceBone_t::ySize: %f\n"
				"axReferenceBone_t::zSize: %f\n",
				i,
				refBone->name,
				refBone->flags,
				refBone->numChildren,
				refBone->parentIndex,
				refBone->bone.quat[0], refBone->bone.quat[1], refBone->bone.quat[2], refBone->bone.quat[3],
				refBone->bone.position[0], refBone->bone.position[1], refBone->bone.position[2],
				refBone->bone.length,
				refBone->bone.xSize,
				refBone->bone.ySize,
				refBone->bone.zSize);
#endif
	}

	// read  bone weights
	GetChunkHeader(stream, &chunkHeader);
	if(Q_stricmpn(chunkHeader.ident, "RAWWEIGHTS", 10))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "RAWWEIGHTS");
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		Com_Dealloc(refBones);
		return qfalse;
	}

	if(chunkHeader.dataSize != sizeof(axBoneWeight_t))
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, sizeof(axBoneWeight_t));
		FreeMemStream(stream);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		Com_Dealloc(refBones);
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numWeights = chunkHeader.numData;
	axWeights = (axBoneWeight_t*)Com_Allocate(numWeights * sizeof(axBoneWeight_t));
	for(i = 0, axWeight = axWeights; i < numWeights; i++, axWeight++)
	{
		axWeight->weight = MemStreamGetFloat(stream);
		axWeight->pointIndex = MemStreamGetLong(stream);
		axWeight->boneIndex = MemStreamGetLong(stream);

#if 0
		ri.Printf(PRINT_ALL, "R_LoadPSK: axBoneWeight_t(%i):\n"
				"axBoneWeight_t::weight: %f\n"
				"axBoneWeight_t::pointIndex %i\n"
				"axBoneWeight_t::boneIndex: %i\n",
				i,
				axWeight->weight,
				axWeight->pointIndex,
				axWeight->boneIndex);
#endif
	}


	//
	// convert the model to an internal MD5 representation
	//
	md5->numBones = numReferenceBones;

	// calc numMeshes <number>
	/*
	numSmoothGroups = 0;
	for(i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		if(triangle->smoothingGroups)
		{

		}
	}
	*/

	if(md5->numBones < 1)
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has no bones\n", modName);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		Com_Dealloc(refBones);
		Com_Dealloc(axWeights);
		return qfalse;
	}
	if(md5->numBones > MAX_BONES)
	{
		ri.Printf(PRINT_WARNING, "R_LoadPSK: '%s' has more than %i bones (%i)\n", modName, MAX_BONES, md5->numBones);
		Com_Dealloc(points);
		Com_Dealloc(vertexes);
		Com_Dealloc(triangles);
		Com_Dealloc(materials);
		Com_Dealloc(refBones);
		Com_Dealloc(axWeights);
		return qfalse;
	}
	//ri.Printf(PRINT_ALL, "R_LoadPSK: '%s' has %i bones\n", modName, md5->numBones);

	// copy all reference bones
	md5->bones = (md5Bone_t*)ri.Hunk_Alloc(sizeof(*md5Bone) * md5->numBones, h_low);
	for(i = 0, md5Bone = md5->bones, refBone = refBones; i < md5->numBones; i++, md5Bone++, refBone++)
	{
		Q_strncpyz(md5Bone->name, refBone->name, sizeof(md5Bone->name));

		if(i == 0)
		{
			md5Bone->parentIndex = refBone->parentIndex -1;
		}
		else
		{
			md5Bone->parentIndex = refBone->parentIndex;
		}

		//ri.Printf(PRINT_ALL, "R_LoadPSK: '%s' has bone '%s' with parent index %i\n", modName, md5Bone->name, md5Bone->parentIndex);

		if(md5Bone->parentIndex >= md5->numBones)
		{
			ri.Error(ERR_DROP, "R_LoadPSK: '%s' has bone '%s' with bad parent index %i while numBones is %i\n", modName,
					 md5Bone->name, md5Bone->parentIndex, md5->numBones);
		}

		for(j = 0; j < 3; j++)
		{
			boneOrigin[j] = refBone->bone.position[j];
		}

		// Tr3B: I have really no idea why the .psk format stores the first quaternion with inverted quats.
		// Furthermore only the X and Z components of the first quat are inverted ?!?!
		if(i == 0)
		{
			boneQuat[0] = refBone->bone.quat[0];
			boneQuat[1] = -refBone->bone.quat[1];
			boneQuat[2] = refBone->bone.quat[2];
			boneQuat[3] = refBone->bone.quat[3];
		}
		else
		{
			boneQuat[0] = -refBone->bone.quat[0];
			boneQuat[1] = -refBone->bone.quat[1];
			boneQuat[2] = -refBone->bone.quat[2];
			boneQuat[3] = refBone->bone.quat[3];
		}

		VectorCopy(boneOrigin, md5Bone->origin);
		//MatrixTransformPoint(unrealToQuake, boneOrigin, md5Bone->origin);

		QuatCopy(boneQuat, md5Bone->rotation);

		//QuatClear(md5Bone->rotation);


#if 0
		ri.Printf(PRINT_ALL, "R_LoadPSK: md5Bone_t(%i):\n"
						"md5Bone_t::name: '%s'\n"
						"md5Bone_t::parentIndex: %i\n"
						"md5Bone_t::quat: %f %f %f %f\n"
						"md5bone_t::position: %f %f %f\n",
						i,
						md5Bone->name,
						md5Bone->parentIndex,
						md5Bone->rotation[0], md5Bone->rotation[1], md5Bone->rotation[2], md5Bone->rotation[3],
						md5Bone->origin[0], md5Bone->origin[1], md5Bone->origin[2]);
#endif

		if(md5Bone->parentIndex >= 0)
		{
			vec3_t          rotated;
			quat_t          quat;

			md5Bone_t      *parent;

			parent = &md5->bones[md5Bone->parentIndex];

			QuatTransformVector(parent->rotation, md5Bone->origin, rotated);
			//QuatTransformVector(md5Bone->rotation, md5Bone->origin, rotated);

			VectorAdd(parent->origin, rotated, md5Bone->origin);

			QuatMultiply1(parent->rotation, md5Bone->rotation, quat);
			QuatCopy(quat, md5Bone->rotation);
		}

		MatrixSetupTransformFromQuat(md5Bone->inverseTransform, md5Bone->rotation, md5Bone->origin);
		MatrixInverse(md5Bone->inverseTransform);

#if 0
		ri.Printf(PRINT_ALL, "R_LoadPSK: md5Bone_t(%i):\n"
						"md5Bone_t::name: '%s'\n"
						"md5Bone_t::parentIndex: %i\n"
						"md5Bone_t::quat: %f %f %f %f\n"
						"md5bone_t::position: %f %f %f\n",
						i,
						md5Bone->name,
						md5Bone->parentIndex,
						md5Bone->rotation[0], md5Bone->rotation[1], md5Bone->rotation[2], md5Bone->rotation[3],
						md5Bone->origin[0], md5Bone->origin[1], md5Bone->origin[2]);
#endif
	}

	Com_InitGrowList(&vboVertexes, 10000);
	for(i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		md5Vertex_t *vboVert = (md5Vertex_t*)Com_Allocate(sizeof(*vboVert));

		for(j = 0; j < 3; j++)
		{
			vboVert->position[j] = points[vertex->pointIndex].point[j];
		}

		vboVert->texCoords[0] = vertex->st[0];
		vboVert->texCoords[1] = vertex->st[1];

		// find number of associated weights
		vboVert->numWeights = 0;
		for(j = 0, axWeight = axWeights; j < numWeights; j++, axWeight++)
		{
			if(axWeight->pointIndex == vertex->pointIndex && axWeight->weight > 0.0f)
			{
				vboVert->numWeights++;
			}
		}

		if(vboVert->numWeights > MAX_WEIGHTS)
		{
			ri.Error(ERR_DROP, "R_LoadPSK: vertex %i requires more weights %i than the maximum of %i in model '%s'", i, vboVert->numWeights, MAX_WEIGHTS, modName);
			//ri.Printf(PRINT_WARNING, "R_LoadPSK: vertex %i requires more weights %i than the maximum of %i in model '%s'\n", i, vboVert->numWeights, MAX_WEIGHTS, modName);
		}

		vboVert->weights = (md5Weight_t**)ri.Hunk_Alloc(sizeof(*vboVert->weights) * vboVert->numWeights, h_low);
		for(j = 0, axWeight = axWeights, k = 0; j < numWeights; j++, axWeight++)
		{
			if(axWeight->pointIndex == vertex->pointIndex && axWeight->weight > 0.0f)
			{
				weight = (md5Weight_t*)ri.Hunk_Alloc(sizeof(*weight), h_low);

				weight->boneIndex = axWeight->boneIndex;
				weight->boneWeight = axWeight->weight;

				// FIXME?
				weight->offset[0] = refBones[axWeight->boneIndex].bone.xSize;
				weight->offset[1] = refBones[axWeight->boneIndex].bone.ySize;
				weight->offset[2] = refBones[axWeight->boneIndex].bone.zSize;

				vboVert->weights[k++] = weight;
			}
		}

		Com_AddToGrowList(&vboVertexes, vboVert);
	}

	ClearBounds(md5->bounds[0], md5->bounds[1]);
	for(i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		AddPointToBounds(points[vertex->pointIndex].point, md5->bounds[0], md5->bounds[1]);
	}

#if 0
	ri.Printf(PRINT_ALL, "R_LoadPSK: AABB (%i %i %i) (%i %i %i)\n",
			(int)md5->bounds[0][0],
			(int)md5->bounds[0][1],
			(int)md5->bounds[0][2],
			(int)md5->bounds[1][0],
			(int)md5->bounds[1][1],
			(int)md5->bounds[1][2]);
#endif

	// sort triangles
	qsort(triangles, numTriangles, sizeof(axTriangle_t), CompareTrianglesByMaterialIndex);

	Com_InitGrowList(&sortedTriangles, 1000);
	for(i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		skelTriangle_t *sortTri = (skelTriangle_t*)Com_Allocate(sizeof(*sortTri));

		for(j = 0; j < 3; j++)
		{
			sortTri->indexes[j] = triangle->indexes[j];
			sortTri->vertexes[j] = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, triangle->indexes[j]);
		}
		sortTri->referenced = qfalse;

		Com_AddToGrowList(&sortedTriangles, sortTri);
	}

	// calc tangent spaces
#if 1
	{
		md5Vertex_t    *v0, *v1, *v2;
		const float    *p0, *p1, *p2;
		const float    *t0, *t1, *t2;
		vec3_t          tangent;
		vec3_t          binormal;
		vec3_t          normal;

		for(j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, j);

			VectorClear(v0->tangent);
			VectorClear(v0->binormal);
			VectorClear(v0->normal);
		}

		for(j = 0; j < sortedTriangles.currentElements; j++)
		{
			skelTriangle_t *tri = (skelTriangle_t*)Com_GrowListElement(&sortedTriangles, j);

			v0 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, tri->indexes[0]);
			v1 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, tri->indexes[1]);
			v2 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, tri->indexes[2]);

			p0 = v0->position;
			p1 = v1->position;
			p2 = v2->position;

			t0 = v0->texCoords;
			t1 = v1->texCoords;
			t2 = v2->texCoords;

#if 1
			R_CalcTangentSpace(tangent, binormal, normal, p0, p1, p2, t0, t1, t2);
#else
			R_CalcNormalForTriangle(normal, p0, p1, p2);
			R_CalcTangentsForTriangle(tangent, binormal, p0, p1, p2, t0, t1, t2);
#endif

			for(k = 0; k < 3; k++)
			{
				float          *v;

				v0 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, tri->indexes[k]);

				v = v0->tangent;
				VectorAdd(v, tangent, v);

				v = v0->binormal;
				VectorAdd(v, binormal, v);

				v = v0->normal;
				VectorAdd(v, normal, v);
			}
		}

		for(j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, j);

			VectorNormalize(v0->tangent);
			VectorNormalize(v0->binormal);
			VectorNormalize(v0->normal);
		}
	}
#else
	{
		float           bb, s, t;
		vec3_t          bary;
		vec3_t			faceNormal;
		md5Vertex_t    *dv[3];

		for(j = 0; j < sortedTriangles.currentElements; j++)
		{
			skelTriangle_t *tri = Com_GrowListElement(&sortedTriangles, j);

			dv[0] = Com_GrowListElement(&vboVertexes, tri->indexes[0]);
			dv[1] = Com_GrowListElement(&vboVertexes, tri->indexes[1]);
			dv[2] = Com_GrowListElement(&vboVertexes, tri->indexes[2]);

			R_CalcNormalForTriangle(faceNormal, dv[0]->position, dv[1]->position, dv[2]->position);

			// calculate barycentric basis for the triangle
			bb = (dv[1]->texCoords[0] - dv[0]->texCoords[0]) * (dv[2]->texCoords[1] - dv[0]->texCoords[1]) - (dv[2]->texCoords[0] - dv[0]->texCoords[0]) * (dv[1]->texCoords[1] -
																												  dv[0]->texCoords[1]);
			if(fabs(bb) < 0.00000001f)
				continue;

			// do each vertex
			for(k = 0; k < 3; k++)
			{
				// calculate s tangent vector
				s = dv[k]->texCoords[0] + 10.0f;
				t = dv[k]->texCoords[1];
				bary[0] = ((dv[1]->texCoords[0] - s) * (dv[2]->texCoords[1] - t) - (dv[2]->texCoords[0] - s) * (dv[1]->texCoords[1] - t)) / bb;
				bary[1] = ((dv[2]->texCoords[0] - s) * (dv[0]->texCoords[1] - t) - (dv[0]->texCoords[0] - s) * (dv[2]->texCoords[1] - t)) / bb;
				bary[2] = ((dv[0]->texCoords[0] - s) * (dv[1]->texCoords[1] - t) - (dv[1]->texCoords[0] - s) * (dv[0]->texCoords[1] - t)) / bb;

				dv[k]->tangent[0] = bary[0] * dv[0]->position[0] + bary[1] * dv[1]->position[0] + bary[2] * dv[2]->position[0];
				dv[k]->tangent[1] = bary[0] * dv[0]->position[1] + bary[1] * dv[1]->position[1] + bary[2] * dv[2]->position[1];
				dv[k]->tangent[2] = bary[0] * dv[0]->position[2] + bary[1] * dv[1]->position[2] + bary[2] * dv[2]->position[2];

				VectorSubtract(dv[k]->tangent, dv[k]->position, dv[k]->tangent);
				VectorNormalize(dv[k]->tangent);

				// calculate t tangent vector (binormal)
				s = dv[k]->texCoords[0];
				t = dv[k]->texCoords[1] + 10.0f;
				bary[0] = ((dv[1]->texCoords[0] - s) * (dv[2]->texCoords[1] - t) - (dv[2]->texCoords[0] - s) * (dv[1]->texCoords[1] - t)) / bb;
				bary[1] = ((dv[2]->texCoords[0] - s) * (dv[0]->texCoords[1] - t) - (dv[0]->texCoords[0] - s) * (dv[2]->texCoords[1] - t)) / bb;
				bary[2] = ((dv[0]->texCoords[0] - s) * (dv[1]->texCoords[1] - t) - (dv[1]->texCoords[0] - s) * (dv[0]->texCoords[1] - t)) / bb;

				dv[k]->binormal[0] = bary[0] * dv[0]->position[0] + bary[1] * dv[1]->position[0] + bary[2] * dv[2]->position[0];
				dv[k]->binormal[1] = bary[0] * dv[0]->position[1] + bary[1] * dv[1]->position[1] + bary[2] * dv[2]->position[1];
				dv[k]->binormal[2] = bary[0] * dv[0]->position[2] + bary[1] * dv[1]->position[2] + bary[2] * dv[2]->position[2];

				VectorSubtract(dv[k]->binormal, dv[k]->position, dv[k]->binormal);
				VectorNormalize(dv[k]->binormal);

				// calculate the normal as cross product N=TxB
#if 0
				CrossProduct(dv[k]->tangent, dv[k]->binormal, dv[k]->normal);
				VectorNormalize(dv[k]->normal);

				// Gram-Schmidt orthogonalization process for B
				// compute the cross product B=NxT to obtain
				// an orthogonal basis
				CrossProduct(dv[k]->normal, dv[k]->tangent, dv[k]->binormal);

				if(DotProduct(dv[k]->normal, faceNormal) < 0)
				{
					VectorInverse(dv[k]->normal);
					//VectorInverse(dv[k]->tangent);
					//VectorInverse(dv[k]->binormal);
				}
#else
				VectorAdd(dv[k]->normal, faceNormal, dv[k]->normal);
#endif
			}
		}

#if 1
		for(j = 0; j < vboVertexes.currentElements; j++)
		{
			dv[0] = Com_GrowListElement(&vboVertexes, j);
			//VectorNormalize(dv[0]->tangent);
			//VectorNormalize(dv[0]->binormal);
			VectorNormalize(dv[0]->normal);
		}
#endif
	}
#endif

#if 0
	{
		md5Vertex_t    *v0, *v1;

		// do another extra smoothing for normals to avoid flat shading
		for(j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = Com_GrowListElement(&vboVertexes, j);

			for(k = 0; k < vboVertexes.currentElements; k++)
			{
				if(j == k)
					continue;

				v1 = Com_GrowListElement(&vboVertexes, k);

				if(VectorCompare(v0->position, v1->position))
				{
					VectorAdd(v0->position, v1->normal, v0->normal);
				}
			}

			VectorNormalize(v0->normal);
		}
	}
#endif

	// split the surfaces into VBO surfaces by the maximum number of GPU vertex skinning bones
	Com_InitGrowList(&vboSurfaces, 10);

	materialIndex = oldMaterialIndex = -1;
	for(i = 0; i < numTriangles; i++)
	{
		triangle = &triangles[i];
		materialIndex = triangle->materialIndex;

		if(materialIndex != oldMaterialIndex)
		{
			oldMaterialIndex = materialIndex;

			numRemaining = sortedTriangles.currentElements - i;
			while(numRemaining)
			{
				numBoneReferences = 0;
				Com_Memset(boneReferences, 0, sizeof(boneReferences));

				Com_InitGrowList(&vboTriangles, 1000);

				for(j = i; j < sortedTriangles.currentElements; j++)
				{
					skelTriangle_t *sortTri;

					triangle = &triangles[j];
					materialIndex = triangle->materialIndex;

					if(materialIndex != oldMaterialIndex)
						continue;

					sortTri = (skelTriangle_t*)Com_GrowListElement(&sortedTriangles, j);

					if(sortTri->referenced)
						continue;

					if(AddTriangleToVBOTriangleList(&vboTriangles, sortTri, &numBoneReferences, boneReferences))
					{
						sortTri->referenced = qtrue;
					}
				}

				for(j = 0; j < MAX_BONES; j++)
				{
					if(boneReferences[j] > 0)
					{
						ri.Printf(PRINT_ALL, "R_LoadPSK: referenced bone: '%s'\n", (j < numReferenceBones) ? refBones[j].name : NULL);
					}
				}

				if(!vboTriangles.currentElements)
				{
					ri.Printf(PRINT_WARNING, "R_LoadPSK: could not add triangles to a remaining VBO surface for model '%s'\n", modName);
					break;
				}

				// FIXME skinIndex
				AddSurfaceToVBOSurfacesList2(&vboSurfaces, &vboTriangles, &vboVertexes, md5, vboSurfaces.currentElements, materials[oldMaterialIndex].name, numBoneReferences, boneReferences);
				numRemaining -= vboTriangles.currentElements;

				Com_DestroyGrowList(&vboTriangles);
			}
		}
	}

	for(j = 0; j < sortedTriangles.currentElements; j++)
	{
		skelTriangle_t *sortTri = (skelTriangle_t*)Com_GrowListElement(&sortedTriangles, j);
		Com_Dealloc(sortTri);
	}
	Com_DestroyGrowList(&sortedTriangles);

	for(j = 0; j < vboVertexes.currentElements; j++)
	{
		md5Vertex_t *v = (md5Vertex_t*)Com_GrowListElement(&vboVertexes, j);
		Com_Dealloc(v);
	}
	Com_DestroyGrowList(&vboVertexes);

	// move VBO surfaces list to hunk
	md5->numVBOSurfaces = vboSurfaces.currentElements;
	md5->vboSurfaces = (srfVBOMD5Mesh_t**)ri.Hunk_Alloc(md5->numVBOSurfaces * sizeof(*md5->vboSurfaces), h_low);

	for(i = 0; i < md5->numVBOSurfaces; i++)
	{
		md5->vboSurfaces[i] = (srfVBOMD5Mesh_t *) Com_GrowListElement(&vboSurfaces, i);
	}

	Com_DestroyGrowList(&vboSurfaces);

	FreeMemStream(stream);
	Com_Dealloc(points);
	Com_Dealloc(vertexes);
	Com_Dealloc(triangles);
	Com_Dealloc(materials);
	Com_Dealloc(refBones);
	Com_Dealloc(axWeights);

	ri.Printf(PRINT_ALL, "%i VBO surfaces created for PSK model '%s'\n", md5->numVBOSurfaces, modName);

	return qtrue;
}
コード例 #2
0
ファイル: mkxsubjreg.c プロジェクト: guo2004131/freesurfer
/*---------------------------------------------------------------*/
int main(int argc, char **argv) {
  char *srcsubj;
  float betplaneres, inplaneres, intensity;
  MATRIX *R, *Xsrc, *invXsrc, *Xtarg, *Rtarg;
  int float2int, err;

  Progname = argv[0] ;
  argc --;
  argv++;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  if (argc == 0) usage_exit();

  parse_commandline(argc, argv);
  check_options();
  dump_options(stdout);

  /* Load the registration matrix, fix if necessary */
  err = regio_read_register(srcregpath, &srcsubj, &inplaneres,
                            &betplaneres, &intensity, &R,
                            &float2int);
  if (err) exit(1);
  printf("---- Input registration matrix --------\n");
  MatrixPrint(stdout,R);

  if (float2int == FLT2INT_TKREG && fixtkreg) {
    if (fvolid == NULL) {
      printf("ERROR: the input registration file requires that you "
             "supply an example functional volume with --fvol\n");
      exit(1);
    }
    FuncMRI = MRIreadHeader(fvolid,MRI_VOLUME_TYPE_UNKNOWN);
    if (FuncMRI==NULL) exit(1);
    printf("INFO: making tkreg matrix compatible with round\n");
    R = MRIfixTkReg(FuncMRI,R);
    printf("---- Fixed input registration matrix --------\n");
    MatrixPrint(stdout,R);
  }
  float2int = FLT2INT_ROUND;

  /* Load the source subject xfm */
  Xsrc = DevolveXFM(srcsubj,NULL,xfmrname);
  if (Xsrc == NULL) exit(1);
  invXsrc = MatrixInverse(Xsrc,NULL);

  /* Load the target subject xfm */
  Xtarg = DevolveXFM(targsubj,NULL,xfmrname);
  if (Xtarg == NULL) exit(1);

  /* Rtarg = R*inv(Xsrc)*Xtarg */
  Rtarg = MatrixMultiply(R,invXsrc,NULL);
  Rtarg = MatrixMultiply(Rtarg,Xtarg,Rtarg);

  printf("---- New registration matrix --------\n");
  MatrixPrint(stdout,Rtarg);

  err = regio_write_register(targregpath, targsubj, inplaneres,
                             betplaneres, intensity, Rtarg, float2int);

  if (err) {
    printf("ERROR: could not write to %s\n",targregpath);
    exit(1);
  }

  return(0);
  exit(0);
}
コード例 #3
0
float computePairCNR(float *LDAmean1, float *LDAmean2, MATRIX *SW1, MATRIX *SW2, float classSize1, float classSize2, int nvolumes_total, float *weights, int flag)
{
  /* if flag == 1, output the optimal weights to weights */
  float cnr;
  int m1, m2;
  MATRIX *SW, *SB, *InvSW;
  float *weight;
  double value1, value2;

  if (classSize1 < 0.5 || classSize2 < 0.5)
  {
    printf("One of the two classes is empty\n");
    return 0;
  }

  SW = (MATRIX *)MatrixAlloc(nvolumes_total, nvolumes_total, MATRIX_REAL);
  SB = (MATRIX *)MatrixAlloc(nvolumes_total, nvolumes_total, MATRIX_REAL);
  weight = (float *)malloc(nvolumes_total*sizeof(float));

  /* initialize all */
  for (m1=1; m1 <= nvolumes_total; m1++)
  {
    for (m2=1; m2 <= nvolumes_total; m2++)
    {
      SW->rptr[m1][m2] = 0.5*(SW1->rptr[m1][m2] + SW2->rptr[m1][m2]); /* index starts from 1 for matrix */
      SB->rptr[m1][m2] = 0.0; /* index starts from 1 for matrix */
    }
    /* weight[m1-1] = 0.0; */ /*initialize later */
  }

  for (m1=1; m1 <= nvolumes_total; m1++)
  {
    value1 = LDAmean1[m1-1]  - LDAmean2[m1-1];
    for (m2=m1; m2 <= nvolumes_total; m2++)
    {
      value2 = LDAmean1[m2-1]  - LDAmean2[m2-1];
      SB->rptr[m1][m2] += value1*value2;
      SB->rptr[m2][m1]  = SB->rptr[m1][m2];
    }
  }

  InvSW = MatrixInverse(SW, NULL);

  /* compute the optimal weight that will give largest CNR for the two
   * classes! Note that the weight differs depending on which formula
   * to use to evaluate final CNR
   * Here, the weight is consistent with the following definition:
   * CNR = |\mu_1 - \mu_2|\sqrt((\sigma_1^2 + \sigma_2^2)*0.5)
   */
  for (m1=1; m1 <= nvolumes_total; m1++)
  {
    weight[m1-1]= 0.0;
    for (m2=1; m2 <= nvolumes_total; m2++)
    {
      weight[m1-1] += InvSW->rptr[m1][m2] *(LDAmean1[m2-1] - LDAmean2[m2-1]);
    }
  }

  /* compute CNR */
  cnr = 0 ;
  value1 = 0.0;
  value2 = 0.0; /* borrowed */
  for (m1=0; m1 < nvolumes_total; m1++)
  {
    cnr += weight[m1]*(LDAmean1[m1] - LDAmean2[m1]);
    if (flag)
    {
      value1 += weight[m1];
      value2 += weight[m1]*weight[m1];
    }
  }

  if (flag && weights != NULL)
  {
    value2 = sqrt(value2);
    for (m1=0; m1 < nvolumes_total; m1++)
    {
      if (value1 > 0)
        weights[m1] = weight[m1]/(value2 + 1e-15);
      else
        weights[m1] = -weight[m1]/(value2 + 1e-15);
    }
  }

  cnr = sqrt(cnr);

  MatrixFree(&SW);
  MatrixFree(&InvSW);
  MatrixFree(&SB);
  free(weight);

  return cnr;
}
コード例 #4
0
ファイル: tr_model_md5.c プロジェクト: SHOVELL/Unvanquished
/*
=================
R_LoadMD5
=================
*/
qboolean R_LoadMD5( model_t *mod, void *buffer, int bufferSize, const char *modName )
{
	int           i, j, k;
	md5Model_t    *md5;
	md5Bone_t     *bone;
	md5Surface_t  *surf;
	md5Triangle_t *tri;
	md5Vertex_t   *v;
	md5Weight_t   *weight;
	int           version;
	shader_t      *sh;
	char          *buf_p;
	char          *token;
	vec3_t        boneOrigin;
	quat_t        boneQuat;
	matrix_t      boneMat;

	buf_p = ( char * ) buffer;

	// skip MD5Version indent string
	COM_ParseExt2( &buf_p, qfalse );

	// check version
	token = COM_ParseExt2( &buf_p, qfalse );
	version = atoi( token );

	if ( version != MD5_VERSION )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: %s has wrong version (%i should be %i)\n", modName, version, MD5_VERSION );
		return qfalse;
	}

	mod->type = MOD_MD5;
	mod->dataSize += sizeof( md5Model_t );
	md5 = mod->model.md5 = ri.Hunk_Alloc( sizeof( md5Model_t ), h_low );

	// skip commandline <arguments string>
	token = COM_ParseExt2( &buf_p, qtrue );
	token = COM_ParseExt2( &buf_p, qtrue );
//  ri.Printf(PRINT_ALL, "%s\n", token);

	// parse numJoints <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "numJoints" ) )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'numJoints' found '%s' in model '%s'\n", token, modName );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	md5->numBones = atoi( token );

	// parse numMeshes <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "numMeshes" ) )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'numMeshes' found '%s' in model '%s'\n", token, modName );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	md5->numSurfaces = atoi( token );
	//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has %i surfaces\n", modName, md5->numSurfaces);

	if ( md5->numBones < 1 )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: '%s' has no bones\n", modName );
		return qfalse;
	}

	if ( md5->numBones > MAX_BONES )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: '%s' has more than %i bones (%i)\n", modName, MAX_BONES, md5->numBones );
		return qfalse;
	}

	//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has %i bones\n", modName, md5->numBones);

	// parse all the bones
	md5->bones = ri.Hunk_Alloc( sizeof( *bone ) * md5->numBones, h_low );

	// parse joints {
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "joints" ) )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'joints' found '%s' in model '%s'\n", token, modName );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );

	if ( Q_stricmp( token, "{" ) )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '{' found '%s' in model '%s'\n", token, modName );
		return qfalse;
	}

	for ( i = 0, bone = md5->bones; i < md5->numBones; i++, bone++ )
	{
		token = COM_ParseExt2( &buf_p, qtrue );
		Q_strncpyz( bone->name, token, sizeof( bone->name ) );

		//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has bone '%s'\n", modName, bone->name);

		token = COM_ParseExt2( &buf_p, qfalse );
		bone->parentIndex = atoi( token );

		//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has bone '%s' with parent index %i\n", modName, bone->name, bone->parentIndex);

		if ( bone->parentIndex >= md5->numBones )
		{
			ri.Error( ERR_DROP, "R_LoadMD5: '%s' has bone '%s' with bad parent index %i while numBones is %i\n", modName,
			          bone->name, bone->parentIndex, md5->numBones );
		}

		// skip (
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '(' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			boneOrigin[ j ] = atof( token );
		}

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected ')' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		// skip (
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '(' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			boneQuat[ j ] = atof( token );
		}

		QuatCalcW( boneQuat );
		MatrixFromQuat( boneMat, boneQuat );

		VectorCopy( boneOrigin, bone->origin );
		QuatCopy( boneQuat, bone->rotation );

		MatrixSetupTransformFromQuat( bone->inverseTransform, boneQuat, boneOrigin );
		MatrixInverse( bone->inverseTransform );

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '(' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}
	}

	// parse }
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "}" ) )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '}' found '%s' in model '%s'\n", token, modName );
		return qfalse;
	}

	// parse all the surfaces
	if ( md5->numSurfaces < 1 )
	{
		ri.Printf( PRINT_WARNING, "R_LoadMD5: '%s' has no surfaces\n", modName );
		return qfalse;
	}

	//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has %i surfaces\n", modName, md5->numSurfaces);

	md5->surfaces = ri.Hunk_Alloc( sizeof( *surf ) * md5->numSurfaces, h_low );

	for ( i = 0, surf = md5->surfaces; i < md5->numSurfaces; i++, surf++ )
	{
		// parse mesh {
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "mesh" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'mesh' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "{" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '{' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		// change to surface identifier
		surf->surfaceType = SF_MD5;

		// give pointer to model for Tess_SurfaceMD5
		surf->model = md5;

		// parse shader <name>
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "shader" ) )
		{
			Q_strncpyz( surf->shader, "<default>", sizeof( surf->shader ) );
			surf->shaderIndex = 0;
		}
		else
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			Q_strncpyz( surf->shader, token, sizeof( surf->shader ) );

			//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' uses shader '%s'\n", modName, surf->shader);

			// FIXME .md5mesh meshes don't have surface names
			// lowercase the surface name so skin compares are faster
			//Q_strlwr(surf->name);
			//ri.Printf(PRINT_ALL, "R_LoadMD5: '%s' has surface '%s'\n", modName, surf->name);

			// register the shaders
			sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );

			if ( sh->defaultShader )
			{
				surf->shaderIndex = 0;
			}
			else
			{
				surf->shaderIndex = sh->index;
			}

			token = COM_ParseExt2( &buf_p, qtrue );
		}

		// parse numVerts <number>
		if ( Q_stricmp( token, "numVerts" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'numVerts' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );
		surf->numVerts = atoi( token );

		if ( surf->numVerts > SHADER_MAX_VERTEXES )
		{
			ri.Error( ERR_DROP, "R_LoadMD5: '%s' has more than %i verts on a surface (%i)",
			          modName, SHADER_MAX_VERTEXES, surf->numVerts );
		}

		surf->verts = ri.Hunk_Alloc( sizeof( *v ) * surf->numVerts, h_low );

		for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ )
		{
			// skip vert <number>
			token = COM_ParseExt2( &buf_p, qtrue );

			if ( Q_stricmp( token, "vert" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'vert' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			COM_ParseExt2( &buf_p, qfalse );

			// skip (
			token = COM_ParseExt2( &buf_p, qfalse );

			if ( Q_stricmp( token, "(" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '(' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			for ( k = 0; k < 2; k++ )
			{
				token = COM_ParseExt2( &buf_p, qfalse );
				v->texCoords[ k ] = atof( token );
			}

			// skip )
			token = COM_ParseExt2( &buf_p, qfalse );

			if ( Q_stricmp( token, ")" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected ')' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			token = COM_ParseExt2( &buf_p, qfalse );
			v->firstWeight = atoi( token );

			token = COM_ParseExt2( &buf_p, qfalse );
			v->numWeights = atoi( token );

			if ( v->numWeights > MAX_WEIGHTS )
			{
				ri.Error( ERR_DROP, "R_LoadMD5: vertex %i requires more than %i weights on surface (%i) in model '%s'",
				          j, MAX_WEIGHTS, i, modName );
			}
		}

		// parse numTris <number>
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "numTris" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'numTris' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );
		surf->numTriangles = atoi( token );

		if ( surf->numTriangles > SHADER_MAX_TRIANGLES )
		{
			ri.Error( ERR_DROP, "R_LoadMD5: '%s' has more than %i triangles on a surface (%i)",
			          modName, SHADER_MAX_TRIANGLES, surf->numTriangles );
		}

		surf->triangles = ri.Hunk_Alloc( sizeof( *tri ) * surf->numTriangles, h_low );

		for ( j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++ )
		{
			// skip tri <number>
			token = COM_ParseExt2( &buf_p, qtrue );

			if ( Q_stricmp( token, "tri" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'tri' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			COM_ParseExt2( &buf_p, qfalse );

			for ( k = 0; k < 3; k++ )
			{
				token = COM_ParseExt2( &buf_p, qfalse );
				tri->indexes[ k ] = atoi( token );
			}
		}

		// parse numWeights <number>
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "numWeights" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'numWeights' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );
		surf->numWeights = atoi( token );

		surf->weights = ri.Hunk_Alloc( sizeof( *weight ) * surf->numWeights, h_low );

		for ( j = 0, weight = surf->weights; j < surf->numWeights; j++, weight++ )
		{
			// skip weight <number>
			token = COM_ParseExt2( &buf_p, qtrue );

			if ( Q_stricmp( token, "weight" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected 'weight' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			COM_ParseExt2( &buf_p, qfalse );

			token = COM_ParseExt2( &buf_p, qfalse );
			weight->boneIndex = atoi( token );

			token = COM_ParseExt2( &buf_p, qfalse );
			weight->boneWeight = atof( token );

			// skip (
			token = COM_ParseExt2( &buf_p, qfalse );

			if ( Q_stricmp( token, "(" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '(' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}

			for ( k = 0; k < 3; k++ )
			{
				token = COM_ParseExt2( &buf_p, qfalse );
				weight->offset[ k ] = atof( token );
			}

			// skip )
			token = COM_ParseExt2( &buf_p, qfalse );

			if ( Q_stricmp( token, ")" ) )
			{
				ri.Printf( PRINT_WARNING, "R_LoadMD5: expected ')' found '%s' in model '%s'\n", token, modName );
				return qfalse;
			}
		}

		// parse }
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "}" ) )
		{
			ri.Printf( PRINT_WARNING, "R_LoadMD5: expected '}' found '%s' in model '%s'\n", token, modName );
			return qfalse;
		}

		// loop trough all vertices and set up the vertex weights
		for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ )
		{
			v->weights = ri.Hunk_Alloc( sizeof( *v->weights ) * v->numWeights, h_low );

			for ( k = 0; k < v->numWeights; k++ )
			{
				v->weights[ k ] = surf->weights + ( v->firstWeight + k );
			}
		}
	}

	// loading is done now calculate the bounding box and tangent spaces
	ClearBounds( md5->bounds[ 0 ], md5->bounds[ 1 ] );

	for ( i = 0, surf = md5->surfaces; i < md5->numSurfaces; i++, surf++ )
	{
		for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ )
		{
			vec3_t      tmpVert;
			md5Weight_t *w;

			VectorClear( tmpVert );

			for ( k = 0, w = v->weights[ 0 ]; k < v->numWeights; k++, w++ )
			{
				vec3_t offsetVec;

				bone = &md5->bones[ w->boneIndex ];

				QuatTransformVector( bone->rotation, w->offset, offsetVec );
				VectorAdd( bone->origin, offsetVec, offsetVec );

				VectorMA( tmpVert, w->boneWeight, offsetVec, tmpVert );
			}

			VectorCopy( tmpVert, v->position );
			AddPointToBounds( tmpVert, md5->bounds[ 0 ], md5->bounds[ 1 ] );
		}

		// calc normals
		{
			const float *v0, *v1, *v2;
			const float *t0, *t1, *t2;
			vec3_t      normal;

			for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ )
			{
				VectorClear( v->tangent );
				VectorClear( v->binormal );
				VectorClear( v->normal );
			}

			for ( j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++ )
			{
				v0 = surf->verts[ tri->indexes[ 0 ] ].position;
				v1 = surf->verts[ tri->indexes[ 1 ] ].position;
				v2 = surf->verts[ tri->indexes[ 2 ] ].position;

				t0 = surf->verts[ tri->indexes[ 0 ] ].texCoords;
				t1 = surf->verts[ tri->indexes[ 1 ] ].texCoords;
				t2 = surf->verts[ tri->indexes[ 2 ] ].texCoords;

				R_CalcNormalForTriangle( normal, v0, v1, v2 );

				for ( k = 0; k < 3; k++ )
				{
					float *v;

					v = surf->verts[ tri->indexes[ k ] ].normal;
					VectorAdd( v, normal, v );
				}
			}

			for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ )
			{
				VectorNormalize( v->normal );
			}
		}

#if 0

		// do another extra smoothing for normals to avoid flat shading
		for ( j = 0; j < surf->numVerts; j++ )
		{
			for ( k = 0; k < surf->numVerts; k++ )
			{
				if ( j == k )
				{
					continue;
				}

				if ( VectorCompare( surf->verts[ j ].position, surf->verts[ k ].position ) )
				{
					VectorAdd( surf->verts[ j ].normal, surf->verts[ k ].normal, surf->verts[ j ].normal );
				}
			}

			VectorNormalize( surf->verts[ j ].normal );
		}

#endif
	}

	return qtrue;
}
コード例 #5
0
int main(int argc, char *argv[])
{

  char **av, *ltafn1, *ltafn2, *ltafn_total;
  LTA *lta1, *lta2, *lta_total;
  FILE *fo;
  MATRIX *r_to_i_1, *i_to_r_1, *i_to_r_2, *r_to_i_2;
  MATRIX *RAS_1_to_1, *RAS_2_to_2, *m_tmp;
  int nargs, ac;
  int type = 0;

  Progname = argv[0];

  nargs = handle_version_option (argc, argv, "$Id: mri_concatenate_lta.c,v 1.5 2011/03/02 00:04:55 nicks Exp $", "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }


  if (argc != 4)
    usage(1);

  ltafn1 = argv[1];
  ltafn2 = argv[2];
  ltafn_total = argv[3];

  printf("Read individual LTAs\n");
  lta1 = ltaReadFileEx(ltafn1);
  if (!lta1)
    ErrorExit(ERROR_BADFILE, "%s: can't read file %s",Progname, ltafn1);

  if (invert1)
  {
    VOL_GEOM vgtmp;
    LT *lt;
    MATRIX *m_tmp = lta1->xforms[0].m_L ;
    lta1->xforms[0].m_L = MatrixInverse(lta1->xforms[0].m_L, NULL) ;
    MatrixFree(&m_tmp) ;
    lt = &lta1->xforms[0];
    if (lt->dst.valid == 0 || lt->src.valid == 0)
    {
      fprintf(stderr, "WARNING:***************************************************************\n");
      fprintf(stderr, "WARNING:dst volume infor is invalid.  Most likely produce wrong inverse.\n");
      fprintf(stderr, "WARNING:***************************************************************\n");
    }
    copyVolGeom(&lt->dst, &vgtmp);
    copyVolGeom(&lt->src, &lt->dst);
    copyVolGeom(&vgtmp, &lt->src);
  }

  type = TransformFileNameType(ltafn2);
  if (type == MNI_TRANSFORM_TYPE)
  {

    if (invert2 != 0)
      ErrorExit(ERROR_BADFILE, "%s: LTA2 is talairach.xfm, and shouldn't be inverted ",Progname);

    lta2 = ltaMNIreadEx(ltafn2) ;
    //the talairach xform is supposed to be linear_RAS_TO_RAS, right? Yes
    lta2->type =  LINEAR_RAS_TO_RAS;

    if (tal_src_file == 0 && lta2->xforms[0].src.valid == 0)
      ErrorExit(ERROR_BADFILE, "%s: pls use -tal option to give talairach src and template filenames",Progname);
    if (tal_dst_file == 0 && lta2->xforms[0].dst.valid == 0)
      ErrorExit(ERROR_BADFILE, "%s: pls use -tal option to give talairach src and template filenames",Progname);

    if (tal_src_file != 0)
      LTAmodifySrcDstGeom(lta2, tal_src, NULL); // add src and dst information
    if (tal_dst_file != 0)
      LTAmodifySrcDstGeom(lta2, NULL, tal_dst); // add src and dst information
  }
  else
    lta2 = ltaReadFileEx(ltafn2);

  if (!lta2)
    ErrorExit(ERROR_BADFILE, "%s: can't read file %s",Progname, ltafn2);

  if (invert2)
  {
    VOL_GEOM vgtmp;
    LT *lt;
    MATRIX *m_tmp = lta2->xforms[0].m_L ;
    lta2->xforms[0].m_L = MatrixInverse(lta2->xforms[0].m_L, NULL) ;
    MatrixFree(&m_tmp) ;
    lt = &lta2->xforms[0];
    if (lt->dst.valid == 0 || lt->src.valid == 0)
    {
      fprintf(stderr, "WARNING:***************************************************************\n");
      fprintf(stderr, "WARNING:dst volume infor is invalid.  Most likely produce wrong inverse.\n");
      fprintf(stderr, "WARNING:***************************************************************\n");
    }
    copyVolGeom(&lt->dst, &vgtmp);
    copyVolGeom(&lt->src, &lt->dst);
    copyVolGeom(&vgtmp, &lt->src);
  }

  if (vg_isEqual(&lta1->xforms[0].dst, &lta2->xforms[0].src) == 0)
  {
    /*    ErrorExit(ERROR_BADFILE, "%s: dst volume of lta1 doesn't match src volume of lta2",Progname);*/
    printf("Warning: dst volume of lta1 doesn't match src volume of lta2\n");
    printf("Volume geometry for lta1-dst:\n");
    vg_print(&lta1->xforms[0].dst);
    printf("Volume geometry for lta2-src:\n");
    vg_print(&lta2->xforms[0].src);
  }

  printf("Combine the two LTAs to get a RAS-to-RAS from src of LTA1 to dst of LTA2\n");

  if (lta1->type == LINEAR_RAS_TO_RAS)
  {
    RAS_1_to_1 =  MatrixCopy(lta1->xforms[0].m_L, NULL);
  }
  else if (lta1->type == LINEAR_VOX_TO_VOX)
  {
    r_to_i_1 = vg_r_to_i(&lta1->xforms[0].src);
    i_to_r_1 = vg_i_to_r(&lta1->xforms[0].dst);
    if (!r_to_i_1 || !i_to_r_1)
      ErrorExit(ERROR_BADFILE, "%s: failed to convert LTA1 to RAS_to_RAS",Progname);
    m_tmp = MatrixMultiply(lta1->xforms[0].m_L, r_to_i_1, NULL);
    RAS_1_to_1 = MatrixMultiply(i_to_r_1, m_tmp, NULL);
    MatrixFree(&m_tmp);
  }
  else
  {
    ErrorExit(ERROR_BADFILE, "%s: unknown transform type for LTA1",Progname);
  }

  if (lta2->type == LINEAR_RAS_TO_RAS)
  {
    RAS_2_to_2 =  MatrixCopy(lta2->xforms[0].m_L, NULL);
  }
  else if (lta2->type == LINEAR_VOX_TO_VOX)
  {
    r_to_i_2 = vg_r_to_i(&lta2->xforms[0].src);
    i_to_r_2 = vg_i_to_r(&lta2->xforms[0].dst);
    if (!r_to_i_2 || !i_to_r_2)
      ErrorExit(ERROR_BADFILE, "%s: failed to convert LTA1 to RAS_to_RAS",Progname);
    m_tmp = MatrixMultiply(lta2->xforms[0].m_L, r_to_i_2, NULL);
    RAS_2_to_2 = MatrixMultiply(i_to_r_2, m_tmp, NULL);
    MatrixFree(&m_tmp);
  }
  else
  {
    ErrorExit(ERROR_BADFILE, "%s: unknown transform type for LTA1",Progname);
  }

  lta_total = LTAalloc(1, NULL);
  lta_total->type = LINEAR_RAS_TO_RAS;
  MatrixMultiply(RAS_2_to_2, RAS_1_to_1, lta_total->xforms[0].m_L);
  lta_total->xforms[0].src = lta1->xforms[0].src;
  lta_total->xforms[0].dst = lta2->xforms[0].dst;
  lta_total->xforms[0].x0 = 0;
  lta_total->xforms[0].y0 = 0;
  lta_total->xforms[0].z0 = 0;
  lta_total->xforms[0].sigma = 1.0f;

  type = TransformFileNameType(ltafn_total);
  if (type == MNI_TRANSFORM_TYPE)
  {
    ltaMNIwrite(lta_total, ltafn_total);
  }
  else
  {
    //change type to VOXEL_VOXEL
    if (lta_total->type != out_type)
      LTAchangeType(lta_total, out_type);

    printf("Write combined LTA to file %s\n", ltafn_total);
    fo = fopen(ltafn_total,"w");
    if (fo==NULL)
      ErrorExit(ERROR_BADFILE, "%s: can't create file %s",Progname, ltafn_total);

    LTAprint(fo, lta_total);

    fclose(fo);
  }

  LTAfree(&lta1);
  LTAfree(&lta2);
  LTAfree(&lta_total);
  MatrixFree(&RAS_1_to_1);
  MatrixFree(&RAS_2_to_2);

  if (tal_src) MRIfree(&tal_src);
  if (tal_dst) MRIfree(&tal_dst);

  return(0);

}  /*  end main()  */
コード例 #6
0
ファイル: main.c プロジェクト: kasicass/frustum
void display(void) {
    float mview[16],imview[16];
    char buffer[128];

    shadowmap();

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45,4.0 / 3.0,1,2048);
    
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(camerapos[0],camerapos[1],camerapos[2], cameradir[0],cameradir[1],cameradir[2], 0,0,1);

    glLightfv(GL_LIGHT0,GL_POSITION,lightpos);

    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
    glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
    glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);

    glEnable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);                        // draw model
    glBindTexture(GL_TEXTURE_2D,texturemodel);
    glPushMatrix();
    glTranslatef(objpos[0],objpos[1],objpos[2]);
    glRotatef(modelangle,0,0,1);
    glCallList(modellist);
    glPopMatrix();
    
    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);

    glDisable(GL_LIGHTING);
    glBindTexture(GL_TEXTURE_2D,textureground);     // draw ground
    glCallList(groundlist);

    glDisable(GL_TEXTURE_2D);
    glPushMatrix();                                 // light sources
    glTranslatef(lightpos[0],lightpos[1],lightpos[2]);
    glColor4f(0,1,0,1);
    glCallList(lightlist);
    glColor4f(1,1,1,1);
    glPopMatrix();
    
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
    glEnable(GL_TEXTURE_GEN_R);
    glEnable(GL_TEXTURE_GEN_Q);
    glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
    glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
    glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
    glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);

    glGetFloatv(GL_MODELVIEW_MATRIX,mview);
    MatrixInverse(mview,imview);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glTranslatef(0.5,0.5,0);
    glScalef(0.5,0.5,1.0);
    glOrtho(-modelsize,modelsize,-modelsize,modelsize,-1,1);
    gluLookAt(lightpos[0],lightpos[1],lightpos[2], objpos[0],objpos[1],objpos[2], 0,1,0);
    glMultMatrixf(imview);

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);                             // shadow
    glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR);
    glBindTexture(GL_TEXTURE_2D,textureshadow);
    glCallList(groundlist);
    glDisable(GL_BLEND);
    
    glMatrixMode(GL_MODELVIEW);
    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
    glDisable(GL_TEXTURE_GEN_R);
    glDisable(GL_TEXTURE_GEN_Q);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1,1,-1,1,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glColor4f(1,1,1,1);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_LIGHTING);
    sprintf(buffer,"fps: %.2f",getfps());
    drawstring(-0.95,0.95,buffer);
    glEnable(GL_DEPTH_TEST);
    
    glutSwapBuffers();
}
コード例 #7
0
int
MRIcomputePartialVolumeFractions(MRI *mri_src, MATRIX *m_vox2vox, 
                                 MRI *mri_seg, MRI *mri_wm, MRI *mri_subcort_gm, MRI *mri_cortex,
				 MRI *mri_csf,
                                 int wm_val, int subcort_gm_val, int cortex_val, int csf_val)
{
  int    x, y, z, xs, ys, zs, label ;
  VECTOR *v1, *v2 ;
  MRI    *mri_counts ;
  float  val, count ;
  MATRIX *m_inv ;

  m_inv = MatrixInverse(m_vox2vox, NULL) ;
  if (m_inv == NULL)
  {
    MatrixPrint(stdout, m_vox2vox) ;
    ErrorExit(ERROR_BADPARM, "MRIcomputePartialVolumeFractions: non-invertible vox2vox matrix");
  }
  mri_counts = MRIcloneDifferentType(mri_src, MRI_INT) ;

  v1 = VectorAlloc(4, MATRIX_REAL) ;
  v2 = VectorAlloc(4, MATRIX_REAL) ;
  VECTOR_ELT(v1, 4) = 1.0 ; VECTOR_ELT(v2, 4) = 1.0 ;
  for (x = 0 ; x < mri_seg->width ; x++)
  {
    V3_X(v1) = x ;
    for (y = 0 ; y < mri_seg->height ; y++)
    {
      V3_Y(v1) = y ;
      for (z = 0 ; z < mri_seg->depth ; z++)
      {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        V3_Z(v1) = z ;
        MatrixMultiply(m_vox2vox, v1, v2) ;
        xs = nint(V3_X(v2)) ; ys = nint(V3_Y(v2)) ; zs = nint(V3_Z(v2)) ;
        if (xs >= 0 && ys >= 0 && zs >= 0 &&
            xs < mri_src->width && ys < mri_src->height && zs < mri_src->depth)
        {
          val = MRIgetVoxVal(mri_counts, xs, ys, zs, 0) ;
          MRIsetVoxVal(mri_counts, xs, ys, zs, 0, val+1) ;

          label = MRIgetVoxVal(mri_seg, x, y, z, 0) ;
          if (label == csf_val)
          {
            val = MRIgetVoxVal(mri_csf, xs, ys, zs, 0) ;
            MRIsetVoxVal(mri_csf, xs, ys, zs, 0, val+1) ;
          }
          else if (label == wm_val)
          {
            val = MRIgetVoxVal(mri_wm, xs, ys, zs, 0) ;
            MRIsetVoxVal(mri_wm, xs, ys, zs, 0, val+1) ;
          }
          else if (label == subcort_gm_val)
          {
            val = MRIgetVoxVal(mri_subcort_gm, xs, ys, zs, 0) ;
            MRIsetVoxVal(mri_subcort_gm, xs, ys, zs, 0, val+1) ;
          }
          else if (label == cortex_val)
          {
            val = MRIgetVoxVal(mri_cortex, xs, ys, zs, 0) ;
            MRIsetVoxVal(mri_cortex, xs, ys, zs, 0, val+1) ;
          }
          else
            DiagBreak() ;
        }
      }
    }
  }

  for (x = 0 ; x < mri_src->width ; x++)
    for (y = 0 ; y < mri_src->height ; y++)
      for (z = 0 ; z < mri_src->depth ; z++)
      {
        count = MRIgetVoxVal(mri_counts, x, y, z, 0) ;
        if (count >= 1)
        {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          val = MRIgetVoxVal(mri_wm, x, y, z, 0) ;
          MRIsetVoxVal(mri_wm, x, y, z, 0, val/count) ;
          val = MRIgetVoxVal(mri_subcort_gm, x, y, z, 0) ;
          MRIsetVoxVal(mri_subcort_gm, x, y, z, 0, val/count) ;
          val = MRIgetVoxVal(mri_cortex, x, y, z, 0) ;
          MRIsetVoxVal(mri_cortex, x, y, z, 0, val/count) ;
          val = MRIgetVoxVal(mri_csf, x, y, z, 0) ;
          MRIsetVoxVal(mri_csf, x, y, z, 0, val/count) ;
        }
        else  // sample in other direction
        {
          V3_X(v1) = x ; V3_Y(v1) = y ; V3_Z(v1) = z ;
          MatrixMultiply(m_inv, v1, v2) ;
          MatrixMultiply(m_inv, v1, v2) ;
          xs = nint(V3_X(v2)) ; ys = nint(V3_Y(v2)) ; zs = nint(V3_Z(v2)) ;
          if (xs >= 0 && ys >= 0 && zs >= 0 &&
              xs < mri_seg->width && ys < mri_seg->height && zs < mri_seg->depth)
          {
            label = MRIgetVoxVal(mri_seg, xs, ys, zs, 0) ;
            if (label == csf_val)
              MRIsetVoxVal(mri_csf, x, y, z, 0, 1) ;
            else if (label == wm_val)
              MRIsetVoxVal(mri_wm, x, y, z, 0, 1) ;
            else if (label == subcort_gm_val)
              MRIsetVoxVal(mri_subcort_gm, x, y, z, 0, 1) ;
            else if (cortex_val)
              MRIsetVoxVal(mri_cortex, x, y, z, 0, 1) ;
            else
              DiagBreak() ;
          }
        }
      }
  VectorFree(&v1) ; VectorFree(&v2) ; MatrixFree(&m_inv) ;
  MRIfree(&mri_counts) ;

  return(NO_ERROR) ;
}
コード例 #8
0
ファイル: PMDIK.cpp プロジェクト: r1cebank/MMDRender
//======
// 更新
//======
void cPMDIK::update( void )
{
	Vector3	vec3OrgTargetPos;
	vec3OrgTargetPos.x = m_pTargetBone->m_matLocal[3][0];
	vec3OrgTargetPos.y = m_pTargetBone->m_matLocal[3][1];
	vec3OrgTargetPos.z = m_pTargetBone->m_matLocal[3][2];

	Vector3	vec3EffPos;
	Vector3	vec3TargetPos;

	for( short i = m_cbNumLink - 1 ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); }
	m_pEffBone->updateMatrix();

	for( unsigned short it = 0 ; it < m_unCount ; it++ )
	{
		for( unsigned char cbLinkIdx = 0 ; cbLinkIdx < m_cbNumLink ; cbLinkIdx++ )
		{
			// エフェクタの位置の取得
			vec3EffPos.x = m_pEffBone->m_matLocal[3][0];
			vec3EffPos.y = m_pEffBone->m_matLocal[3][1];
			vec3EffPos.z = m_pEffBone->m_matLocal[3][2];

			// ワールド座標系から注目ノードの局所(ローカル)座標系への変換
			Matrix	matInvBone;
			MatrixInverse( matInvBone, m_ppBoneList[cbLinkIdx]->m_matLocal );

			// エフェクタ,到達目標のローカル位置
			Vector3Transform( &vec3EffPos, &vec3EffPos, matInvBone );
			Vector3Transform( &vec3TargetPos, &vec3OrgTargetPos, matInvBone );

			// 十分近ければ終了
			Vector3	vec3Diff;
			Vector3Sub( &vec3Diff, &vec3EffPos, &vec3TargetPos );
			if( Vector3DotProduct( &vec3Diff, &vec3Diff ) < 0.0000001f )	return;

			// (1) 基準関節→エフェクタ位置への方向ベクトル
			Vector3Normalize( &vec3EffPos, &vec3EffPos );

			// (2) 基準関節→目標位置への方向ベクトル
			Vector3Normalize( &vec3TargetPos, &vec3TargetPos );

			// ベクトル (1) を (2) に一致させるための最短回転量(Axis-Angle)
			//
			// 回転角
			float	fRotAngle = acosf( Vector3DotProduct( &vec3EffPos, &vec3TargetPos ) );

			if( 0.00000001f < fabsf( fRotAngle ) )
			{
				if( fRotAngle < -m_fFact )	fRotAngle = -m_fFact;
				else if( m_fFact < fRotAngle )	fRotAngle = m_fFact;

				// 回転軸
				Vector3 vec3RotAxis;

				Vector3CrossProduct( &vec3RotAxis, &vec3EffPos, &vec3TargetPos );
				if( Vector3DotProduct( &vec3RotAxis, &vec3RotAxis ) < 0.0000001f )	continue;

				Vector3Normalize( &vec3RotAxis, &vec3RotAxis );

				// 関節回転量の補正
				Vector4		vec4RotQuat;
				QuaternionCreateAxis( &vec4RotQuat, &vec3RotAxis, fRotAngle );

				if( m_ppBoneList[cbLinkIdx]->m_bIKLimitAngle )	limitAngle( &vec4RotQuat, &vec4RotQuat );

				QuaternionNormalize( &vec4RotQuat, &vec4RotQuat );

				QuaternionMultiply( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &vec4RotQuat );
				QuaternionNormalize( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation );

				for( short i = cbLinkIdx ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); }
				m_pEffBone->updateMatrix();
			}
		}
	}
}
コード例 #9
0
int main(int argc, char *argv[]) {
  char **av;
  char *fslfn, *ltafn;
  MRI *mri_src, *mri_tgt;
  int ac, nargs;
  LTA *mylta = 0;
  FILE *fo;
  VOL_GEOM srcG, dstG;
  MATRIX *invTgt, *Dsrc, *V_to_V;

  Progname = argv[0];

  nargs = handle_version_option (argc, argv, "$Id: mri_fslmat_to_lta.c,v 1.3 2011/03/02 00:04:15 nicks Exp $", "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc != 5)
    usage(1);

  printf("Read source volume file %s\n", argv[1]);
  mri_src = MRIread(argv[1]) ;

  if (!mri_src)
    ErrorExit(ERROR_BADPARM, "%s: could not read source volume %s",
              Progname, argv[1]) ;

  printf("Read destination volume file %s\n", argv[2]);
  mri_tgt = MRIread(argv[2]) ;
  if (!mri_tgt)
    ErrorExit(ERROR_BADPARM, "%s: could not read label volume %s",
              Progname, argv[2]) ;

  fslfn = argv[3];
  ltafn = argv[4];

  printf("Read fsl transformation from file %s\n", fslfn);
  mylta = ltaFSLread(fslfn);

  getVolGeom(mri_src, &srcG);
  getVolGeom(mri_tgt, &dstG);

  if (invert_flag) {
    mylta->xforms[0].src = dstG;
    mylta->xforms[0].dst = srcG;
  } else {
    mylta->xforms[0].src = srcG;
    mylta->xforms[0].dst = dstG;
  }

  invTgt = MatrixAlloc(4,4,MATRIX_REAL);
  invTgt->rptr[1][1] = 1.0/dstG.xsize;
  invTgt->rptr[2][2] = 1.0/dstG.ysize;
  invTgt->rptr[3][3] = 1.0/dstG.zsize;
  invTgt->rptr[4][4] = 1.0;

  Dsrc = MatrixAlloc(4,4,MATRIX_REAL);
  Dsrc->rptr[1][1] = srcG.xsize;
  Dsrc->rptr[2][2] = srcG.ysize;
  Dsrc->rptr[3][3] = srcG.zsize;
  Dsrc->rptr[4][4] = 1.0;

  V_to_V = MatrixMultiply(invTgt, mylta->xforms[0].m_L, NULL);
  V_to_V = MatrixMultiply(V_to_V, Dsrc, V_to_V);

  if (invert_flag) {
    mylta->xforms[0].m_L = MatrixInverse(V_to_V, mylta->xforms[0].m_L);
  } else {
    mylta->xforms[0].m_L = MatrixCopy(V_to_V, mylta->xforms[0].m_L);
  }

  if (!mylta) {
    MRIfree(&mri_src);
    MRIfree(&mri_tgt);
    ErrorExit(ERROR_BADFILE, "%s: can't read in transformation",Progname);
  }

  printf("Write transformation to lta file %s\n", ltafn);
  fo = fopen(ltafn,"w");
  if (fo==NULL)
    ErrorExit(ERROR_BADFILE, "%s: can't create file %s",Progname, ltafn);

  LTAprint(fo, mylta);

  fclose(fo);


  MRIfree(&mri_src);
  MRIfree(&mri_tgt);

  LTAfree(&mylta);

  MatrixFree(&invTgt);
  MatrixFree(&Dsrc);
  MatrixFree(&V_to_V);

  return(0);

}  /*  end main()  */
コード例 #10
0
	void CEditRenderPipeline::SetRenderStyle( const STATIC_RS& RenderStyle )
	{
		//m_pipeline->SetRenderStyle(RenderStyle);
		//return ;

		m_GraphicRenderStyle.m_Material = RenderStyle.m_Material;
		CRenderPipeline::GetInst()->SetShader(RenderStyle.m_ShaderType);
		_SetMaterial( m_GraphicRenderStyle.m_Material );
		_SetRenderStyle ( RS_ALPHAREF, RenderStyle.m_Alpharef );

		if (m_GraphicRenderStyle.m_Texturefactor!=RenderStyle.m_Texturefactor || bReFreshTexFactor)
		{
			m_GraphicRenderStyle.m_Texturefactor = RenderStyle.m_Texturefactor;
			_SetRenderStyle ( RS_TEXTUREFACTOR, m_GraphicRenderStyle.m_Texturefactor );
			CColor4 factor = m_GraphicRenderStyle.m_Texturefactor;
			SetFragmentShaderF(ACT_TEXTURE_FACTOR, factor.r, factor.g, factor.b, factor.a);
			bReFreshTexFactor = false;
		}

		float	Params[4];
		Params[0] = (float)RenderStyle.m_Alpharef;
		Params[1] = (float)RenderStyle.m_Material.Diffuse.a;
		Params[2] = (float)RenderStyle.m_Material.Specular.a;
		SetVertexShaderF(ACT_TEXTURE_FACTOR,Params,1);

		CColor4 tSpecular(0.0f,0.0f,0.0f,0.0f);
		if (RenderStyle.m_SpecularEnable)
		{
			tSpecular = m_GraphicRenderStyle.m_Material.Specular;
			tSpecular.a = m_GraphicRenderStyle.m_Material.Power;
		}

		SetVertexShaderF(ACT_MAT_DIFFUSE_COLOR	, (float*)&m_GraphicRenderStyle.m_Material.Diffuse, 1);
		SetVertexShaderF(ACT_MAT_AMBIENT_COLOR	, (float*)&m_GraphicRenderStyle.m_Material.Ambient, 1);
		SetVertexShaderF(ACT_MAT_SPECULAR_COLOR	, (float*)&tSpecular, 1);
		SetVertexShaderF(ACT_MAT_EMISSIVE_COLOR	, (float*)&m_GraphicRenderStyle.m_Material.Emissive, 1);
		
		SetVertexShaderF(ACT_REFRACT_SCALAR	, RenderStyle.m_fRefractIndex);
		SetVertexShaderF(ACT_UV_INDEX , float(RenderStyle.m_Uv_S0) , float(RenderStyle.m_Uv_S1) , float(RenderStyle.m_Uv_S2) );

		//_SetRenderStyle ( RS_SLOPESCALEDEPTHBIAS, *(DWORD*)&(RenderStyle.m_fSlopeScaleZBias));
		_SetRenderStyle ( RS_DEPTHBIAS, *(DWORD*)&(RenderStyle.m_fZBias));
		_SetRenderStyle ( RS_ALPHABLENDENABLE,  RenderStyle.m_AlphaBlendEnable );
		_SetRenderStyle ( RS_SRCBLEND, RenderStyle.m_SrcBlend );
		_SetRenderStyle ( RS_DESTBLEND, RenderStyle.m_DestBlend );
		_SetRenderStyle ( RS_ALPHATESTENABLE,  RenderStyle.m_AlphaTestEnable );
		_SetRenderStyle ( RS_ALPHAFUNC, RenderStyle.m_AlphaTestFun );
		_SetRenderStyle ( RS_LIGHTING, RenderStyle.m_LightEnable );
		_SetRenderStyle ( RS_SPECULARENABLE,  RenderStyle.m_SpecularEnable );
		_SetRenderStyle ( RS_ZENABLE,  RenderStyle.m_ZTestEnable );
		_SetRenderStyle ( RS_ZFUNC,  RenderStyle.m_ZTestFun );
		_SetRenderStyle ( RS_ZWRITEENABLE, RenderStyle.m_ZWrite );
		_SetRenderStyle ( RS_CULLMODE, RenderStyle.m_Cull );
		_SetRenderStyle ( RS_FILLMODE, RenderStyle.m_FillMode );
		bool isClipPlaneValid = RenderStyle.m_ClipPlane.IsValid();
		if (isClipPlaneValid)
		{
			CPlane plane = RenderStyle.m_ClipPlane;
			if (RenderStyle.m_ShaderType.GetVSShaderID())
			{
				// transform to clipping space
				CMatrix transform = m_CurViewProj;
				MatrixInverse(transform);
				transform.Transpose();
				plane.Transform(transform);
			}
			_SetClipPlane(0, plane);
		}
		_SetRenderStyle( RS_CLIPPLANEENABLE, DWORD(isClipPlaneValid ? CLIPPLANE0 : 0) );
		SetTextureEx(RenderStyle);
	}
コード例 #11
0
ファイル: mri_mask.c プロジェクト: ewong718/freesurfer
int main(int argc, char *argv[])
{
  char **av;
  MRI *mri_src, *mri_mask, *mri_dst ;
  int nargs, ac, nmask;
  int x, y, z;
  float value;
  MRI_REGION *region;
  LTA          *lta = 0;
  int          transform_type;
  MRI *mri_tmp;

  nargs =
    handle_version_option
    (
      argc, argv,
      "$Id: mri_mask.c,v 1.18 2012/12/07 22:45:50 greve Exp $", "$Name:  $"
    );
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs ;

  Progname = argv[0];
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc != 4)
  {
    printf("Incorrect number of arguments, argc = %d\n", argc);
    usage(1);
  }

  mri_src = MRIread(argv[1]) ;
  if (!mri_src)
    ErrorExit(ERROR_BADPARM, "%s: could not read source volume %s",
              Progname, argv[1]) ;
  mri_mask = MRIread(argv[2]) ;
  if (!mri_mask)
    ErrorExit(ERROR_BADPARM, "%s: could not read mask volume %s",
              Progname, argv[2]) ;

  if(mri_src->width != mri_mask->width)
  {
    printf("ERROR: dimension mismatch between source and mask\n");
    exit(1);
  }

  printf("DoAbs = %d\n",DoAbs);

  /* Read LTA transform and apply it to mri_mask */
  if (xform_fname != NULL)
  {

    printf("Apply the given LTA xfrom to the mask volume\n");
    // read transform
    transform_type =  TransformFileNameType(xform_fname);

    if (transform_type == MNI_TRANSFORM_TYPE ||
        transform_type == TRANSFORM_ARRAY_TYPE ||
        transform_type == REGISTER_DAT ||
        transform_type == FSLREG_TYPE
       )
    {
      printf("Reading transform ...\n");
      lta = LTAreadEx(xform_fname) ;
      if (!lta)
        ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s",
                  Progname, xform_fname) ;

      if (transform_type == FSLREG_TYPE)
      {
        if (lta_src == 0 || lta_dst == 0)
        {
          fprintf(stderr,
                  "ERROR: fslmat does not have information on "
                  "the src and dst volumes\n");
          fprintf(stderr,
                  "ERROR: you must give options '-lta_src' "
                  "and '-lta_dst' to specify the src and dst volume infos\n");
        }

        LTAmodifySrcDstGeom(lta, lta_src, lta_dst);
        // add src and dst information
        LTAchangeType(lta, LINEAR_VOX_TO_VOX);
      }

      if (lta->xforms[0].src.valid == 0)
      {
        if (lta_src == 0)
        {
          fprintf(stderr,
                  "The transform does not have the valid src volume info.\n");
          fprintf(stderr,
                  "Either you give src volume info by option -lta_src or\n");
          fprintf(stderr,
                  "make the transform to have the valid src info.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information
          //      getVolGeom(lta_src, &lt->src);
        }
      }
      if (lta->xforms[0].dst.valid == 0)
      {
        if (lta_dst == 0)
        {
          fprintf(stderr,
                  "The transform does not have the valid dst volume info.\n");
          fprintf(stderr,
                  "Either you give src volume info by option -lta_dst or\n");
          fprintf(stderr,
                  "make the transform to have the valid dst info.\n");
          fprintf(stderr,
                  "If the dst was average_305, then you can set\n");
          fprintf(stderr,
                  "environmental variable USE_AVERAGE305 true\n");
          fprintf(stderr,
                  "without giving the dst volume for RAS-to-RAS transform.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add  dst information
        }
      }
    }
    else
    {
      ErrorExit(ERROR_BADPARM,
                "transform is not of MNI, nor Register.dat, nor FSLMAT type");
    }

    if (invert)
    {
      VOL_GEOM vgtmp;
      LT *lt;
      MATRIX *m_tmp = lta->xforms[0].m_L ;
      lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ;
      MatrixFree(&m_tmp) ;
      lt = &lta->xforms[0];
      if (lt->dst.valid == 0 || lt->src.valid == 0)
      {
        fprintf(stderr,
                "WARNING:**************************************"
                "*************************\n");
        fprintf(stderr,
                "WARNING:dst volume information is invalid.  "
                "Most likely produced wrong inverse.\n");
        fprintf(stderr,
                "WARNING:**************************************"
                "*************************\n");
      }
      copyVolGeom(&lt->dst, &vgtmp);
      copyVolGeom(&lt->src, &lt->dst);
      copyVolGeom(&vgtmp, &lt->src);
    }

    //    LTAchangeType(lta, LINEAR_VOX_TO_VOX);
    mri_tmp =
      MRIalloc(mri_src->width,
               mri_src->height,
               mri_src->depth,
               mri_mask->type) ;
    MRIcopyHeader(mri_src, mri_tmp) ;

    mri_tmp = LTAtransformInterp(mri_mask, mri_tmp, lta, InterpMethod);

    // mri_tmp =
    //MRIlinearTransformInterp
    //  (
    //   mri_mask, mri_tmp, lta->xforms[0].m_L, InterpMethod
    //  );

    MRIfree(&mri_mask);

    mri_mask = mri_tmp;

    if (lta_src)
    {
      MRIfree(&lta_src);
    }
    if (lta_dst)
    {
      MRIfree(&lta_dst);
    }
    if (lta)
    {
      LTAfree(&lta);
    }
  }   /* if (xform_fname != NULL) */

  // Threshold mask
  nmask = 0;
  for (z = 0 ; z <mri_mask->depth ; z++)
  {
    for (y = 0 ; y < mri_mask->height ; y++)
    {
      for (x = 0 ; x < mri_mask->width ; x++)
      {
        value = MRIgetVoxVal(mri_mask, x, y, z, 0);
        if(DoAbs)
        {
          value = fabs(value);
        }
        if(value <= threshold)
        {
          MRIsetVoxVal(mri_mask,x,y,z,0,0);
        }
        else
        {
          nmask ++;
        }
      }
    }
  }
  printf("Found %d voxels in mask (pct=%6.2f)\n",nmask,
	 100.0*nmask/(mri_mask->width*mri_mask->height*mri_mask->depth));

  if(DoBB){
    printf("Computing bounding box, npad = %d\n",nPadBB);
    region = REGIONgetBoundingBox(mri_mask,nPadBB);
    REGIONprint(stdout, region);
    mri_tmp = MRIextractRegion(mri_mask, NULL, region);
    if(mri_tmp == NULL) exit(1);
    MRIfree(&mri_mask);
    mri_mask = mri_tmp;
    mri_tmp = MRIextractRegion(mri_src, NULL, region);
    if(mri_tmp == NULL) exit(1);
    MRIfree(&mri_src);
    mri_src = mri_tmp;
  }

  int mask=0;
  float out_val=0;
  if (do_transfer)
  {
    mask = (int)transfer_val;
    out_val = transfer_val;
  }
  mri_dst = MRImask(mri_src, mri_mask, NULL, mask, out_val) ;
  if (!mri_dst)
  {
    ErrorExit(Gerror, "%s: stripping failed", Progname) ;
  }

  if (keep_mask_deletion_edits)
  {
    mri_dst = MRImask(mri_dst, mri_mask, NULL, 1, 1) ; // keep voxels = 1
    if (!mri_dst)
      ErrorExit(Gerror, "%s: stripping failed on keep_mask_deletion_edits",
                Progname) ;
  }

  printf("Writing masked volume to %s...", argv[3]) ;
  MRIwrite(mri_dst, argv[3]);
  printf("done.\n") ;

  MRIfree(&mri_src);
  MRIfree(&mri_mask);
  MRIfree(&mri_dst);

  exit(0);

}  /*  end main()  */
コード例 #12
0
int
main(int argc, char *argv[]) {
  char         *ref_fname, *in_fname, *out_fname, fname[STRLEN], **av ;
  MRI          *mri_ref, *mri_in, *mri_orig, *mri_in_red, *mri_ref_red,
  *mri_in_tmp, *mri_ref_tmp, *mri_ref_orig, *mri_in_orig ;
  int          ac, nargs, i, msec, minutes, seconds ;
  struct timeb start ;
  MATRIX       *m_L ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_linear_register.c,v 1.13 2011/03/02 00:04:22 nicks Exp $", "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  parms.mri_crop = NULL ;
  parms.l_intensity = 1.0f ;
  parms.niterations = 100 ;
  parms.levels = -1 ;   /* use default */
  parms.dt = 1e-6 ;  /* was 5e-6 */
  parms.tol = INTEGRATION_TOL*5 ;

  parms.dt = 5e-6 ;  /* was 5e-6 */
  parms.tol = 1e-3 ;
  parms.momentum = 0.8 ;
  parms.max_levels = MAX_LEVELS ;
  parms.factor = 1.0 ;
  parms.niterations = 25 ;
  Progname = argv[0] ;


  DiagInit(NULL, NULL, NULL) ;
  ErrorInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc < 4)
    ErrorExit(ERROR_BADPARM,
              "usage: %s <in brain> <template> <output file name>\n",
              Progname) ;

  in_fname = argv[1] ;
  ref_fname = argv[2] ;
  if (xform_mean_fname) {
    int   sno, nsubjects ;
    FILE  *fp ;

    parms.m_xform_mean = MatrixAsciiRead(xform_mean_fname, NULL) ;
    if (!parms.m_xform_mean)
      ErrorExit(Gerror, "%s: could not read parameter means from %s",
                Progname, xform_mean_fname) ;

    fp = fopen(xform_covariance_fname, "r") ;
    if (!fp)
      ErrorExit(ERROR_NOFILE, "%s: could not read covariances from %s",
                Progname, xform_covariance_fname) ;

    fscanf(fp, "nsubjects=%d", &nsubjects) ;
    printf("reading %d transforms...\n", nsubjects) ;

    parms.m_xforms = (MATRIX **)calloc(nsubjects, sizeof(MATRIX *)) ;
    if (!parms.m_xforms)
      ErrorExit(ERROR_NOMEMORY, "%s: could not allocate array of %d xforms",
                Progname, nsubjects) ;
    for (sno = 0 ; sno < nsubjects ; sno++) {
      parms.m_xforms[sno] = MatrixAsciiReadFrom(fp, NULL) ;
      if (!parms.m_xforms[sno])
        ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dth xform",
                  Progname, sno) ;

    }
    parms.m_xform_covariance = MatrixAsciiReadFrom(fp, NULL) ;
    if (!parms.m_xform_covariance)
      ErrorExit(Gerror, "%s: could not read parameter covariance from %s",
                Progname, xform_covariance_fname) ;
    fclose(fp) ;
    parms.l_priors = l_priors ;
    parms.nxforms = nsubjects ;
  }
  out_fname = argv[3] ;
  FileNameOnly(out_fname, fname) ;
  FileNameRemoveExtension(fname, fname) ;
  strcpy(parms.base_name, fname) ;
  fprintf(stderr, "logging results to %s.log\n", parms.base_name) ;

  TimerStart(&start) ;
  fprintf(stderr, "reading '%s'...\n", ref_fname) ;
  fflush(stderr) ;
  mri_ref = MRIread(ref_fname) ;
  if (!mri_ref)
    ErrorExit(ERROR_NOFILE, "%s: could not open reference volume %s.\n",
              Progname, ref_fname) ;
  if (mri_ref->type != MRI_UCHAR) {
    MRI *mri_tmp ;

    mri_tmp = MRIchangeType(mri_ref, MRI_UCHAR, 0.0, 0.999, FALSE) ;
    MRIfree(&mri_ref) ;
    mri_ref = mri_tmp ;
  }

  if (var_fname)  /* read in a volume of standard deviations */
  {
    MRI *mri_var, *mri_tmp ;

    fprintf(stderr, "reading '%s'...\n", var_fname) ;
    mri_var = MRIread(var_fname) ;
    if (!mri_var)
      ErrorExit(ERROR_NOFILE, "%s: could not open variance volume %s.\n",
                Progname, var_fname) ;
    mri_tmp = MRIconcatenateFrames(mri_ref, mri_var, NULL) ;
    MRIfree(&mri_var) ;
    MRIfree(&mri_ref) ;
    mri_ref = mri_tmp ;
  }
  fprintf(stderr, "reading '%s'...\n", in_fname) ;
  fflush(stderr) ;
  mri_orig = mri_in = MRIread(in_fname) ;
  if (!mri_in)
    ErrorExit(ERROR_NOFILE, "%s: could not open input volume %s.\n",
              Progname, in_fname) ;
  if (mri_in->type != MRI_UCHAR) {
    MRI *mri_tmp ;

    mri_orig = mri_tmp = MRIchangeType(mri_in, MRI_UCHAR, 0.0, 0.999, FALSE) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  /* make sure they are the same size */
  if (mri_in->width  != mri_ref->width ||
      mri_in->height != mri_ref->height  ||
      mri_in->depth  != mri_ref->depth) {
    int  width, height, depth ;
    MRI  *mri_tmp ;

    width = MAX(mri_in->width, mri_ref->width) ;
    height = MAX(mri_in->height, mri_ref->height) ;
    depth = MAX(mri_in->depth, mri_ref->depth) ;
    mri_tmp = MRIalloc(width, height, depth, MRI_UCHAR) ;
    MRIextractInto(mri_in, mri_tmp, 0, 0, 0,
                   mri_in->width, mri_in->height, mri_in->depth, 0, 0, 0) ;
#if 0
    MRIfree(&mri_in) ;
#else
    parms.mri_in = mri_in ;
#endif
    mri_in = mri_orig = mri_tmp ;

    mri_tmp = MRIallocSequence(width, height,depth,MRI_UCHAR,mri_ref->nframes);
    MRIextractInto(mri_ref, mri_tmp, 0, 0, 0,
                   mri_ref->width, mri_ref->height, mri_ref->depth, 0, 0, 0) ;
#if 0
    MRIfree(&mri_ref) ;
#else
    parms.mri_in = mri_in ;
#endif
    mri_ref = mri_tmp ;
  }


  if (!FZERO(tx) || !FZERO(ty) || !FZERO(tz)) {
    MRI *mri_tmp ;

    fprintf(stderr, "translating second volume by (%2.1f, %2.1f, %2.1f)\n",
            tx, ty, tz) ;
    mri_tmp = MRItranslate(mri_in, NULL, tx, ty, tz) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  if (!FZERO(rzrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around Z axis\n",
            (float)DEGREES(rzrot)) ;
    mri_tmp = MRIrotateZ_I(mri_in, NULL, rzrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }
  if (!FZERO(rxrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around X axis\n",
            (float)DEGREES(rxrot)) ;
    mri_tmp = MRIrotateX_I(mri_in, NULL, rxrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }
  if (!FZERO(ryrot)) {
    MRI *mri_tmp ;

    fprintf(stderr,
            "rotating second volume by %2.1f degrees around Y axis\n",
            (float)DEGREES(ryrot)) ;
    mri_tmp = MRIrotateY_I(mri_in, NULL, ryrot) ;
    MRIfree(&mri_in) ;
    mri_in = mri_tmp ;
  }

  if (!transform_loaded)   /* wasn't preloaded */
    parms.lta = LTAalloc(1, mri_in) ;

  if (!FZERO(blur_sigma)) {
    MRI *mri_kernel, *mri_tmp ;

    mri_kernel = MRIgaussian1d(blur_sigma, 100) ;
    mri_tmp = MRIconvolveGaussian(mri_in, NULL, mri_kernel) ;
    mri_in = mri_tmp ;
    MRIfree(&mri_kernel) ;
  }
  MRIscaleMeanIntensities(mri_in, mri_ref, mri_in);

  mri_ref_orig = mri_ref ;
  mri_in_orig = mri_in ;
  if (nreductions > 0) {
    mri_in_red = mri_in_tmp = MRIcopy(mri_in, NULL) ;
    mri_ref_red = mri_ref_tmp = MRIcopy(mri_ref, NULL) ;
    for (i = 0 ; i < nreductions ; i++) {
      mri_in_red = MRIreduceByte(mri_in_tmp, NULL) ;
      mri_ref_red = MRIreduceMeanAndStdByte(mri_ref_tmp,NULL);
      MRIfree(&mri_in_tmp);
      MRIfree(&mri_ref_tmp) ;
      mri_in_tmp = mri_in_red ;
      mri_ref_tmp = mri_ref_red ;
    }
    mri_in = mri_in_red ;
    mri_ref = mri_ref_red ;
  }
  /* for diagnostics */
  if (full_res) {
    parms.mri_ref = mri_ref ;
    parms.mri_in = mri_in ;
  } else {
    parms.mri_ref = mri_ref_orig ;
    parms.mri_in = mri_in_orig ;
  }

  m_L = initialize_transform(mri_in, mri_ref, &parms) ;

  if (use_gradient) {
    MRI  *mri_in_mag, *mri_ref_mag, *mri_grad, *mri_mag ;

    printf("computing gradient magnitude of input image...\n") ;
    mri_mag = MRIalloc(mri_in->width, mri_in->height, mri_in->depth,MRI_FLOAT);
    MRIcopyHeader(mri_in, mri_mag) ;
    mri_grad = MRIsobel(mri_in, NULL, mri_mag) ;
    MRIfree(&mri_grad) ;

    /* convert it to ubytes */
    MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ;
    mri_in_mag = MRIclone(mri_in, NULL) ;
    MRIcopy(mri_mag, mri_in_mag) ;
    MRIfree(&mri_mag) ;

    /* now compute gradient of ref image */
    printf("computing gradient magnitude of reference image...\n") ;
    mri_mag = MRIalloc(mri_ref->width, mri_ref->height, mri_ref->depth,MRI_FLOAT);
    MRIcopyHeader(mri_ref, mri_mag) ;
    mri_grad = MRIsobel(mri_ref, NULL, mri_mag) ;
    MRIfree(&mri_grad) ;

    /* convert it to ubytes */
    MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ;
    mri_ref_mag = MRIclone(mri_ref, NULL) ;
    MRIcopy(mri_mag, mri_ref_mag) ;
    MRIfree(&mri_mag) ;

    register_mri(mri_in_mag, mri_ref_mag, &parms, m_L) ;
    MRIfree(&mri_in_mag) ;
    MRIfree(&mri_ref_mag) ;
  }
  register_mri(mri_in, mri_ref, &parms, m_L) ;
  if (check_crop_flag)  /* not working yet! */
  {
    printf("searching for cropped regions in the input image...\n") ;
    parms.mri_crop = find_cropping(mri_orig, mri_ref, &parms) ;
    MRIwrite(parms.mri_crop, "crop.mgh") ;
    register_mri(mri_in, mri_ref, &parms, m_L) ;
  }

  if (voxel_coords) {
    printf("transforming xform to voxel coordinates...\n") ;
    MRIrasXformToVoxelXform(mri_in_orig, mri_ref_orig,
                            parms.lta->xforms[0].m_L,
                            parms.lta->xforms[0].m_L);
    if (Gdiag & DIAG_WRITE) {
      MRI *mri_tmp ;

      mri_tmp = MRIlinearTransform(mri_in_orig, NULL,parms.lta->xforms[0].m_L);
      MRIwriteImageViews(mri_tmp, "morphed", IMAGE_SIZE) ;
      MRIfree(&mri_tmp) ;
    }
  }
  // save src and target info in lta
  getVolGeom(mri_in_orig, &parms.lta->xforms[0].src);
  getVolGeom(mri_ref_orig, &parms.lta->xforms[0].dst);
  fprintf(stderr, "writing output transformation to %s...\n", out_fname) ;
  if (invert_flag) {
    MATRIX *m_tmp ;

    m_tmp = MatrixInverse(parms.lta->xforms[0].m_L, NULL) ;
    MatrixFree(&parms.lta->xforms[0].m_L) ;
    // change src and dst
    getVolGeom(mri_in_orig, &parms.lta->xforms[0].dst);
    getVolGeom(mri_ref_orig, &parms.lta->xforms[0].src);
    parms.lta->xforms[0].m_L = m_tmp ;
  }
  //
  LTAwriteEx(parms.lta, out_fname) ;
  //
  if (mri_ref)
    MRIfree(&mri_ref) ;
  if (mri_in)
    MRIfree(&mri_in) ;
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  fprintf(stderr, "registration took %d minutes and %d seconds.\n",
          minutes, seconds) ;
  exit(0) ;
  return(0) ;
}