void T3Dmesh::copyfrom(const CSGShape &shape) { reset(); Titemarray<CSGVector> tmp_normals; for (int i=0; i<shape.G_vertexcount(); i++) { addvertex(&Tvec3d(shape.G_vertex(i).x,shape.G_vertex(i).y,shape.G_vertex(i).z),i); tmp_normals.add(CSGVector(0,0,0)); vertices_label[vertices.G_count()-1]=-1; } for (int i=0; i<shape.G_facecount(); i++) { const CSGFace &face=shape.G_face(i); CSGVertex* vs[3]; const CSGVector *ns[3]; int idxs[3]; vs[0]=face.v1;vs[1]=face.v2;vs[2]=face.v3; ns[0]=&face.n1;ns[1]=&face.n2;ns[2]=&face.n3; for (int j=0; j<3; j++) { int oidx=vs[j]->idx;idxs[j]=oidx; bool makenew=false; if ((vertices_label[oidx]>=0)&&(face.label!=vertices_label[oidx])) makenew=true; if (!ns[j]->IsZero()) { if (!tmp_normals[oidx].IsZero()) { if (!ns[j]->IsSame(tmp_normals[oidx])) makenew=true; } } if (makenew) { Tvec3d v0=vertices[oidx]; idxs[j]=addvertex(&v0,oidx); vertices_label[idxs[j]]=face.label; vertices_normals[idxs[j]].set(ns[j]->x,ns[j]->y,ns[j]->z); } else { tmp_normals[oidx]=*ns[j]; vertices_label[oidx]=face.label; vertices_normals[oidx].set(ns[j]->x,ns[j]->y,ns[j]->z); } } addtriangle(idxs[0],idxs[1],idxs[2]); } hasvertexnormals=true; calcnormals(); calcedges(); hasowncolors=false; }
int T3Dmesh::addvertex(Tvertex *v, int vertexidx, Tvector *normal, double texcoord1, double texcoord2) { Tvec3d v1,v2; v1.set(v->G3_x(),v->G3_y(),v->G3_z()); if (normal!=NULL) { v2.set(normal->G_x(),normal->G_y(),normal->G_z()); return addvertex(&v1,vertexidx,&v2,texcoord1,texcoord2); } else return addvertex(&v1,vertexidx,NULL,texcoord1,texcoord2); }
// if the point (x,y) is near a line, divides the line with it Tvertex *insertvertex(coord3d x,coord3d y) { Tline *l; Tsector *s; if (!findline(&l,&s,x,y)) return NULL; int v=addvertex(x,y); refvertex(v); Twall *w; for (w=*l->walls;w;w=w->next) { if (is_hole(w)) { Tsector *s=((Thole *)w)->sector; Tline *l1; for (l1=s->lines;l1;l1=l1->next) if (l1->v1==l->v2 && l1->v2==l->v1) { splitline(l1,v); refvertex(v); refvertex(v); s->linesnum++; } } } splitline(l,v); s->linesnum++; return verts+v; }
void T3Dmesh::createsphere(Tvec3d ¢, double radius, int resol) { int i,j,i1,i2,j1,j2; double al1,al2; Tvec3d norm,vertex; int ct=0; for (i=0; i<=2*resol-1; i++) { al1=(i*1.0)/resol*Pi; for (j=0; j<=resol; j++) { al2=(j*1.0)/resol*Pi; norm.x=(V3DFLOAT)(sin(al2)*cos(al1)); norm.y=(V3DFLOAT)(sin(al2)*sin(al1)); norm.z=(V3DFLOAT)(cos(al2)); vertex.lincomb(cent,norm,1,radius); addvertex(&vertex,ct,&norm,al1/(2*Pi)+0.5,1.0-al2/Pi); ct++; } } for (i=0; i<=2*resol-1; i++) { i1=i;i2=(i+1)%(2*resol); for (j=0; j<resol; j++) { j1=j; j2=j+1; addtriangle(i1*(resol+1)+j2,i2*(resol+1)+j2,i2*(resol+1)+j1); addtriangle(i1*(resol+1)+j2,i2*(resol+1)+j1,i1*(resol+1)+j1); } } calcnormals(); calcedges(); hasowncolors=false; }
static void buildgraph(void) { profilenode *n, *p; vertex *u, *v; edge *e; graphedge *g; profiledata d; for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL; n = (profilenode *) __mp_successor(&n->node)) if ((n->data != 0) && !(n->flags & 1)) { cleardata(&d); sumdata(&d, &data[n->data - 1]); p = (profilenode *) __mp_successor(&n->node); while ((p != NULL) && ((p->addr == n->addr) || (!useaddresses && (p->symbol != 0) && (p->symbol == n->symbol)))) { if ((p->data != 0) && !(p->flags & 1) && comparestack(n, p, 1)) { sumdata(&d, &data[p->data - 1]); p->flags |= 1; } p = (profilenode *) __mp_successor(&p->node); } p = n; if (useaddresses || (p->symbol == 0)) u = (vertex *) __mp_search(temptree.root, (unsigned long) p->addr); else u = (vertex *) __mp_search(temptree.root, p->symbol); if (u == NULL) u = addvertex(p); if ((g = __mp_findedge(&graph, &u->gnode, &graph.end)) == NULL) e = addedge(&u->gnode, &graph.end); else e = (edge *) ((char *) g - offsetof(edge, gnode)); sumdata(&e->data, &d); u->pnode->flags |= 2; for (v = u; p->parent != 0; u = v) { p = &nodes[p->parent - 1]; if (useaddresses || (p->symbol == 0)) v = (vertex *) __mp_search(temptree.root, (unsigned long) p->addr); else v = (vertex *) __mp_search(temptree.root, p->symbol); if (v == NULL) v = addvertex(p); if ((g = __mp_findedge(&graph, &v->gnode, &u->gnode)) == NULL) e = addedge(&v->gnode, &u->gnode); else e = (edge *) ((char *) g - offsetof(edge, gnode)); /* Find out if we've been here before. If we have then we have * detected a cycle in the call graph and we should not * contribute anything to the current edge since we have done so * already. However, we mark the edge as being part of a cycle * since it is useful to know this later on. */ if (v->pnode->flags & 2) e->flags |= 2; else { sumdata(&e->data, &d); v->pnode->flags |= 2; } } if ((g = __mp_findedge(&graph, &graph.start, &v->gnode)) == NULL) e = addedge(&graph.start, &v->gnode); else e = (edge *) ((char *) g - offsetof(edge, gnode)); sumdata(&e->data, &d); /* Clear all of the flags from the current call stack that we used * to determine cycles in the call graph. */ p = n; do { if (useaddresses || (p->symbol == 0)) v = (vertex *) __mp_search(temptree.root, (unsigned long) p->addr); else v = (vertex *) __mp_search(temptree.root, p->symbol); v->pnode->flags &= ~2; if (p->parent != 0) p = &nodes[p->parent - 1]; else p = NULL; } while (p != NULL); } for (n = (profilenode *) __mp_minimum(proftree.root); n != NULL; n = (profilenode *) __mp_successor(&n->node)) n->flags = 0; }