예제 #1
0
ObjectDB *getObjectDB( LWItemID id, GlobalFunc *global )
{
   LWObjectInfo *objinfo;
   LWMeshInfo *mesh;
   LWPntID ptid;
   ObjectDB *odb;
   const char *name;
   int npts, npols, nverts, i, j, k, ok = 0;

   /* get the object info global */

   objinfo = global( LWOBJECTINFO_GLOBAL, GFUSE_TRANSIENT );
   if ( !objinfo ) return NULL;

   /* get the mesh info for the object */

   mesh = objinfo->meshInfo( id, 1 );
   if ( !mesh ) return NULL;

   /* alloc the object database */

   odb = calloc( 1, sizeof( ObjectDB ));
   if ( !odb ) goto Finish;

   odb->id = id;
   name = objinfo->filename( id );
   odb->filename = malloc( strlen( name ) + 1 );
   if ( !odb->filename ) goto Finish;
   strcpy( odb->filename, name );

   /* alloc and init the points array */

   npts = mesh->numPoints( mesh );
   odb->pt = calloc( npts, sizeof( DBPoint ));
   if ( !odb->pt ) goto Finish;

   if ( mesh->scanPoints( mesh, pntScan, odb ))
      goto Finish;

   /* alloc and init the polygons array */

   npols = mesh->numPolygons( mesh );
   odb->pol = calloc( npols, sizeof( DBPolygon ));
   if ( !odb->pol ) goto Finish;

   if ( mesh->scanPolys( mesh, polScan, odb ))
      goto Finish;

   /* get the vertices of each polygon */

   for ( i = 0; i < npols; i++ ) {
      nverts = mesh->polSize( mesh, odb->pol[ i ].id );
      odb->pol[ i ].v = calloc( nverts, sizeof( DBPolVert ));
      if ( !odb->pol[ i ].v ) goto Finish;
      odb->pol[ i ].nverts = nverts;
      for ( j = 0; j < nverts; j++ ) {
         ptid = mesh->polVertex( mesh, odb->pol[ i ].id, j );
         odb->pol[ i ].v[ j ].index = findVert( odb, ptid );
      }
   }

   /* count the number of polygons per point */

   for ( i = 0; i < npols; i++ )
      for ( j = 0; j < odb->pol[ i ].nverts; j++ )
         ++odb->pt[ odb->pol[ i ].v[ j ].index ].npols;

   /* alloc per-point polygon arrays */

   for ( i = 0; i < npts; i++ ) {
      if ( odb->pt[ i ].npols == 0 ) continue;
      odb->pt[ i ].pol = calloc( odb->pt[ i ].npols, sizeof( int ));
      if ( !odb->pt[ i ].pol ) goto Finish;
      odb->pt[ i ].npols = 0;
   }

   /* fill in polygon array for each point */

   for ( i = 0; i < npols; i++ ) {
      for ( j = 0; j < odb->pol[ i ].nverts; j++ ) {
         k = odb->pol[ i ].v[ j ].index;
         odb->pt[ k ].pol[ odb->pt[ k ].npols ] = i;
         ++odb->pt[ k ].npols;
      }
   }

   /* get the position of each point */

   for ( i = 0; i < npts; i++ ) {
      mesh->pntBasePos( mesh, odb->pt[ i ].id, odb->pt[ i ].pos[ 0 ] );
      mesh->pntOtherPos( mesh, odb->pt[ i ].id, odb->pt[ i ].pos[ 1 ] );
   }

   /* init the point search array */

   /* Ordinarily, you won't need this because you can look up points
      by their IDs.  Uncomment this if you do need to search by point
      position instead.  The second argument is 0 for base position
      and 1 for final position.

      if ( !initPointSearch( odb, 0 ))
         goto Finish;
   */

   /* calculate the normal of each polygon */

   getPolyNormals( odb, 0 );
   getPolyNormals( odb, 1 );

   /* get the vmaps */

   if ( !getObjectVMaps( odb, mesh, global ))
      goto Finish;

   /* get the surfaces */

   if ( !getObjectSurfs( odb, mesh, global ))
      goto Finish;

   /* calculate vertex normals */

   getVertNormals( odb, 0 );
   getVertNormals( odb, 1 );

   /* done */

   ok = 1;

Finish:
   if ( mesh->destroy )
      mesh->destroy( mesh );

   if ( !ok ) {
      freeObjectDB( odb );
      return NULL;
   }

   return odb;
}
예제 #2
0
bool LWObject::collectWeights(const std::vector<LWBone> &bones)
{
	LWObjectInfo *objectInfo = Manager::getSingleton()->getObjectInfo();
	if(objectInfo == 0)
		return false;
			
	LWMeshInfo *meshInfo = objectInfo->meshInfo(lwId, TRUE);
	if(meshInfo == 0)
		return false;

	bool hasWeights = false;

	// Each bone has it's own weightmap
	for(unsigned int i = 0; i < bones.size(); ++i)
	{
		const std::string &weightMap = bones[i].getWeightName();

		// Select vertex map to read
		void *map = 0;
		if((map = meshInfo->pntVLookup(meshInfo, LWVMAP_WGHT, weightMap.c_str())) == 0)
			continue;

		if(meshInfo->pntVSelect(meshInfo, map) != 1)
		{
			Manager::getSingleton()->getExporter()->printWarning(name + ": weightmap has more than 1 dimension");
			continue;
		}

		// Try for each vertex
		for(unsigned int j = 0; j < vertices.size(); ++j)
		{
			float weight = 0.f;
			if(meshInfo->pntVGet(meshInfo, vertices[j].id, &weight))
			{
				// 0-weight is valid
				//if(fabs(weight) < .001f)
				//	continue;


				// Set if greater than what's already in
				for(int k = 0; k < LWVertex::MAX_WEIGHTS; ++k)
				{
					if(vertices[j].boneIndices[k] == -1 || fabs(vertices[j].boneWeights[k]) < fabsf(weight)) 
					{	
						// Store old value forward
						if(k + 1 < LWVertex::MAX_WEIGHTS)
						{
							vertices[j].boneIndices[k + 1] = vertices[j].boneIndices[k];
							vertices[j].boneWeights[k + 1] = vertices[j].boneWeights[k];
						}

						vertices[j].boneIndices[k] = i;
						vertices[j].boneWeights[k] = weight;
						break;
					}
				}

				/*
				// Set if has no weight
				bool set = false;
				for(int k = 0; k < LWVertex::MAX_WEIGHTS; ++k)
				{
					if(vertices[j].boneIndices[k] == -1) 
					{
						vertices[j].boneIndices[k] = i;
						vertices[j].boneWeights[k] = weight;
						set = true;

						hasWeights = true;
						break;
					}
				}

				if(set == true)
					continue;

				// Set if greater than what's already in
				for(k = LWVertex::MAX_WEIGHTS - 1; k >= 0; --k)
				{
					if(fabs(vertices[j].boneWeights[k]) < fabsf(weight)) 
					{	
						// Store old value forward
						if(k + 1 < LWVertex::MAX_WEIGHTS)
						{
							vertices[j].boneIndices[k + 1] = vertices[j].boneIndices[k];
							vertices[j].boneWeights[k + 1] = vertices[j].boneWeights[k];
						}

						vertices[j].boneIndices[k] = i;
						vertices[j].boneWeights[k] = weight;
						break;
					}
				}
				*/
			}

		}
	}

	if(meshInfo->destroy)
		meshInfo->destroy(meshInfo);

	return hasWeights;
}
예제 #3
0
void LWObject::collectTextureCoordinates(const std::vector<LWMaterial> &materials, const FBMatrix &transform)
{
	// This part is a bit messy. 
	// Can't help it since LW's gotta do what LW's gotta do etc.
	LWTextureFuncs *textureFunctions = Manager::getSingleton()->getTextureFunctions();
	LWObjectInfo *objectInfo = Manager::getSingleton()->getObjectInfo();

	if((textureFunctions == 0) || (objectInfo == 0))
		return;

	LWMeshInfo *meshInfo = objectInfo->meshInfo(lwId, TRUE);
	if(meshInfo == 0)
		return;

	// Get them per face (looks ugly otherwise)
	for(unsigned int i = 0; i < faces.size(); ++i)
	{
		// If no material, no texture
		if(faces[i].materialId == -1)
			continue;

		// Each face have different material
		LWTextureID textureId = materials[faces[i].materialId].getTextureId();
		if(textureId == 0)
			continue;

		LWTLayerID layerId = textureFunctions->firstLayer(textureId);
		if(layerId == 0)
			continue;

		int projection = 0;
		textureFunctions->getParam(layerId, TXTAG_PROJ, &projection);

		for(int j = 0; j < 3; ++j)
		{
			if(projection == TXPRJ_UVMAP) // UV-map
			{
				void *map = NULL;
				textureFunctions->getParam(layerId, TXTAG_VMAP, &map);

				if(map == 0)
					continue;

				if(meshInfo->pntVSelect(meshInfo, map) != 2)
				{
					Manager::getSingleton()->getExporter()->printWarning(name + ": UV-map isn't 2-dimensional. Discarding.");
					continue;
				}

				float uv[2] = { 0 };
				LWPntID vertexId = vertices[faces[i].indices[j]].id;

				// Finally query texture coordinates
				if(meshInfo->pntVPGet(meshInfo, vertexId, faces[i].id, uv))
				{
					faces[i].uvs[j].x = uv[0];
					faces[i].uvs[j].y = -uv[1];
					faces[i].hasUvs[j] = true;
				}
				else if(meshInfo->pntVGet(meshInfo, vertexId, uv))
				{
					faces[i].uvs[j].x = uv[0];
					faces[i].uvs[j].y = -uv[1];
					faces[i].hasUvs[j] = true;
				}
			}
			else // Projected mapping
			{
				// Normals largest absolute value defines dominant axis (in world and object space)
				FBVector worldNormal = faces[i].normal;
				transform.RotateVector(worldNormal);

				int wAxis = getDominantAxis(worldNormal);
				//int wAxis = getDominantAxis(transform.GetTransformedVector(faces[i].normal));
				int oAxis = getDominantAxis(faces[i].normal);

				// Position in world and object space
				FBVector &vO = vertices[faces[i].indices[j]].position;
				FBVector vW = transform.GetTransformedVector(vO);

				double oPosition[3] = { vO.x, vO.y, vO.z };
				double wPosition[3] = { vW.x, vW.y, vW.z };
				double uv[2] = { 0 };

				textureFunctions->evaluateUV(layerId, wAxis, oAxis, oPosition, wPosition, uv);
				faces[i].uvs[j].x = static_cast<double> (uv[0]);
				faces[i].uvs[j].y = static_cast<double> (-uv[1]);
				faces[i].hasUvs[j] = true;
			}

			//faces[i].uvs2[j] = faces[i].uvs[j];
		}
	}

	// In the name of holy spaghetti. Should clean this up a bit
	for(unsigned int i = 0; i < faces.size(); ++i)
	{
		// If no material, no texture
		if(faces[i].materialId == -1)
			continue;

		// Each face have different material
		LWTextureID textureId = materials[faces[i].materialId].getLightmapId();
		if(textureId == 0)
			continue;
/*
int a = 0;
if(materials[faces[i].materialId].getName() == "Lattia")
	a = 1;
*/
		LWTLayerID layerId = textureFunctions->firstLayer(textureId);
		if(layerId == 0)
		{
			//materials[faces[i].materialId].removeLightmap();
			continue;
		}

		int projection = 0;
		textureFunctions->getParam(layerId, TXTAG_PROJ, &projection);

		for(int j = 0; j < 3; ++j)
		{
			if(projection == TXPRJ_UVMAP) // UV-map
			{
				void *map = 0;
				textureFunctions->getParam(layerId, TXTAG_VMAP, &map);

				if(meshInfo->pntVSelect(meshInfo, map) != 2)
				{
					Manager::getSingleton()->getExporter()->printWarning(name + ": No actual UV-map defined. Discarding.");
					//materials[faces[i].materialId].removeLightmap();
					continue;
				}

				if(map == 0)
				{
					//materials[faces[i].materialId].removeLightmap();
					continue;
				}

				if(meshInfo->pntVSelect(meshInfo, map) != 2)
				{
					Manager::getSingleton()->getExporter()->printWarning(name + ": UV-map isn't 2-dimensional. Discarding.");
					//materials[faces[i].materialId].removeLightmap();
					continue;
				}

				float uv[2] = { 0 };
				LWPntID vertexId = vertices[faces[i].indices[j]].id;

				// Finally query texture coordinates
				if(meshInfo->pntVPGet(meshInfo, vertexId, faces[i].id, uv))
				{
					faces[i].uvs2[j].x = uv[0];
					faces[i].uvs2[j].y = -uv[1];

					if(faces[i].hasUvs[j] == false)
					{
						faces[i].uvs[j].x = faces[i].uvs2[j].x;
						faces[i].uvs[j].y = faces[i].uvs2[j].y;
					}

					faces[i].hasUvs[j] = true;
				}
				else if(meshInfo->pntVGet(meshInfo, vertexId, uv))
				{
					faces[i].uvs2[j].x = uv[0];
					faces[i].uvs2[j].y = -uv[1];

					if(faces[i].hasUvs[j] == false)
					{
						faces[i].uvs[j].x = faces[i].uvs2[j].x;
						faces[i].uvs[j].y = faces[i].uvs2[j].y;
					}
					
					faces[i].hasUvs[j] = true;
				}
				//else
				//	materials[faces[i].materialId].removeLightmap();
			}
			//else
			//	materials[faces[i].materialId].removeLightmap();



/*
			else // Projected mapping
			{
				// Normals largest absolute value defines dominant axis (in world and object space)
				FBVector worldNormal = faces[i].normal;
				transform.RotateVector(worldNormal);

				int wAxis = getDominantAxis(worldNormal);
				int oAxis = getDominantAxis(faces[i].normal);

				// Position in world and object space
				Vector &vO = vertices[faces[i].indices[j]].position;
				Vector vW = transform.GetTransformedVector(vO);

				double oPosition[3] = { vO.x, vO.y, vO.z };
				double wPosition[3] = { vW.x, vW.y, vW.z };
				double uv[2] = { 0 };
				
				textureFunctions->evaluateUV(layerId, wAxis, oAxis, oPosition, wPosition, uv);
				faces[i].uvs2[j].x = static_cast<double> (uv[0]);
				faces[i].uvs2[j].y = static_cast<double> (-uv[1]);

				if(faces[i].hasUvs[j] == false)
				{
					faces[i].uvs[j].x = faces[i].uvs2[j].x;
					faces[i].uvs[j].y = faces[i].uvs2[j].y;
				}
				
				faces[i].hasUvs[j] = true;
			}
*/
		}
	}

	if(meshInfo->destroy)
		meshInfo->destroy(meshInfo);
}
예제 #4
0
파일: objectdb.cpp 프로젝트: 2asoft/xray
ObjectDB *getObjectDB( LWItemID id, GlobalFunc *global )
{
   LWObjectInfo *objinfo;
   LWMeshInfo *mesh;
   LWPntID ptid;
   ObjectDB *odb;
   const char *name;
   int npts, npols, nverts, i, j, k, ok = 0;


   /* get the object info global */

   objinfo = (st_LWObjectInfo*)global( LWOBJECTINFO_GLOBAL, GFUSE_TRANSIENT );
   if ( !objinfo ) return NULL;

   /* get the mesh info for the object */

   mesh = objinfo->meshInfo( id, 1 );
   if ( !mesh ) return NULL;

   /* alloc the object database */

   odb = (st_ObjectDB*)calloc( 1, sizeof( ObjectDB ));
   if ( !odb ) goto Finish;

   odb->id = id;
   name = objinfo->filename( id );
   odb->filename = (char*)malloc( xr_strlen( name ) + 1 );
   if ( !odb->filename ) goto Finish;
   strcpy( odb->filename, name );

   /* alloc and init the points array */

   npts = mesh->numPoints( mesh );
   odb->pt = (st_DBPoint*)calloc( npts, sizeof( DBPoint ));
   if ( !odb->pt ) goto Finish;

   if ( mesh->scanPoints( mesh, (int (__cdecl *)(void *,struct st_GCoreVertex *))pntScan, odb ))
      goto Finish;

   /* alloc and init the polygons array */

   npols = mesh->numPolygons( mesh );
   odb->pol = (st_DBPolygon*)calloc( npols, sizeof( DBPolygon ));
   if ( !odb->pol ) goto Finish;

   if ( mesh->scanPolys( mesh, (int (__cdecl *)(void *,struct st_GCorePolygon *))polScan, odb ))
      goto Finish;

   /* get the vertices of each polygon */

   for ( i = 0; i < npols; i++ ) {
      nverts = mesh->polSize( mesh, odb->pol[ i ].id );
      odb->pol[ i ].v = (st_DBPolVert*)calloc( nverts, sizeof( DBPolVert ));
      if ( !odb->pol[ i ].v ) goto Finish;
      odb->pol[ i ].nverts = nverts;
      for ( j = 0; j < nverts; j++ ) {
         ptid = mesh->polVertex( mesh, odb->pol[ i ].id, j );
         odb->pol[ i ].v[ j ].index = findVert( odb, ptid );
      }
   }

   /* count the number of polygons per point */

   for ( i = 0; i < npols; i++ )
      for ( j = 0; j < odb->pol[ i ].nverts; j++ )
         ++odb->pt[ odb->pol[ i ].v[ j ].index ].npols;

   /* alloc per-point polygon arrays */

   for ( i = 0; i < npts; i++ ) {
      if ( odb->pt[ i ].npols == 0 ) continue;
      odb->pt[ i ].pol = (int*)calloc( odb->pt[ i ].npols, sizeof( int ));
      if ( !odb->pt[ i ].pol ) goto Finish;
      odb->pt[ i ].npols = 0;
   }

   /* fill in polygon array for each point */

   for ( i = 0; i < npols; i++ ) {
      for ( j = 0; j < odb->pol[ i ].nverts; j++ ) {
         k = odb->pol[ i ].v[ j ].index;
         odb->pt[ k ].pol[ odb->pt[ k ].npols ] = i;
         ++odb->pt[ k ].npols;
      }
   }

   /* get the base position of each point */

   for ( i = 0; i < npts; i++ )
      mesh->pntBasePos( mesh, odb->pt[ i ].id, odb->pt[ i ].pos[ 0 ] );

   /* init the point search array */
   /* do this here if you need to search by base pos, or later if you
      need to search by final pos */

   // if ( !initPointSearch( odb, 0 ))
   //    goto Finish;

   /* calculate the base normal of each polygon */

   getPolyNormals( odb, 0 );

   /* get the vmaps */

   if ( !getObjectVMaps( odb, mesh, global ))
      goto Finish;

   /* get the surfaces */

   if ( !getObjectSurfs( odb, mesh, global ))
      goto Finish;

   /* calculate initial vertex normals */

   getVertNormals( odb, 0 );

   /* done */

   ok = 1;

Finish:
   if ( mesh->destroy )
      mesh->destroy( mesh );

   if ( !ok ) {
      freeObjectDB( odb );
      return NULL;
   }

   return odb;
}