static void _ase_submit_triangles_unshared ( picoModel_t* model , aseMaterial_t* materials , aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces, int meshHasNormals ) { aseFacesIter_t i = faces, end = faces + numFaces; aseUniqueIndices_t indices; aseUniqueIndices_t remap; aseUniqueIndices_reserve(&indices, numFaces * 3); aseUniqueIndices_reserve(&remap, numFaces * 3); indices.faces = faces; for(; i != end; ++i) { /* look up the shader for the material/submaterial pair */ aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, (*i).materialId, (*i).subMaterialId ); if( subMtl == NULL ) { return; } { picoSurface_t* surface = PicoModelFindOrAddSurface(model, subMtl->shader); int j; /* we pull the data from the vertex, color and texcoord arrays using the face index data */ for ( j = 0 ; j < 3 ; j ++ ) { picoIndex_t index = (picoIndex_t)(((i - faces) * 3) + j); picoIndex_t size = (picoIndex_t)aseUniqueIndices_size(&indices); picoIndex_t unique = aseUniqueIndices_insertUniqueVertex(&indices, index); picoIndex_t numVertexes = PicoGetSurfaceNumVertexes(surface); picoIndex_t numIndexes = PicoGetSurfaceNumIndexes(surface); aseUniqueIndices_pushBack(&remap, numIndexes); PicoSetSurfaceIndex(surface, numIndexes, remap.data[unique]); if(unique == size) { PicoSetSurfaceXYZ(surface, numVertexes, vertices[(*i).indices[j]].xyz); PicoSetSurfaceNormal(surface, numVertexes, vertices[(*i).indices[j]].normal); PicoSetSurfaceST(surface, 0, numVertexes, texcoords[(*i).indices[j + 3]].texcoord); if ( (*i).indices[j + 6] >= 0 ) { PicoSetSurfaceColor(surface, 0, numVertexes, colors[(*i).indices[j + 6]].color); } else { PicoSetSurfaceColor(surface, 0, numVertexes, white); } PicoSetSurfaceSmoothingGroup(surface, numVertexes, (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup); } } } } aseUniqueIndices_clear(&indices); aseUniqueIndices_clear(&remap); }
/** * @brief A nice way to add individual triangles to the model. * Chooses an appropriate surface based on the shader, or adds a new surface if necessary */ void PicoAddTriangleToModel (picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader, picoIndex_t* smoothingGroup) { int i, j; int vertDataIndex; picoSurface_t* workSurface = NULL; /* see if a surface already has the shader */ for (i = 0; i < model->numSurfaces; i++) { workSurface = model->surface[i]; if (workSurface->shader == shader) { break; } } /* no surface uses this shader yet, so create a new surface */ if (!workSurface || i >= model->numSurfaces) { /* create a new surface in the model for the unique shader */ workSurface = PicoNewSurface(model); if (!workSurface) { _pico_printf(PICO_ERROR, "Could not allocate a new surface!\n"); return; } /* do surface setup */ PicoSetSurfaceType(workSurface, PICO_TRIANGLES); PicoSetSurfaceName(workSurface, shader->name); PicoSetSurfaceShader(workSurface, shader); } /* add the triangle data to the surface */ for (i = 0; i < 3; i++) { /* get the next free spot in the index array */ int newVertIndex = PicoGetSurfaceNumIndexes(workSurface); /* get the index of the vertex that we're going to store at newVertIndex */ vertDataIndex = PicoFindSurfaceVertexNum(workSurface, *xyz[i], *normals[i], numSTs, st[i], numColors, colors[i], smoothingGroup[i]); /* the vertex wasn't found, so create a new vertex in the pool from the data we have */ if (vertDataIndex == -1) { /* find the next spot for a new vertex */ vertDataIndex = PicoGetSurfaceNumVertexes(workSurface); /* assign the data to it */ PicoSetSurfaceXYZ(workSurface, vertDataIndex, *xyz[i]); PicoSetSurfaceNormal(workSurface, vertDataIndex, *normals[i]); /* make sure to copy over all available ST's and colors for the vertex */ for (j = 0; j < numColors; j++) { PicoSetSurfaceColor(workSurface, j, vertDataIndex, colors[i][j]); } for (j = 0; j < numSTs; j++) { PicoSetSurfaceST(workSurface, j, vertDataIndex, st[i][j]); } PicoSetSurfaceSmoothingGroup(workSurface, vertDataIndex, smoothingGroup[i]); } /* add this vertex to the triangle */ PicoSetSurfaceIndex(workSurface, newVertIndex, vertDataIndex); } }