1 Index: libs/picomodel/pm_ase.c
2 ===================================================================
3 --- libs/picomodel/pm_ase.c (revision 191)
4 +++ libs/picomodel/pm_ase.c (working copy)
7 ----------------------------------------------------------------------------- */
9 +void Sys_Printf (const char *format, ...);
22 picoIndex_t smoothingGroup;
23 picoIndex_t materialId;
24 picoIndex_t subMaterialId;
25 + picoVec3_t facenormal;
26 + picoVec3_t vertexnormal[3];
28 typedef aseFace_t* aseFacesIter_t;
30 @@ -455,33 +457,157 @@
34 +static int VectorCompareExtn( picoVec3_t n1, picoVec3_t n2, float epsilon )
40 + for( i= 0; i < 3; i++ )
41 + if( fabs( n1[ i ] - n2[ i ]) > epsilon )
46 +#define CrossProductTemp(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
48 static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials , aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces )
50 - aseFacesIter_t i = faces, end = faces + numFaces;
51 - for(; i != end; ++i)
56 + aseFacesIter_t i = faces, end = faces + numFaces;
60 + for(i=faces; i != end; ++i)
65 + //VectorSubtract(va, vb, v1);
66 + //VectorSubtract(vc, vb, v2);
67 + //CrossProduct(v1, v2, out);
70 + picoVec3_t v1,v2,v3;
75 + a[j] = vertices[(*i).indices[0]].xyz[j];
76 + b[j] = vertices[(*i).indices[1]].xyz[j];
77 + c[j] = vertices[(*i).indices[2]].xyz[j];
85 + CrossProductTemp(v1,v2,v3);
86 + _pico_normalize_vec(v3);
87 + (*i).facenormal[0]=v3[0];
88 + (*i).facenormal[1]=v3[1];
89 + (*i).facenormal[2]=v3[2];
95 + //if (counter>0) Sys_Printf( "Rebuilding %d Normals\n", counter * 3 );
96 + for(i=faces; i != end; ++i)
98 - /* look up the shader for the material/submaterial pair */
99 + /* look up the shader for the material/submaterial pair */
100 aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, (*i).materialId, (*i).subMaterialId );
101 - if( subMtl == NULL )
103 + if( subMtl == NULL )
111 picoVec3_t* normal[3];
113 picoColor_t* color[3];
114 picoIndex_t smooth[3];
116 - /* we pull the data from the vertex, color and texcoord arrays using the face index data */
117 - for ( j = 0 ; j < 3 ; j ++ )
123 + /* we pull the data from the vertex, color and texcoord arrays using the face index data */
124 + for ( j = 0 ; j < 3 ; j ++ )
126 - xyz[j] = &vertices[(*i).indices[j]].xyz;
127 - normal[j] = &vertices[(*i).indices[j]].normal;
128 + aseFacesIter_t q = faces;
129 + aseFacesIter_t qend = faces + numFaces;
131 + xyz[j] = &vertices[(*i).indices[j]].xyz;
134 + normal[j] = &(*i).facenormal;
137 + //Oooor we can use the smoothing group
139 + //Slow method, but testing
140 + //Find All faces that use this vertex, average their facenormals.
141 + // skip where smoothgroups both equal 0, or don't have any shared bits (x & y)
142 + index=(*i).indices[j];
147 + accum[0]=(*i).facenormal[0];
148 + accum[1]=(*i).facenormal[1];
149 + accum[2]=(*i).facenormal[2];
154 + for(; q != qend; ++q)
159 + // if ( (*q).indices[0]==index || (*q).indices[1]==index || (*q).indices[2]==index)
160 + a[0]= &vertices[(*q).indices[0] ].xyz;
161 + a[1]= &vertices[(*q).indices[1] ].xyz;
162 + a[2]= &vertices[(*q).indices[2] ].xyz;
164 + if ( VectorCompareExtn(*a[0],*xyz[j],0.01f)>0 ||
165 + VectorCompareExtn(*a[1],*xyz[j],0.01f)>0 ||
166 + VectorCompareExtn(*a[2],*xyz[j],0.01f)>0
169 + if ( (*i).smoothingGroup==0 && (*q).smoothingGroup ==0 )
172 + if ( (*i).smoothingGroup & (*q).smoothingGroup )
174 + accum[0]+=(*q).facenormal[0];
175 + accum[1]+=(*q).facenormal[1];
176 + accum[2]+=(*q).facenormal[2];
183 + _pico_normalize_vec(accum);
185 + (*i).vertexnormal[j][0]=accum[0];
186 + (*i).vertexnormal[j][1]=accum[1];
187 + (*i).vertexnormal[j][2]=accum[2];
188 + normal[j]=&(*i).vertexnormal[j];
191 st[j] = &texcoords[(*i).indices[j + 3]].texcoord;
193 - if( colors != NULL && (*i).indices[j + 6] >= 0 )
195 + if( colors != NULL && (*i).indices[j + 6] >= 0 )
197 color[j] = &colors[(*i).indices[j + 6]].color;
199 @@ -490,30 +616,18 @@
203 - smooth[j] = (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup; /* don't merge vertices */
204 + smooth[j] = 0;// (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup; /* don't merge vertices */
208 /* submit the triangle to the model */
209 PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader, smooth );
215 -static void shadername_convert(char* shaderName)
217 - /* unix-style path separators */
218 - char* s = shaderName;
219 - for(; *s != '\0'; ++s)
230 * loads a 3dsmax ase model file.
233 int numColorVertices = 0;
234 int numColorVertexFaces = 0;
236 + int currentVertexFace=0;
237 + int currentVertexIndex=0;
240 aseMaterial_t* materials = NULL;
242 @@ -610,10 +727,11 @@
244 else if (!_pico_stricmp(p->token,"*mesh_numvertex"))
246 - if (!_pico_parse_int( p, &numVertices) )
247 + if (!_pico_parse_int( p, &numVertices) )
248 _ase_error_return("Missing MESH_NUMVERTEX value");
250 vertices = _pico_calloc(numVertices, sizeof(aseVertex_t));
251 + currentVertexIndex=0;
253 else if (!_pico_stricmp(p->token,"*mesh_numfaces"))
256 _ase_error_return("Missing MESH_NUMFACES value");
258 faces = _pico_calloc(numFaces, sizeof(aseFace_t));
261 else if (!_pico_stricmp(p->token,"*mesh_numtvertex"))
265 vertices[index].id = vertexId++;
267 - /* model mesh vertex normal */
268 + else if (!_pico_stricmp(p->token,"*mesh_facenormal"))
270 + //Grab the faceindex for the next vertex normals.
271 + if( numVertices == 0 )
272 + _ase_error_return("Vertex parse error (facenormals)");
274 + if (!_pico_parse_int( p,¤tVertexFace ))
275 + _ase_error_return("Vertex parse error");
277 + if (!_pico_parse_vec( p,faces[currentVertexFace].facenormal ))
278 + _ase_error_return("Vertex parse error");
281 + /* model mesh vertex normal */
282 else if (!_pico_stricmp(p->token,"*mesh_vertexnormal"))
285 @@ -696,10 +828,25 @@
286 /* get vertex data (orig: index +y -x +z) */
287 if (!_pico_parse_int( p,&index ))
288 _ase_error_return("Vertex parse error");
289 - if (!_pico_parse_vec( p,vertices[index].normal ))
291 + //^^ Index is 'wrong' in .ase models. they reference the same vert index with multiple normals..
292 + // I've tried, this is a lost cause. Use the SG's
296 + if (!_pico_parse_vec( p,vertices[counter].normal ))
297 _ase_error_return("Vertex parse error");
298 + vertices[counter].faceid=index;
302 /* model mesh face */
303 + else if (!_pico_stricmp(p->token,"*mesh_normals"))
305 + // counter=0; //part of the above vertex normals fix
308 + /* model mesh face */
309 else if (!_pico_stricmp(p->token,"*mesh_face"))
311 picoIndex_t indexes[3];
314 if (!_pico_stricmp (p->token,"*MESH_SMOOTHING" ))
316 - _pico_parse_int ( p , &faces[index].smoothingGroup );
325 + faces[index].smoothingGroup=0;
327 + //Super dodgy comma delimited string parse
330 + if (*point<=32 || *point==',')
335 + faces[index].smoothingGroup+=1<<total;
347 if (!_pico_stricmp (p->token,"*MESH_MTLID" ))
349 _pico_parse_int ( p , &faces[index].subMaterialId );
350 @@ -755,19 +929,19 @@
353 if( numVertices == 0 )
354 - _ase_error_return("Texture Vertex parse error");
355 + _ase_error_return("Vertex parse error");
357 /* get uv vertex index */
358 - if (!_pico_parse_int( p,&index ) || index >= numTextureVertices)
359 - _ase_error_return("Texture vertex parse error");
360 + if (!_pico_parse_int( p,&index ))
361 + _ase_error_return("UV vertex parse error");
363 /* get uv vertex s */
364 if (!_pico_parse_float( p,&texcoords[index].texcoord[0] ))
365 - _ase_error_return("Texture vertex parse error");
366 + _ase_error_return("UV vertex parse error");
368 /* get uv vertex t */
369 if (!_pico_parse_float( p,&texcoords[index].texcoord[1] ))
370 - _ase_error_return("Texture vertex parse error");
371 + _ase_error_return("UV vertex parse error");
373 /* ydnar: invert t */
374 texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ];
375 @@ -831,6 +1005,13 @@
377 /* leave alpha alone since we don't get any data from the ASE format */
378 colors[index].color[3] = 255;
380 + /* 27 hack, red as alpha */
381 + colors[index].color[3]=colors[index].color[0];
382 + colors[index].color[0]=255;
383 + colors[index].color[1]=255;
384 + colors[index].color[2]=255;
387 /* model color face */
388 else if (!_pico_stricmp(p->token,"*mesh_cface"))
391 /* set material name */
392 _pico_first_token( materialName );
393 - shadername_convert(materialName);
394 PicoSetShaderName( shader, materialName);
396 /* set shader's transparency */
397 @@ -1085,7 +1265,6 @@
400 /* set material name */
401 - shadername_convert(materialName);
402 PicoSetShaderName( shader,materialName );
404 /* set shader's transparency */
405 @@ -1115,8 +1294,18 @@
408 /* convert to shader-name format */
409 - shadername_convert(mapname);
411 + /* unix-style path separators */
413 + for(; *s != '\0'; ++s)
422 /* remove extension */
423 char* last_period = strrchr(p, '.');
424 if(last_period != NULL)
425 @@ -1125,14 +1314,32 @@
429 - /* find shader path */
430 + /* find game root */
431 for(; *p != '\0'; ++p)
433 - if(_pico_strnicmp(p, "models/", 7) == 0 || _pico_strnicmp(p, "textures/", 9) == 0)
434 + if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
439 + /* root-relative */
440 + for(; *p != '\0'; ++p)
448 + /* game-relative */
449 + for(; *p != '\0'; ++p)