uint DebugShapes::MakeVector(const glm::vec3& start, const glm::vec3& end, float lifetime, bool depthTest, const glm::vec3& color) { Assert(activeRenderer != NULL); if(VECTOR_GEO_ID == (uint)-1) { Neumont::ShapeData data = Neumont::ShapeGenerator::makeVector(5); VECTOR_GEO_ID = activeRenderer->AddGeometry(data.verts, data.numVerts, data.indices, data.numIndices, rm_TRIANGLES); } CheckForShader(); Assert(nextInstanceIndex < MAX_DEBUG_RENDERABLES); DebugShapeInstanceInfo newShape = DebugShapeInstanceInfo(); newShape.duration = lifetime; newShape.elapsed = 0; // transform matrix glm::vec3 rotation = end - start; float length = glm::length(rotation); float rotationAngle = acosf(glm::dot(glm::normalize(glm::vec3(0.0f, 0.0f, 1.0f)), glm::normalize(rotation))); float convertedAngle = rotationAngle * 180.0f / PI; glm::vec3 cross = glm::cross(glm::vec3(0,0,1), rotation); if(end.x == start.x && end.y == start.y) cross = glm::cross(glm::vec3(0,1,0), rotation); if(cross.x == 0.0f && cross.y == 0.0f && cross.z == 0.0f) { cross.x = 1.0f; convertedAngle = 0; } glm::mat4 transform = glm::translate(start) * glm::rotate(convertedAngle, cross) * glm::scale(1.0f, 1.0f, length) * glm::translate(0.0f, -0.015625f, 0.5f) * glm::scale(0.0625f, 0.0625f, -0.5f); // transform matrix newShape.position = transform; newShape.geoBufferID = VECTOR_GEO_ID; newShape.color = color; newShape.UseDepthTest = depthTest; return MakeShape(newShape); }
uint DebugShapes::MakeLine(const glm::mat4& position, float lifetime, bool depthTest, const glm::vec3& color) { Assert(activeRenderer != NULL); if(LINE_GEO_ID == (uint)-1) { Neumont::ShapeData data = Neumont::ShapeGenerator::makeLine(); LINE_GEO_ID = activeRenderer->AddGeometry(data.verts, data.numVerts, data.indices, data.numIndices, rm_LINES); } CheckForShader(); Assert(nextInstanceIndex < MAX_DEBUG_RENDERABLES); DebugShapeInstanceInfo newShape = DebugShapeInstanceInfo(); newShape.duration = lifetime; newShape.elapsed = 0; newShape.position = position; newShape.geoBufferID = LINE_GEO_ID; newShape.color = color; newShape.UseDepthTest = depthTest; return MakeShape(newShape); }
static void generate_system (ModeInfo * mi) { pipesstruct *pp = &pipes[MI_SCREEN(mi)]; Bool wire = MI_IS_WIREFRAME(mi); int newdir; int OPX, OPY, OPZ; Bool reset_p = False; pp->system_index = 0; pp->system_size = 0; pinit (mi, 1); while (1) { glNewList (get_dlist (mi, pp->system_size++), GL_COMPILE); mi->polygon_count = 0; glPushMatrix(); FindNeighbors(mi); if (wire) glColor4fv (pp->system_color); else glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pp->system_color); /* If it's the begining of a system, draw a sphere */ if (pp->olddir == dirNone) { glPushMatrix(); glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0); mySphere(0.6, wire); glPopMatrix(); } /* Check for stop conditions */ if (pp->ndirections == 0 || pp->counter > pp->system_length) { glPushMatrix(); glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0); /* Finish the system with another sphere */ mySphere(0.6, wire); glPopMatrix(); /* If the maximum number of system was drawn, restart (clearing the screen), */ /* else start a new system. */ if (++pp->system_number > pp->number_of_systems) { reset_p = True; } else { pinit(mi, 0); } goto NEXT; } pp->counter++; pp->turncounter++; /* Do will the direction change? if so, determine the new one */ newdir = pp->nowdir; if (!pp->directions[newdir]) { /* cannot proceed in the current direction */ newdir = SelectNeighbor(mi); } else { if (tightturns) { /* random change (20% chance) */ if ((pp->counter > 1) && (NRAND(100) < 20)) { newdir = SelectNeighbor(mi); } } else { /* Chance to turn increases after each length of pipe drawn */ if ((pp->counter > 1) && NRAND(50) < NRAND(pp->turncounter + 1)) { newdir = SelectNeighbor(mi); pp->turncounter = 0; } } } /* Has the direction changed? */ if (newdir == pp->nowdir) { /* If not, draw the cell's center pipe */ glPushMatrix(); glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0); /* Chance of factory shape here, if enabled. */ if ((pp->counter > 1) && (NRAND(100) < factory)) { MakeShape(mi, newdir); } else { MakeTube(mi, newdir); } glPopMatrix(); } else { /* If so, draw the cell's center elbow/sphere */ int sysT = pp->system_type; if (sysT == NofSysTypes + 1) { sysT = ((pp->system_number - 1) % NofSysTypes) + 1; } glPushMatrix(); switch (sysT) { case 1: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0); mySphere(elbowradius, wire); break; case 2: case 3: switch (pp->nowdir) { case dirUP: switch (newdir) { case dirLEFT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 1.0, 0.0, 0.0); break; case dirRIGHT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirFAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); glRotatef(180.0, 0.0, 0.0, 1.0); break; case dirNEAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); glRotatef(180.0, 1.0, 0.0, 0.0); break; } break; case dirDOWN: switch (newdir) { case dirLEFT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0); break; case dirRIGHT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirFAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 0.0, 1.0, 0.0); break; case dirNEAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); break; } break; case dirLEFT: switch (newdir) { case dirUP: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirDOWN: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirFAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirNEAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 0.0, 1.0); break; } break; case dirRIGHT: switch (newdir) { case dirUP: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0); break; case dirDOWN: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0); glRotatef(180.0, 1.0, 0.0, 0.0); break; case dirFAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); break; case dirNEAR: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 1.0, 0.0, 0.0); break; } break; case dirNEAR: switch (newdir) { case dirLEFT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); break; case dirRIGHT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 1.0, 0.0); break; case dirUP: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(270.0, 0.0, 1.0, 0.0); break; case dirDOWN: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0 - (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); glRotatef(180.0, 0.0, 0.0, 1.0); break; } break; case dirFAR: switch (newdir) { case dirUP: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 + (one_third), (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); break; case dirDOWN: glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0 - (one_third), (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 0.0, 1.0, 0.0); glRotatef(180.0, 1.0, 0.0, 0.0); break; case dirLEFT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 - (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(90.0, 1.0, 0.0, 0.0); break; case dirRIGHT: glTranslatef((pp->PX - 16) / 3.0 * 4.0 + (one_third), (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0 + (one_third)); glRotatef(270.0, 1.0, 0.0, 0.0); glRotatef(180.0, 0.0, 0.0, 1.0); break; } break; } myElbow(mi, (sysT == 2)); break; } glPopMatrix(); } OPX = pp->PX; OPY = pp->PY; OPZ = pp->PZ; pp->olddir = pp->nowdir; pp->nowdir = newdir; switch (pp->nowdir) { case dirUP: pp->PY++; break; case dirDOWN: pp->PY--; break; case dirLEFT: pp->PX--; break; case dirRIGHT: pp->PX++; break; case dirNEAR: pp->PZ++; break; case dirFAR: pp->PZ--; break; } pp->Cells[pp->PX][pp->PY][pp->PZ] = 1; /* Cells'face pipe */ glTranslatef(((pp->PX + OPX) / 2.0 - 16) / 3.0 * 4.0, ((pp->PY + OPY) / 2.0 - 12) / 3.0 * 4.0, ((pp->PZ + OPZ) / 2.0 - 16) / 3.0 * 4.0); MakeTube(mi, newdir); NEXT: glPopMatrix(); glEndList(); pp->poly_counts [pp->system_size-1] = mi->polygon_count; if (reset_p) break; } }
void NURBS::Refine(vector<Reference<Shape> > &refined) const { // Compute NURBS dicing rates int diceu = 30, dicev = 30; float *ueval = new float[diceu]; float *veval = new float[dicev]; Point *evalPs = new Point[diceu*dicev]; Normal *evalNs = new Normal[diceu*dicev]; int i; for (i = 0; i < diceu; ++i) ueval[i] = Lerp((float)i / (float)(diceu-1), umin, umax); for (i = 0; i < dicev; ++i) veval[i] = Lerp((float)i / (float)(dicev-1), vmin, vmax); // Evaluate NURBS over grid of points memset(evalPs, 0, diceu*dicev*sizeof(Point)); memset(evalNs, 0, diceu*dicev*sizeof(Point)); float *uvs = new float[2*diceu*dicev]; // Turn NURBS into triangles Homogeneous3 *Pw = (Homogeneous3 *)P; if (!isHomogeneous) { Pw = (Homogeneous3 *)alloca(nu*nv*sizeof(Homogeneous3)); for (int i = 0; i < nu*nv; ++i) { Pw[i].x = P[3*i]; Pw[i].y = P[3*i+1]; Pw[i].z = P[3*i+2]; Pw[i].w = 1.; } } for (int v = 0; v < dicev; ++v) { for (int u = 0; u < diceu; ++u) { uvs[2*(v*diceu+u)] = ueval[u]; uvs[2*(v*diceu+u)+1] = veval[v]; Vector dPdu, dPdv; Point pt = NURBSEvaluateSurface(uorder, uknot, nu, ueval[u], vorder, vknot, nv, veval[v], Pw, &dPdu, &dPdv); evalPs[v*diceu + u].x = pt.x; evalPs[v*diceu + u].y = pt.y; evalPs[v*diceu + u].z = pt.z; evalNs[v*diceu + u] = Normal(Normalize(Cross(dPdu, dPdv))); } } // Generate points-polygons mesh int nTris = 2*(diceu-1)*(dicev-1); int *vertices = new int[3 * nTris]; int *vertp = vertices; // Compute the vertex offset numbers for the triangles for (int v = 0; v < dicev-1; ++v) { for (int u = 0; u < diceu-1; ++u) { #define VN(u,v) ((v)*diceu+(u)) *vertp++ = VN(u, v); *vertp++ = VN(u+1, v); *vertp++ = VN(u+1, v+1); *vertp++ = VN(u, v); *vertp++ = VN(u+1, v+1); *vertp++ = VN(u, v+1); #undef VN } } int nVerts = diceu*dicev; ParamSet paramSet; paramSet.AddInt("indices", vertices, 3*nTris); paramSet.AddPoint("P", evalPs, nVerts); paramSet.AddFloat("uv", uvs, 2 * nVerts); paramSet.AddNormal("N", evalNs, nVerts); refined.push_back(MakeShape("trianglemesh", ObjectToWorld, reverseOrientation, paramSet)); // Cleanup from NURBS refinement delete[] uvs; delete[] ueval; delete[] veval; delete[] evalPs; delete[] evalNs; delete[] vertices; }