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; }
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; }
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; }
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; }
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); }
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++; } // 根据读入的信息组装三角形,并以某种方式使用即可,比如存入到列表中、保存到文件等... } }
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); }
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; }
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(); }
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; }
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]); } } } }
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; }
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(); }
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(); }
// 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 ); }
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); } } }
// 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 ); }