Esempio n. 1
0
void VFSPlugin_LWO::read_bbox(long length)
{
	//	Read the min/max constraints of the mesh
	Vertex3f *min	= ReadVertex();
	Vertex3f *max	= ReadVertex();

	//	Dont use them yet, so delete it's temporary memory
	delete min;
	delete max;
}
Esempio n. 2
0
void VFSPlugin_LWO::read_pnts(long length)
{
	//	Calculate the number of vertex in the mesh
	int numvertex = length/sizeof(Vertex3f);

	Mesh *m = reinterpret_cast<Mesh *>(m_fileinfo->mesh);
	m->Initialise(numvertex);

	Vertex3f *v = new Vertex3f[numvertex];
	Vertex3f *temp;

	//	Read all the vertices from the file data
	for(int a=0;a<numvertex;a++){
		temp = ReadVertex();

		//	Store the vertex data
		v[a].x	= temp->x;
		v[a].y	= temp->y;
		v[a].z	= temp->z;
	
		//	Delete the temporary vertex data
		delete temp;
	}

	m->SetPosition(v);

	delete[] v;
}
Esempio n. 3
0
void VFSPlugin_LWO::read_layr(long length)
{
	//	Read the layer number
	short layernumber = ReadShort();
	length-=sizeof(layernumber);

	//	Read the layer flags
	short layerflags = ReadShort();
	length-=sizeof(layerflags);

	//	Read the layer pivot axis
	Vertex3f *v = ReadVertex();
	length-=sizeof(Vertex3f);

	//	Read the layer name
	long stringlength;
	char *layername = ReadString(&stringlength);
	length-=stringlength;

	//	Read the parent layer number
	short parentid = -1;
	if(length>=sizeof(parentid)) parentid = ReadShort();

	//	Clean up any temporary memory
	delete v;
	delete layername;
}
Esempio n. 4
0
Graph *ReadGraph(char *filename, LabelList *labelList, BOOLEAN directed)
{
   Graph *graph;
   FILE *graphFile;
   ULONG lineNo;             // Line number counter for graph file
   char token[TOKEN_LEN];
   ULONG vertexListSize = 0; // Size of currently-allocated vertex array
   ULONG edgeListSize = 0;   // Size of currently-allocated edge array
   ULONG vertexOffset = 0;   // Dummy argument to ReadVertex and ReadEdge

   // Allocate graph
   graph = AllocateGraph(0,0);

   // Open graph file
   graphFile = fopen(filename,"r");
   if (graphFile == NULL) 
   {
      fprintf(stderr, "Unable to open graph file %s.\n", filename);
      exit(1);
   }

   // Parse graph file
   lineNo = 1;
   while (ReadToken(token, graphFile, &lineNo) != 0) 
   {
      if (strcmp(token, "v") == 0)         // read vertex
         ReadVertex(graph, graphFile, labelList, &vertexListSize, &lineNo,
                    vertexOffset);

      else if (strcmp(token, "e") == 0)    // read 'e' edge
         ReadEdge(graph, graphFile, labelList, &edgeListSize, &lineNo, directed,
                  vertexOffset);

      else if (strcmp(token, "u") == 0)    // read undirected edge
         ReadEdge(graph, graphFile, labelList, &edgeListSize, &lineNo, FALSE,
                  vertexOffset);

      else if (strcmp(token, "d") == 0)    // read directed edge
         ReadEdge(graph, graphFile, labelList, &edgeListSize, &lineNo, TRUE,
                  vertexOffset);

      else 
      {
         fclose(graphFile);
         FreeGraph(graph);
         fprintf(stderr, "Unknown token %s in line %lu of graph file %s.\n",
                 token, lineNo, filename);
         exit(1);
      }
   }
   fclose(graphFile);

   //***** trim vertex, edge and label lists

   return graph;
}
Esempio n. 5
0
void FbxParser::ProcessMesh(FbxNode* pNode,std::vector<GS::BaseMesh*>& meshs)
{
	FbxMesh* lMesh = (FbxMesh*) pNode->GetNodeAttribute ();
	if (lMesh == NULL)
		return ; 
	int triangleCount = lMesh->GetPolygonCount();  
    int vertexCounter = 0;  
	if (triangleCount ==0)
		return ; 
	
	GS::BaseMesh* pMesh = new GS::BaseMesh();
	GS::double3 p0, p1, p2;
	int vertexId = 0;
	GS::VertexInfo v1, v2, v3;
	
	for(int i = 0 ; i < triangleCount ; ++i)  
    {
        int ctrlPointIndex = lMesh->GetPolygonVertex(i , 0);
		
		ReadVertex(lMesh, ctrlPointIndex, v1.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v1.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v1.normal);
		
		// read the second vertex
		ctrlPointIndex = lMesh->GetPolygonVertex(i , 1);
	    ReadVertex(lMesh, ctrlPointIndex, v2.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v2.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v2.normal);
		// read the third vertex
		ctrlPointIndex = lMesh->GetPolygonVertex(i , 2);
		ReadVertex(lMesh, ctrlPointIndex, v3.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v3.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v3.normal);
		pMesh->Add(v1, v2, v3);
	}
	pMesh->GenID();
	//pMesh->GenSurface();
	pMesh->GenAABB(true);
	meshs.push_back(pMesh);
}
Esempio n. 6
0
	void sb7fbxmodel::ProcessMesh(FbxNode* pNode)
	{
		fbxsdk::FbxMesh* pMesh = pNode->GetMesh();  
		if(pMesh == NULL)  
		{  
			return;  
		}  

		int triangleCount = pMesh->GetPolygonCount();  
		int vertexCounter = 0;

		sub_mesh sm;
		sm.count = 3 * triangleCount;
		sm.va = (vetex_attr*)malloc(sizeof(vetex_attr) * sm.count);
		m_vass.push_back(sm);


		for(int i = 0 ; i < triangleCount ; ++i)  
		{  
			for(int j = 0 ; j < 3 ; j++)  
			{
				vetex_attr va;
				int ctrlPointIndex = pMesh->GetPolygonVertex(i , j);  

				// Read the vertex  
				ReadVertex(pMesh , ctrlPointIndex , va.vertex);  

				// Read the color of each vertex  
				ReadColor(pMesh , ctrlPointIndex , vertexCounter , va.color);  

				// Read the UV of each vertex  
				for(int k = 0 ; k < 2 ; ++k)
				{  
					ReadUV(pMesh , ctrlPointIndex , pMesh->GetTextureUVIndex(i, j) , k , va.uv[k]);  
				}  

				// Read the normal of each vertex  
				ReadNormal(pMesh , ctrlPointIndex , vertexCounter , va.normal);  

				// Read the tangent of each vertex  
				ReadTangent(pMesh , ctrlPointIndex , vertexCounter , va.tangent);  
				sm.va[vertexCounter] = va;
				vertexCounter++;  
				
			}  

			// 根据读入的信息组装三角形,并以某种方式使用即可,比如存入到列表中、保存到文件等...   
		}
	}
Esempio n. 7
0
    void ImportVertices(aiMesh* mesh)
    {
        std::vector<aiVector3D> vertices;        

        while(ReadToEndElement(D3MF::XmlTag::vertices))
        {                        
            if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
            {                
                vertices.push_back(ReadVertex());
            }
        }
        mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
        mesh->mVertices = new aiVector3D[mesh->mNumVertices];

        std::copy(vertices.begin(), vertices.end(), mesh->mVertices);

    }
Esempio n. 8
0
void Test(char *subsFileName, char *graphFileName, Parameters *parameters,
          ULONG *TPp, ULONG *TNp, ULONG *FPp, ULONG *FNp)
{
   FILE *graphFile;
   LabelList *labelList;
   BOOLEAN directed;
   Graph **subGraphs;
   ULONG numSubGraphs;
   Graph *graph;
   BOOLEAN positive1;
   BOOLEAN positive2;
   ULONG vertexOffset = 0;
   ULONG lineNo = 1;
   char token[TOKEN_LEN];
   ULONG FP = 0;
   ULONG FN = 0;
   ULONG TP = 0;
   ULONG TN = 0;
   ULONG i;

   labelList = parameters->labelList;
   directed = parameters->directed;

   // read substructures
   subGraphs = ReadSubGraphsFromFile(subsFileName, SUB_TOKEN, &numSubGraphs,
                                     parameters);
   fprintf(stdout, "Read %lu substructures from file %s.\n",
           numSubGraphs, subsFileName);

   // open example graphs file and compute stats
   graphFile = fopen(graphFileName, "r");
   if (graphFile == NULL) 
   {
      fprintf(stderr, "Unable to open graph file %s.\n", graphFileName);
      exit(1);
   }

   graph = NULL;
   positive1 = TRUE;
   while (ReadToken(token, graphFile, &lineNo) != 0) 
   {
      if (strcmp(token, POS_EG_TOKEN) == 0) 
      { // reading positive eg
         if (graph != NULL) 
         {
            // test last graph
            positive2 = PositiveExample(graph, subGraphs, numSubGraphs,
                                        parameters);
            // increment appropriate counter
            if (positive1 && positive2) TP++;
            if (positive1 && (! positive2)) FN++;
            if ((! positive1) && positive2) FP++;
            if ((! positive1) && (! positive2)) TN++;
            FreeGraph(graph);
         }
         graph = AllocateGraph(0,0);
         positive1 = TRUE;
      }
      else if (strcmp(token, NEG_EG_TOKEN) == 0) 
      { // reading negative eg
         if (graph != NULL) 
         {
            // test last graph
            positive2 = PositiveExample(graph, subGraphs, numSubGraphs,
                                        parameters);
            // increment appropriate counter
            if (positive1 && positive2) TP++;
            if (positive1 && (! positive2)) FN++;
            if ((! positive1) && positive2) FP++;
            if ((! positive1) && (! positive2)) TN++;
            FreeGraph(graph);
         }
         graph = AllocateGraph(0,0);
         positive1 = FALSE;
      }
      else if (strcmp(token, "v") == 0) 
      {  // read vertex
         if (positive1 && (graph == NULL)) 
         {
            // first graph starts without positive token, so assumed positive
            graph = AllocateGraph(0,0);
         }
         ReadVertex(graph, graphFile, labelList, &lineNo, vertexOffset);
      }
      else if (strcmp(token, "e") == 0)    // read 'e' edge
         ReadEdge(graph, graphFile, labelList, &lineNo, directed, vertexOffset);

      else if (strcmp(token, "u") == 0)    // read undirected edge
         ReadEdge(graph, graphFile, labelList, &lineNo, FALSE, vertexOffset);

      else if (strcmp(token, "d") == 0)    // read directed edge
         ReadEdge(graph, graphFile, labelList, &lineNo, TRUE, vertexOffset);

      else 
      {
         fclose(graphFile);
         fprintf(stderr, "Unknown token %s in line %lu of input file %s.\n",
                 token, lineNo, graphFileName);
         exit(1);
      }
   }
   // test last graph
   if (graph != NULL) 
   {
      positive2 = PositiveExample(graph, subGraphs, numSubGraphs,
                                  parameters);
      // increment appropriate counter
      if (positive1 && positive2) TP++;
      if (positive1 && (! positive2)) FN++;
      if ((! positive1) && positive2) FP++;
      if ((! positive1) && (! positive2)) TN++;
      FreeGraph(graph);
   }

   fclose(graphFile);

   // free substructure graphs
   for (i = 0; i < numSubGraphs; i++)
      FreeGraph(subGraphs[i]);
   free(subGraphs);

   *TPp = TP;
   *TNp = TN;
   *FPp = FP;
   *FNp = FN;
}
Esempio n. 9
0
void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine)
{
	VertexDecoder &vdecoder = *drawEngine->FindVertexDecoder(vertex_type);
	const DecVtxFormat &vtxfmt = vdecoder.GetDecVtxFmt();

	if (bytesRead)
		*bytesRead = vertex_count * vdecoder.VertexSize();

	// Frame skipping.
	if (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) {
		return;
	}

	u16 index_lower_bound = 0;
	u16 index_upper_bound = vertex_count - 1;
	IndexConverter idxConv(vertex_type, indices);

	if (indices)
		GetIndexBounds(indices, vertex_count, vertex_type, &index_lower_bound, &index_upper_bound);
	vdecoder.DecodeVerts(buf, vertices, index_lower_bound, index_upper_bound);

	VertexReader vreader(buf, vtxfmt, vertex_type);

	const int max_vtcs_per_prim = 3;
	static VertexData data[max_vtcs_per_prim];
	// This is the index of the next vert in data (or higher, may need modulus.)
	static int data_index = 0;

	static GEPrimitiveType prev_prim = GE_PRIM_POINTS;
	if (prim_type != GE_PRIM_KEEP_PREVIOUS) {
		data_index = 0;
		prev_prim = prim_type;
	} else {
		prim_type = prev_prim;
	}

	int vtcs_per_prim;
	switch (prim_type) {
	case GE_PRIM_POINTS: vtcs_per_prim = 1; break;
	case GE_PRIM_LINES: vtcs_per_prim = 2; break;
	case GE_PRIM_TRIANGLES: vtcs_per_prim = 3; break;
	case GE_PRIM_RECTANGLES: vtcs_per_prim = 2; break;
	default: vtcs_per_prim = 0; break;
	}

	// TODO: Do this in two passes - first process the vertices (before indexing/stripping),
	// then resolve the indices. This lets us avoid transforming shared vertices twice.

	switch (prim_type) {
	case GE_PRIM_POINTS:
	case GE_PRIM_LINES:
	case GE_PRIM_TRIANGLES:
	case GE_PRIM_RECTANGLES:
		{
			for (int vtx = 0; vtx < vertex_count; ++vtx) {
				if (indices) {
					vreader.Goto(idxConv.convert(vtx) - index_lower_bound);
				} else {
					vreader.Goto(vtx);
				}

				data[data_index++] = ReadVertex(vreader);
				if (data_index < vtcs_per_prim) {
					// Keep reading.  Note: an incomplete prim will stay read for GE_PRIM_KEEP_PREVIOUS.
					continue;
				}

				// Okay, we've got enough verts.  Reset the index for next time.
				data_index = 0;
				if (outside_range_flag) {
					// Cull the prim if it was outside, and move to the next prim.
					outside_range_flag = false;
					continue;
				}

				switch (prim_type) {
				case GE_PRIM_TRIANGLES:
				{
					if (!gstate.isCullEnabled() || gstate.isModeClear()) {
						Clipper::ProcessTriangle(data[0], data[1], data[2]);
						Clipper::ProcessTriangle(data[2], data[1], data[0]);
					} else if (!gstate.getCullMode()) {
						Clipper::ProcessTriangle(data[2], data[1], data[0]);
					} else {
						Clipper::ProcessTriangle(data[0], data[1], data[2]);
					}
					break;
				}

				case GE_PRIM_RECTANGLES:
					Clipper::ProcessRect(data[0], data[1]);
					break;

				case GE_PRIM_LINES:
					Clipper::ProcessLine(data[0], data[1]);
					break;

				case GE_PRIM_POINTS:
					Clipper::ProcessPoint(data[0]);
					break;

				default:
					_dbg_assert_msg_(G3D, false, "Unexpected prim type: %d", prim_type);
				}
			}
			break;
		}

	case GE_PRIM_LINE_STRIP:
		{
			// Don't draw a line when loading the first vertex.
			// If data_index is 1 or 2, etc., it means we're continuing a line strip.
			int skip_count = data_index == 0 ? 1 : 0;
			for (int vtx = 0; vtx < vertex_count; ++vtx) {
				if (indices) {
					vreader.Goto(idxConv.convert(vtx) - index_lower_bound);
				} else {
					vreader.Goto(vtx);
				}

				data[(data_index++) & 1] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
				} else {
					// We already incremented data_index, so data_index & 1 is previous one.
					Clipper::ProcessLine(data[data_index & 1], data[(data_index & 1) ^ 1]);
				}
			}
			break;
		}

	case GE_PRIM_TRIANGLE_STRIP:
		{
			// Don't draw a triangle when loading the first two vertices.
			int skip_count = data_index >= 2 ? 0 : 2 - data_index;

			for (int vtx = 0; vtx < vertex_count; ++vtx) {
				if (indices) {
					vreader.Goto(idxConv.convert(vtx) - index_lower_bound);
				} else {
					vreader.Goto(vtx);
				}

				data[(data_index++) % 3] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
					continue;
				}

				if (!gstate.isCullEnabled() || gstate.isModeClear()) {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
					// We need to reverse the vertex order for each second primitive,
					// but we additionally need to do that for every primitive if CCW cullmode is used.
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
				}
			}
			break;
		}

	case GE_PRIM_TRIANGLE_FAN:
		{
			// Don't draw a triangle when loading the first two vertices.
			// (this doesn't count the central one.)
			int skip_count = data_index <= 1 ? 1 : 0;
			int start_vtx = 0;

			// Only read the central vertex if we're not continuing.
			if (data_index == 0) {
				if (indices) {
					vreader.Goto(idxConv.convert(0) - index_lower_bound);
				} else {
					vreader.Goto(0);
				}
				data[0] = ReadVertex(vreader);
				data_index++;
				start_vtx = 1;
			}

			for (int vtx = start_vtx; vtx < vertex_count; ++vtx) {
				if (indices) {
					vreader.Goto(idxConv.convert(vtx) - index_lower_bound);
				} else {
					vreader.Goto(vtx);
				}

				data[2 - ((data_index++) % 2)] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
					continue;
				}

				if (!gstate.isCullEnabled() || gstate.isModeClear()) {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
					// We need to reverse the vertex order for each second primitive,
					// but we additionally need to do that for every primitive if CCW cullmode is used.
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
				}
			}
			break;
		}

	default:
		ERROR_LOG(G3D, "Unexpected prim type: %d", prim_type);
		break;
	}

	GPUDebug::NotifyDraw();
}
Esempio n. 10
0
void ReadInputFile(Parameters *parameters)
{
   FILE *inputFile = NULL;
   Graph *graph = NULL;
   Graph *posGraph= NULL;
   Graph *negGraph = NULL;
   ULONG posGraphVertexListSize = 0;
   ULONG posGraphEdgeListSize = 0;
   ULONG negGraphVertexListSize = 0;
   ULONG negGraphEdgeListSize = 0;
   ULONG *vertexListSizePtr = NULL;
   ULONG *edgeListSizePtr = NULL;
   LabelList *labelList = NULL;
   ULONG numPosEgs = 0;
   ULONG numNegEgs = 0;
   ULONG *posEgsVertexIndices = NULL;
   ULONG *negEgsVertexIndices = NULL;
   BOOLEAN readingPositive = TRUE;
   ULONG vertexOffset = 0;
   BOOLEAN directed = TRUE;
   ULONG lineNo = 1;
   char token[TOKEN_LEN];

   labelList = parameters->labelList;
   directed = parameters->directed;

   // Open input file
   inputFile = fopen(parameters->inputFileName,"r");
   if (inputFile == NULL) 
   {
      fprintf(stderr, "Unable to open input file %s.\n",
              parameters->inputFileName);
      exit(1);
   }

   // Parse input file
   while (ReadToken(token, inputFile, &lineNo) != 0) 
   {
      if (strcmp(token, POS_EG_TOKEN) == 0) 
      { // reading positive eg
         if (posGraph == NULL)
            posGraph = AllocateGraph(0,0);
         numPosEgs++;
         vertexOffset = posGraph->numVertices;
         posEgsVertexIndices = AddVertexIndex(posEgsVertexIndices,
                                              numPosEgs, vertexOffset);
         graph = posGraph;
         vertexListSizePtr = & posGraphVertexListSize;
         edgeListSizePtr = & posGraphEdgeListSize;
         readingPositive = TRUE;
      }
      else if (strcmp(token, NEG_EG_TOKEN) == 0) 
      { // reading negative eg
         if (negGraph == NULL)
            negGraph = AllocateGraph(0,0);
         numNegEgs++;
         vertexOffset = negGraph->numVertices;
         negEgsVertexIndices = AddVertexIndex(negEgsVertexIndices,
                                              numNegEgs, vertexOffset);
         graph = negGraph;
         vertexListSizePtr = & negGraphVertexListSize;
         edgeListSizePtr = & negGraphEdgeListSize;
         readingPositive = FALSE;
      }
      else if (strcmp(token, "v") == 0) 
      {  // read vertex
         if (readingPositive && (posGraph == NULL)) 
         {
            // first graph starts without positive token, so assumed positive
            posGraph = AllocateGraph(0,0);
            numPosEgs++;
            vertexOffset = 0;
            posEgsVertexIndices = AddVertexIndex(posEgsVertexIndices,
                                                numPosEgs, vertexOffset);
            graph = posGraph;
            vertexListSizePtr = & posGraphVertexListSize;
            edgeListSizePtr = & posGraphEdgeListSize;
         }
         ReadVertex(graph, inputFile, labelList, vertexListSizePtr, &lineNo,
                    vertexOffset);
      }
      else if (strcmp(token, "e") == 0)    // read 'e' edge
         ReadEdge(graph, inputFile, labelList, edgeListSizePtr, &lineNo,
                  directed, vertexOffset);

      else if (strcmp(token, "u") == 0)    // read undirected edge
         ReadEdge(graph, inputFile, labelList, edgeListSizePtr, &lineNo,
                  FALSE, vertexOffset);

      else if (strcmp(token, "d") == 0)    // read directed edge
         ReadEdge(graph, inputFile, labelList, edgeListSizePtr, &lineNo,
                  TRUE, vertexOffset);

      else 
      {
         fclose(inputFile);
         fprintf(stderr, "Unknown token %s in line %lu of input file %s.\n",
                 token, lineNo, parameters->inputFileName);
         exit(1);
      }
   }
   fclose(inputFile);

   //***** trim vertex, edge and label lists

   parameters->posGraph = posGraph;
   parameters->negGraph = negGraph;
   parameters->labelList = labelList;
   parameters->numPosEgs = numPosEgs;
   parameters->numNegEgs = numNegEgs;
   parameters->posEgsVertexIndices = posEgsVertexIndices;
   parameters->negEgsVertexIndices = negEgsVertexIndices;
}
Esempio n. 11
0
void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type)
{
	// TODO: Cache VertexDecoder objects
	VertexDecoder vdecoder;
	vdecoder.SetVertexType(vertex_type);
	const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();

	static u8 buf[65536 * 48]; // yolo
	u16 index_lower_bound = 0;
	u16 index_upper_bound = vertex_count - 1;
	bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
	u8* indices8 = (u8*)indices;
	u16* indices16 = (u16*)indices;
	if (indices)
		GetIndexBounds(indices, vertex_count, vertex_type, &index_lower_bound, &index_upper_bound);
	vdecoder.DecodeVerts(buf, vertices, index_lower_bound, index_upper_bound);

	VertexReader vreader(buf, vtxfmt, vertex_type);

	const int max_vtcs_per_prim = 3;
	int vtcs_per_prim = 0;
	if (prim_type == GE_PRIM_POINTS) vtcs_per_prim = 1;
	else if (prim_type == GE_PRIM_LINES) vtcs_per_prim = 2;
	else if (prim_type == GE_PRIM_TRIANGLES) vtcs_per_prim = 3;
	else if (prim_type == GE_PRIM_RECTANGLES) vtcs_per_prim = 2;
	else {
		// TODO: Unsupported
	}

	if (prim_type == GE_PRIM_POINTS || prim_type == GE_PRIM_LINES || prim_type == GE_PRIM_TRIANGLES || prim_type == GE_PRIM_RECTANGLES) {
		for (int vtx = 0; vtx < vertex_count; vtx += vtcs_per_prim) {
			VertexData data[max_vtcs_per_prim];

			for (int i = 0; i < vtcs_per_prim; ++i) {
				if (indices)
					vreader.Goto(indices_16bit ? indices16[vtx+i] : indices8[vtx+i]);
				else
					vreader.Goto(vtx+i);

				data[i] = ReadVertex(vreader);
				if (outside_range_flag)
					break;
			}
			if (outside_range_flag) {
				outside_range_flag = false;
				continue;
			}


			switch (prim_type) {
			case GE_PRIM_TRIANGLES:
			{
				if (!gstate.isCullEnabled() || gstate.isModeClear()) {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else if (!gstate.getCullMode())
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				else
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
				break;
			}

			case GE_PRIM_RECTANGLES:
				Clipper::ProcessQuad(data[0], data[1]);
				break;
			}
		}
	} else if (prim_type == GE_PRIM_TRIANGLE_STRIP) {
		VertexData data[3];
		unsigned int skip_count = 2; // Don't draw a triangle when loading the first two vertices

		for (int vtx = 0; vtx < vertex_count; ++vtx) {
			if (indices)
				vreader.Goto(indices_16bit ? indices16[vtx] : indices8[vtx]);
			else
				vreader.Goto(vtx);

			data[vtx % 3] = ReadVertex(vreader);
			if (outside_range_flag) {
				// Drop all primitives containing the current vertex
				skip_count = 2;
				outside_range_flag = false;
				continue;
			}

			if (skip_count) {
				--skip_count;
				continue;
			}

			if (!gstate.isCullEnabled() || gstate.isModeClear()) {
				Clipper::ProcessTriangle(data[0], data[1], data[2]);
				Clipper::ProcessTriangle(data[2], data[1], data[0]);
			} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
				// We need to reverse the vertex order for each second primitive,
				// but we additionally need to do that for every primitive if CCW cullmode is used.
				Clipper::ProcessTriangle(data[2], data[1], data[0]);
			} else {
				Clipper::ProcessTriangle(data[0], data[1], data[2]);
			}
		}
	} else if (prim_type == GE_PRIM_TRIANGLE_FAN) {
		VertexData data[3];
		unsigned int skip_count = 1; // Don't draw a triangle when loading the first two vertices

		if (indices)
			vreader.Goto(indices_16bit ? indices16[0] : indices8[0]);
		else
			vreader.Goto(0);
		data[0] = ReadVertex(vreader);

		for (int vtx = 1; vtx < vertex_count; ++vtx) {
			if (indices)
				vreader.Goto(indices_16bit ? indices16[vtx] : indices8[vtx]);
			else
				vreader.Goto(vtx);

			data[2 - (vtx % 2)] = ReadVertex(vreader);
			if (outside_range_flag) {
				// Drop all primitives containing the current vertex
				skip_count = 2;
				outside_range_flag = false;
				continue;
			}

			if (skip_count) {
				--skip_count;
				continue;
			}

			if (!gstate.isCullEnabled() || gstate.isModeClear()) {
				Clipper::ProcessTriangle(data[0], data[1], data[2]);
				Clipper::ProcessTriangle(data[2], data[1], data[0]);
			} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
				// We need to reverse the vertex order for each second primitive,
				// but we additionally need to do that for every primitive if CCW cullmode is used.
				Clipper::ProcessTriangle(data[2], data[1], data[0]);
			} else {
				Clipper::ProcessTriangle(data[0], data[1], data[2]);
			}
		}
	}
}
Esempio n. 12
0
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type)
{
	VertexDecoder vdecoder;
	vdecoder.SetVertexType(vertex_type);
	const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();

	static u8 buf[65536 * 48]; // yolo
	u16 index_lower_bound = 0;
	u16 index_upper_bound = count_u * count_v - 1;
	bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
	u8* indices8 = (u8*)indices;
	u16* indices16 = (u16*)indices;
	if (indices)
		GetIndexBounds(indices, count_u*count_v, vertex_type, &index_lower_bound, &index_upper_bound);
	vdecoder.DecodeVerts(buf, control_points, index_lower_bound, index_upper_bound);

	VertexReader vreader(buf, vtxfmt, vertex_type);

	int num_patches_u = count_u - 3;
	int num_patches_v = count_v - 3;

	// TODO: Do something less idiotic to manage this buffer
	SplinePatch* patches = new SplinePatch[num_patches_u * num_patches_v];

	for (int patch_u = 0; patch_u < num_patches_u; ++patch_u) {
		for (int patch_v = 0; patch_v < num_patches_v; ++patch_v) {
			SplinePatch& patch = patches[patch_u + patch_v * num_patches_u];

			for (int point = 0; point < 16; ++point) {
				int idx = (patch_u + point%4) + (patch_v + point/4) * count_u;
                if (indices)
                    vreader.Goto(indices_16bit ? indices16[idx] : indices8[idx]);
                else
                    vreader.Goto(idx);

				patch.points[point] = ReadVertex(vreader);
			}
			patch.type = (type_u | (type_v<<2));
			if (patch_u != 0) patch.type &= ~START_OPEN_U;
			if (patch_v != 0) patch.type &= ~START_OPEN_V;
			if (patch_u != num_patches_u-1) patch.type &= ~END_OPEN_U;
			if (patch_v != num_patches_v-1) patch.type &= ~END_OPEN_V;
		}
	}

	for (int patch_idx = 0; patch_idx < num_patches_u*num_patches_v; ++patch_idx) {
		SplinePatch& patch = patches[patch_idx];

		// TODO: Should do actual patch subdivision instead of just drawing the control points!
		const int tile_min_u = (patch.type & START_OPEN_U) ? 0 : 1;
		const int tile_min_v = (patch.type & START_OPEN_V) ? 0 : 1;
		const int tile_max_u = (patch.type & END_OPEN_U) ? 3 : 2;
		const int tile_max_v = (patch.type & END_OPEN_V) ? 3 : 2;
		for (int tile_u = tile_min_u; tile_u < tile_max_u; ++tile_u) {
			for (int tile_v = tile_min_v; tile_v < tile_max_v; ++tile_v) {
				int point_index = tile_u + tile_v*4;

				VertexData v0 = patch.points[point_index];
				VertexData v1 = patch.points[point_index+1];
				VertexData v2 = patch.points[point_index+4];
				VertexData v3 = patch.points[point_index+5];

				// TODO: Backface culling etc
				Clipper::ProcessTriangle(v0, v1, v2);
				Clipper::ProcessTriangle(v2, v1, v0);
				Clipper::ProcessTriangle(v2, v1, v3);
				Clipper::ProcessTriangle(v3, v1, v2);
			}
		}
	}
	delete[] patches;
}
Esempio n. 13
0
void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type, int *bytesRead)
{
	// TODO: Cache VertexDecoder objects
	VertexDecoder vdecoder;
	VertexDecoderOptions options;
	memset(&options, 0, sizeof(options));
	options.expandAllUVtoFloat = false;
	vdecoder.SetVertexType(vertex_type, options);
	const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();

	if (bytesRead)
		*bytesRead = vertex_count * vdecoder.VertexSize();

	// Frame skipping.
	if (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) {
		return;
	}

	u16 index_lower_bound = 0;
	u16 index_upper_bound = vertex_count - 1;
	bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
	bool indices_32bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
	u8 *indices8 = (u8 *)indices;
	u16 *indices16 = (u16 *)indices;
	u32 *indices32 = (u32 *)indices;
	if (indices)
		GetIndexBounds(indices, vertex_count, vertex_type, &index_lower_bound, &index_upper_bound);
	vdecoder.DecodeVerts(buf, vertices, index_lower_bound, index_upper_bound);

	VertexReader vreader(buf, vtxfmt, vertex_type);

	const int max_vtcs_per_prim = 3;
	int vtcs_per_prim = 0;

	switch (prim_type) {
	case GE_PRIM_POINTS: vtcs_per_prim = 1; break;
	case GE_PRIM_LINES: vtcs_per_prim = 2; break;
	case GE_PRIM_TRIANGLES: vtcs_per_prim = 3; break;
	case GE_PRIM_RECTANGLES: vtcs_per_prim = 2; break;
	}

	VertexData data[max_vtcs_per_prim];

	// TODO: Do this in two passes - first process the vertices (before indexing/stripping),
	// then resolve the indices. This lets us avoid transforming shared vertices twice.

	switch (prim_type) {
	case GE_PRIM_POINTS:
	case GE_PRIM_LINES:
	case GE_PRIM_TRIANGLES:
	case GE_PRIM_RECTANGLES:
		{
			for (int vtx = 0; vtx < vertex_count; vtx += vtcs_per_prim) {
				for (int i = 0; i < vtcs_per_prim; ++i) {
					if (indices) {
						if (indices_32bit) {
							vreader.Goto(indices32[vtx + i]);
						} else if (indices_16bit) {
							vreader.Goto(indices16[vtx + i]);
						} else {
							vreader.Goto(indices8[vtx + i]);
						}
					} else {
						vreader.Goto(vtx+i);
					}

					data[i] = ReadVertex(vreader);
					if (outside_range_flag)
						break;
				}
				if (outside_range_flag) {
					outside_range_flag = false;
					continue;
				}

				switch (prim_type) {
				case GE_PRIM_TRIANGLES:
				{
					if (!gstate.isCullEnabled() || gstate.isModeClear()) {
						Clipper::ProcessTriangle(data[0], data[1], data[2]);
						Clipper::ProcessTriangle(data[2], data[1], data[0]);
					} else if (!gstate.getCullMode())
						Clipper::ProcessTriangle(data[2], data[1], data[0]);
					else
						Clipper::ProcessTriangle(data[0], data[1], data[2]);
					break;
				}

				case GE_PRIM_RECTANGLES:
					Clipper::ProcessRect(data[0], data[1]);
					break;

				case GE_PRIM_LINES:
					Clipper::ProcessLine(data[0], data[1]);
					break;

				case GE_PRIM_POINTS:
					Clipper::ProcessPoint(data[0]);
					break;
				}
			}
			break;
		}

	case GE_PRIM_LINE_STRIP:
		{
			int skip_count = 1; // Don't draw a line when loading the first vertex
			for (int vtx = 0; vtx < vertex_count; ++vtx) {
				if (indices)
					vreader.Goto(indices_16bit ? indices16[vtx] : indices8[vtx]);
				else
					vreader.Goto(vtx);

				data[vtx & 1] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
				} else {
					Clipper::ProcessLine(data[(vtx & 1) ^ 1], data[vtx & 1]);
				}
			}
			break;
		}

	case GE_PRIM_TRIANGLE_STRIP:
		{
			int skip_count = 2; // Don't draw a triangle when loading the first two vertices

			for (int vtx = 0; vtx < vertex_count; ++vtx) {
				if (indices)
					vreader.Goto(indices_16bit ? indices16[vtx] : indices8[vtx]);
				else
					vreader.Goto(vtx);

				data[vtx % 3] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
					continue;
				}

				if (!gstate.isCullEnabled() || gstate.isModeClear()) {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
					// We need to reverse the vertex order for each second primitive,
					// but we additionally need to do that for every primitive if CCW cullmode is used.
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
				}
			}
			break;
		}

	case GE_PRIM_TRIANGLE_FAN:
		{
			unsigned int skip_count = 1; // Don't draw a triangle when loading the first two vertices

			if (indices)
				vreader.Goto(indices_16bit ? indices16[0] : indices8[0]);
			else
				vreader.Goto(0);
			data[0] = ReadVertex(vreader);

			for (int vtx = 1; vtx < vertex_count; ++vtx) {
				if (indices)
					vreader.Goto(indices_16bit ? indices16[vtx] : indices8[vtx]);
				else
					vreader.Goto(vtx);

				data[2 - (vtx % 2)] = ReadVertex(vreader);
				if (outside_range_flag) {
					// Drop all primitives containing the current vertex
					skip_count = 2;
					outside_range_flag = false;
					continue;
				}

				if (skip_count) {
					--skip_count;
					continue;
				}

				if (!gstate.isCullEnabled() || gstate.isModeClear()) {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
					// We need to reverse the vertex order for each second primitive,
					// but we additionally need to do that for every primitive if CCW cullmode is used.
					Clipper::ProcessTriangle(data[2], data[1], data[0]);
				} else {
					Clipper::ProcessTriangle(data[0], data[1], data[2]);
				}
			}
			break;
		}
	}

	host->GPUNotifyDraw();
}
Esempio n. 14
0
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type) {
	VertexDecoder vdecoder;
	VertexDecoderOptions options;
	memset(&options, 0, sizeof(options));
	options.expandAllUVtoFloat = false;
	vdecoder.SetVertexType(vertex_type, options);
	const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();

	static u8 buf[65536 * 48]; // yolo
	u16 index_lower_bound = 0;
	u16 index_upper_bound = count_u * count_v - 1;
	bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
	bool indices_32bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
	u8 *indices8 = (u8 *)indices;
	u16 *indices16 = (u16 *)indices;
	u32 *indices32 = (u32 *)indices;
	if (indices)
		GetIndexBounds(indices, count_u*count_v, vertex_type, &index_lower_bound, &index_upper_bound);
	vdecoder.DecodeVerts(buf, control_points, index_lower_bound, index_upper_bound);

	VertexReader vreader(buf, vtxfmt, vertex_type);

	int num_patches_u = count_u - 3;
	int num_patches_v = count_v - 3;

	if (patchBufferSize_ < num_patches_u * num_patches_v) {
		if (patchBuffer_) {
			FreeAlignedMemory(patchBuffer_);
		}
		patchBuffer_ = (SplinePatch *)AllocateAlignedMemory(num_patches_u * num_patches_v, 16);
		patchBufferSize_ = num_patches_u * num_patches_v;
	}
	SplinePatch *patches = patchBuffer_;

	for (int patch_u = 0; patch_u < num_patches_u; ++patch_u) {
		for (int patch_v = 0; patch_v < num_patches_v; ++patch_v) {
			SplinePatch& patch = patches[patch_u + patch_v * num_patches_u];

			for (int point = 0; point < 16; ++point) {
				int idx = (patch_u + point%4) + (patch_v + point/4) * count_u;
				if (indices) {
					if (indices_32bit) {
						vreader.Goto(indices32[idx]);
					} else if (indices_16bit) {
						vreader.Goto(indices16[idx]);
					} else {
						vreader.Goto(indices8[idx]);
					}
				} else {
					vreader.Goto(idx);
				}

				patch.points[point] = ReadVertex(vreader);
			}
			patch.type = (type_u | (type_v<<2));
			if (patch_u != 0) patch.type &= ~START_OPEN_U;
			if (patch_v != 0) patch.type &= ~START_OPEN_V;
			if (patch_u != num_patches_u-1) patch.type &= ~END_OPEN_U;
			if (patch_v != num_patches_v-1) patch.type &= ~END_OPEN_V;
		}
	}

	for (int patch_idx = 0; patch_idx < num_patches_u*num_patches_v; ++patch_idx) {
		SplinePatch& patch = patches[patch_idx];

		// TODO: Should do actual patch subdivision instead of just drawing the control points!
		const int tile_min_u = (patch.type & START_OPEN_U) ? 0 : 1;
		const int tile_min_v = (patch.type & START_OPEN_V) ? 0 : 1;
		const int tile_max_u = (patch.type & END_OPEN_U) ? 3 : 2;
		const int tile_max_v = (patch.type & END_OPEN_V) ? 3 : 2;
		for (int tile_u = tile_min_u; tile_u < tile_max_u; ++tile_u) {
			for (int tile_v = tile_min_v; tile_v < tile_max_v; ++tile_v) {
				int point_index = tile_u + tile_v*4;

				VertexData v0 = patch.points[point_index];
				VertexData v1 = patch.points[point_index+1];
				VertexData v2 = patch.points[point_index+4];
				VertexData v3 = patch.points[point_index+5];

				// TODO: Backface culling etc
				Clipper::ProcessTriangle(v0, v1, v2);
				Clipper::ProcessTriangle(v2, v1, v0);
				Clipper::ProcessTriangle(v2, v1, v3);
				Clipper::ProcessTriangle(v3, v1, v2);
			}
		}
	}

	host->GPUNotifyDraw();
}
Esempio n. 15
0
// parse object data-file -----------------------------------------------------
//
int AodInput::ParseObjectData()
{
	int faceprop_itemsread = 0;
	int facenorm_itemsread = 0;

	InfoMessage( "Processing input data file (format='AOD V1.1') ..." );

	// parse sections and read data -------------------------------
	m_section = _nil;
	while ( m_input.ReadLine( line, TEXTLINE_MAX ) != NULL ) {

		if ( ( m_parser_lineno++ & PARSER_DOT_SIZE ) == 0 )
			printf( "." ), fflush( stdout );

		if ( ( m_scanptr = strtok( line, "/, \t\n\r" ) ) == NULL )
			continue;
		else if ( *m_scanptr == ';' )
			continue;
		else if ( strnicmp( m_scanptr, "<end", 4 ) == 0 )
			break;
		else if ( *m_scanptr == '#' ) {
			if ( strncmp( m_scanptr, _aodsig_str, strlen( _aodsig_str ) ) == 0 ) {
				m_section = _comment;
			} else if ( ( m_section = GetSectionId( m_scanptr ) ) == _nil ) {
				{
				StrScratch error;
				sprintf( error, "%s[Undefined section-name]: %s (line %d)",
						 parser_err_str, m_scanptr, m_parser_lineno );
				ErrorMessage( error );
				}
				HandleCriticalError();
			}
		} else {
			switch ( m_section ) {

			// list of vertices ------------------------------------
			case _vertices :
				ReadVertex();
				break;

			// vertexnums of faces ---------------------------------
			case _faces :
				ReadFace( TRUE );
				break;

			// normals for face's planes ---------------------------
			case _facenormals :

				//NOTE:
				// face normals are currently ignored in the aod
				// file, since they are too inaccurate for later
				// BSP compilation purposes. if no normals are read
				// in, they will be calculated later on anyway.

				//ReadFaceNormal( facenorm_itemsread );
				break;

			// properties of faces ---------------------------------
			case _faceproperties :
				ReadFaceProperties( faceprop_itemsread );
				break;

			// texture->face correspondences ----------------------
			case _correspondences :
				ReadCorrespondences();
				break;

			// texturing data -----------------------------------
			case _textures :
				ReadTextures();
				break;

			// location of the object ---------------------------
			case _worldlocation :
				ReadWorldLocation();
				break;

			// location of camera -------------------------------
			case _camera :
				ReadCameraLocation();
				break;

			// filename of palette file -------------------------
			case _palette :
				ReadPaletteFilename();
				break;

			// scalefactors for object --------------------------
			case _scalefactors :
				ReadScaleFactors();
				break;

			// exchange command for axes ------------------------
			case _xchange :
				ReadXChangeCommand();
				break;

			// set new object origin ----------------------------
			case _setorigin :
				ReadOrigin();
				break;

			}
		}
	}

	// do post processing after parsing
	ApplyOriginTranslation();
	FilterAxesDirSwitch();
	FilterScaleFactors();
	FilterAxesExchange();
	EnforceMaximumExtents();
	m_baseobject->CheckParsedData();

	InfoMessage( "\nObject data ok.\n" );

	// do colorindex to rgb conversion
	ConvertColIndxs();	

	return ( m_inputok = TRUE );
}
Esempio n. 16
0
File: Ase.cpp Progetto: RinM/CGA
void CLoadASE::GetData(t3DModel *pModel, t3DObject *pObject, char *strDesiredData, int desiredObject)
{
	char strWord[255] = {0};
	static int faceNum=0;

	MoveToObject(desiredObject);

	while(!feof(m_FilePointer))
	{
		fscanf(m_FilePointer, "%s", &strWord);

		if(!strcmp(strWord, OBJECT))	
		{
			return;
		}
		else if(!strcmp(strWord, VERTEX))
		{
			if(!strcmp(strDesiredData, VERTEX)) 
			{
				ReadVertex(pObject);
			}
		}
		else if(!strcmp(strWord, TVERTEX))
		{
			if(!strcmp(strDesiredData, TVERTEX)) 
			{
				ReadTextureVertex(pObject, pModel->pMaterials[pObject->materialID]);
			}
		}
		else if(!strcmp(strWord, FACE))
		{
			if(!strcmp(strDesiredData, FACE)) 
			{
				ReadFace(pObject);
			}
		}
		else if(!strcmp(strWord, TFACE))
		{
			if(!strcmp(strDesiredData, TFACE))
			{
				ReadTextureFace(pObject);
			}
		}
		else if(!strcmp(strWord, SHADEMODEL))
		{
			if(!strcmp(strDesiredData, SHADEMODEL))
			{
				pObject->shadeModel = (int)ReadFloat();
				return;
			}				
		}
		else if(!strcmp(strWord, MATERIAL_ID))
		{
			if(!strcmp(strDesiredData, MATERIAL_ID))
			{
				pObject->materialID = (int)ReadFloat();
				return;
			}				
		}
		else 
		{
			fgets(strWord, 100, m_FilePointer);
		}
		
	}
}
Esempio n. 17
0
// parse object data-file -----------------------------------------------------
//
int BspInput::ParseObjectData()
{
	int facedef_itemsread  = 0;
	int faceprop_itemsread = 0;
	int facenorm_itemsread = 0;
	int mappdef_itemsread  = 0;

	InfoMessage( "Processing input data file (format='BSP V1.1') ..." );

	// parse sections and read data -------------------------------
	m_section = _nil;
	while ( m_input.ReadLine( line, TEXTLINE_MAX ) != NULL ) {

		if ( ( m_parser_lineno++ & PARSER_DOT_SIZE ) == 0 )
			printf( "." ), fflush( stdout );

		if ( ( m_scanptr = strtok( line, "/, \t\n\r" ) ) == NULL )
			continue;
		else if ( *m_scanptr == ';' )
			continue;
		else if ( strnicmp( m_scanptr, "<end", 4 ) == 0 )
			break;
		else if ( *m_scanptr == '#' ) {
			if ( strncmp( m_scanptr, _bspsig_str, strlen( _bspsig_str ) ) == 0 ) {
				m_section = _comment;
			} else if ( ( m_section = GetSectionId( m_scanptr ) ) == _nil ) {
				{
				StrScratch error;
				sprintf( error, "%s[Undefined section-name]: %s (line %d)",
						 parser_err_str, m_scanptr, m_parser_lineno );
				ErrorMessage( error );
				}
				HandleCriticalError();
			}
		} else {
			switch ( m_section ) {

			// list of vertices ------------------------------------
			case _vertices :
				ReadVertex();
				break;

			// vertexnums of polygons ------------------------------
			case _polygons :
				ReadFace( FALSE );
				break;

			// definition of faces (consisting of polygons) --------
			case _faces :
				ReadPolyIndxs( facedef_itemsread );
				break;

			// bsptree ---------------------------------------------
			case _bsptree :
				ReadBspTree();
				break;

			// normals for face's planes ---------------------------
			case _facenormals :
				ReadFaceNormal( facenorm_itemsread );
				break;

			// properties of faces ---------------------------------
			case _faceproperties :
				ReadFaceProperties( faceprop_itemsread );
				break;

			// texture->face correspondences ----------------------
			case _correspondences :
				ReadDirectCorrespondences( mappdef_itemsread );
				break;

			// texturing data -----------------------------------
			case _textures :
				ReadTextures();
				break;

			// location of the object ---------------------------
			case _worldlocation :
				ReadWorldLocation();
				break;

			// location of camera -------------------------------
			case _camera :
				ReadCameraLocation();
				break;

			// filename of palette file -------------------------
			case _palette :
				ReadPaletteFilename();
				break;

			// scalefactors for object --------------------------
			case _scalefactors :
				ReadScaleFactors();
				break;

			// exchange command for axes ------------------------
			case _xchange :
				ReadXChangeCommand();
				break;

			// set new object origin ----------------------------
			case _setorigin :
				ReadOrigin();
				break;

			}
		}
	}

	// do post processing after parse
	CorrectMappingCoordinates();
	ApplyOriginTranslation();
	FilterAxesDirSwitch();
	FilterScaleFactors();
	FilterAxesExchange();
	EnforceMaximumExtents();
	m_baseobject->CheckParsedData();

	InfoMessage( "\nObject data ok.\n" );

	// do colorindex to rgb conversion
	ConvertColIndxs();

	return ( m_inputok = TRUE );
}