Ship() { VecZero(dir); pos[0] = (Flt)(xres/2); pos[1] = (Flt)(yres/2); pos[2] = 0.0f; VecZero(vel); angle = 0.0; color[0] = 1.0; color[1] = 1.0; color[2] = 1.0; }
VOID PolyRead(OBJECT *po, FILE *pf) { INT i, j; /* Indices. */ INT instat; /* Read status. */ INT *vindex; INT totalverts; /* Total # of vertices in poly mesh. */ CHAR normstr[5]; /* Face/vertex normal flag string. */ BOOL pnormals; /* Face normals present? */ VEC3 pnorm; /* Polygon normal accumulator. */ VEC3 *vlist, *vptr, *vp; /* Ptr to vertex list. */ VEC3 *vptmp, *vptmp2; /* Ptr to vertex list. */ VEC3 tmppnt, tmppnt2, cross; POLY *pp; /* Ptr to polygon data. */ ELEMENT *pe; /* Ptr to polygon element. */ pe = po->pelem; /* Allocate space for object data. */ instat = fscanf(pf, "%ld", &totalverts); if (instat != 1) { printf("Error in PolyRead: totalverts.\n"); exit(-1); } pp = GlobalMalloc(sizeof(POLY)*po->numelements, "poly.c"); vlist = GlobalMalloc(sizeof(VEC3)*(totalverts + 1), "poly.c"); vptr = vlist; /* Are polygon face normals supplied? */ instat = fscanf(pf, "%s\n", normstr); if (instat != 1) { printf("Error in PolyRead: face normal indicator.\n"); exit(-1); } pnormals = (normstr[2] == 'y' ? TRUE : FALSE); /* Read vertex list. */ for (i = 0; i < totalverts; i++) { instat = fscanf(pf, "%lf %lf %lf", &(*vptr)[0], &(*vptr)[1], &(*vptr)[2]); if (instat != 3) { printf("Error in PolyRead: vertex %ld.\n", i); exit(-1); } vptr++; } (*vptr)[0] = HUGE_REAL; (*vptr)[1] = HUGE_REAL; (*vptr)[2] = HUGE_REAL; /* Read polygon list. */ for (i = 0; i < po->numelements; i++) { instat = fscanf(pf, "%ld", &(pp->nverts)); if (instat != 1) { printf("Error in PolyRead: vertex count.\n"); exit(-1); } if (pp->nverts > MAX_VERTS) { printf("Polygon vertex count, %ld, exceeds maximum.\n", pp->nverts); exit(-1); } if (pnormals) { instat = fscanf(pf, " %lf %lf %lf", &(pp->norm[0]), &(pp->norm[1]), &(pp->norm[2])); if (instat != 3) { printf("Error in PolyRead: face normal %ld.\n", i); exit(-1); } } pp->vptr = vlist; pp->vindex = GlobalMalloc(sizeof(INT)*pp->nverts, "poly.c"); vindex = pp->vindex; for (j = 0; j < pp->nverts; j++) { instat = fscanf(pf, "%ld", vindex++); if (instat != 1) { printf("Error in PolyRead: vertex index %ld.\n", i); exit(-1); } } /* If not supplied, calculate plane normal. */ vindex = pp->vindex; vptr = vlist; if (!pnormals) { vp = vptr + (*vindex); VecZero(pnorm); for (j = 0; j < pp->nverts - 2; j++) { vptmp = vptr + (*(vindex + 1)); vptmp2 = vptr + (*(vindex + 2)); VecSub(tmppnt, (*vptmp), (*vp)); VecSub(tmppnt2, (*vptmp2), (*vptmp)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); vp = vptmp; vindex += 1; } VecSub(tmppnt, (*vptmp2), (*vp)); vindex = pp->vindex; vp = vptr + (*vindex); VecSub(tmppnt2, (*vp), (*vptmp2)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); vp = vptr + (*vindex); VecSub(tmppnt, (*vp), (*vptmp2)); vptmp = vptr + (*(vindex + 1)); VecSub(tmppnt2, (*vptmp), (*vp)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); VecScale(pp->norm, 1.0/VecLen(pnorm), pnorm); } /* Calculate plane equation d. */ vp = pp->vptr + *(pp->vindex); pp->d = -(pp->norm[0]*(*vp)[0] + pp->norm[1]*(*vp)[1] + pp->norm[2]*(*vp)[2]); pe->data = (CHAR *)pp; pe->parent = po; PolyElementBoundBox(pe, pp); pp++; pe++; } }
/************* * DESCRIPTION: - * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParseNamedObject(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; TRIANGLE *triangle; TRILIST *ph1,*ph2; float angle; UWORD p1, p2, p3; UWORD *edges; int i, h; ReadASCIIZ(data, data->ObjName); do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_TRIANGLE: ParseTriObject(data, &chunk); break; } EndChunk(data, &chunk); } while (INCHUNK); if (data->TriList && (data->link->type == LINK_RENDERER)) { // go through all vertices and calculate normals (only for renderer) for (i = 0; i < data->pointcount; i++) { data->VertNorms[i].x = data->VertNorms[i].y = data->VertNorms[i].z = 0.f; ph1 = data->TriList[i]; while (ph1) { for (ph2 = ph1->next; ph2 != NULL; ph2 = ph2->next) { if (!ph1->flag || !ph2->flag) { // test angle between two triangles angle = VecAngle(data->TriNorms[ph1->tri], data->TriNorms[ph2->tri]); // if (angle < 2*PI && angle > /*cos_*/smooth_angle) if (angle >0 && angle < /*cos_*/data->smooth_angle) { if (!ph1->flag) { VecAdd(&data->VertNorms[i], &data->TriNorms[ph1->tri], &data->VertNorms[i]); ph1->flag = TRUE; data->TriSmooth[ph1->tri] = TRUE; } if (!ph2->flag) { VecAdd(&data->VertNorms[i], &data->TriNorms[ph2->tri], &data->VertNorms[i]); ph2->flag = TRUE; data->TriSmooth[ph2->tri] = TRUE; } } } } ph2 = ph1; ph1 = ph1->next; delete ph2; } VecNormalize(&data->VertNorms[i]); } } if (data->face) { data->link->ObjectBegin(data->rc); data->defaultsurface = data->link->SurfaceAdd(data->rc); if (!data->defaultsurface) { data->err = ERR_MEM; return; } data->link->SurfaceName(data->rc, data->defaultsurface, "default"); data->link->SurfaceDiffuse(data->rc, data->defaultsurface, 0.9f, 0.9f, 0.9f); data->link->SurfaceAmbient(data->rc, data->defaultsurface, 0.1f, 0.1f, 0.1f); data->link->SurfaceRefPhong(data->rc, data->defaultsurface, 49.f); triangle = data->link->TriangleAdd(data->rc, data->facecount,data->defaultsurface,data->mainactor); if (!triangle) { data->err = ERR_MEM; return; } if (data->link->type == LINK_SCENARIO) { // modeler needs points,edges and faces seperate if (data->link->TriangleAddPoints(data->rc, data->pointcount,data->points) == -1) { data->err = ERR_MEM; return; } edges = new UWORD[data->facecount*6]; if (!edges) { data->err = ERR_MEM; return; } for (i = 0; i < data->facecount; i++) { h = i*6; edges[h++] = data->face[i].p1; edges[h++] = data->face[i].p2; edges[h++] = data->face[i].p2; edges[h++] = data->face[i].p3; edges[h++] = data->face[i].p3; edges[h++] = data->face[i].p1; } if (data->link->TriangleAddEdges(data->rc, data->facecount*3,edges) == -1) { delete edges; data->err = ERR_MEM; return; } delete edges; } for (i = 0; i < data->facecount; i++) { p1 = data->face[i].p1; p2 = data->face[i].p3; p3 = data->face[i].p2; if(data->replacesurface) data->link->TriangleSurface(data->rc, triangle, data->replacesurface); else { if(!data->material[i]) data->link->TriangleSurface(data->rc, triangle, data->defaultsurface); else data->link->TriangleSurface(data->rc, triangle, data->material[i]); } if (data->link->type == LINK_SCENARIO) { // modeler needs edges data->link->TriangleSetEdges(data->rc, triangle,i*3,i*3+1,i*3+2); } else { // raystorm renderer needs triangles and normals data->link->TrianglePoints(data->rc, triangle,&data->points[p1],&data->points[p2],&data->points[p3]); if (!VecZero(data->TriNorms[i])) { // generate smooth triangle when smooth flag is set if (data->TriSmooth[i]) { data->link->TriangleVNorm(data->rc, triangle, VecZero(data->VertNorms[p1]) ? &data->TriNorms[i] : &data->VertNorms[p1], VecZero(data->VertNorms[p2]) ? &data->TriNorms[i] : &data->VertNorms[p2], VecZero(data->VertNorms[p3]) ? &data->TriNorms[i] : &data->VertNorms[p3]); } } if(data->mapping) { data->link->TriangleUV(data->rc, triangle, &data->mapping[p1], &data->mapping[p2], &data->mapping[p3]); } } // next triangle triangle = data->link->TriangleGetNext(data->rc, triangle); } data->link->ObjectEnd(data->rc); } CleanupMesh(data); }