TriangleList getSurroundingTriangles(QPointF *points, quint32 size, quint32 layers, Vertex v, QPointF *centerPtr) { TriangleList result; if (!v.layer) { for (quint32 i = 0; i < size; ++i) result.append(TRIANGLE(0, i, 0)); return result; } // inner part result.append(TRIANGLE(v.layer - 1, v.sector, 2 * v.index)); if (v.index) { result.append(TRIANGLE(v.layer - 1, v.sector, 2 * v.index - 1)); result.append(TRIANGLE(v.layer - 1, v.sector, 2 * v.index - 2)); } else result.append(TRIANGLE(v.layer - 1, (v.sector + size - 1) % size, 2 * v.layer - 2)); // outer part if (v.layer < layers) { result.append(TRIANGLE(v.layer, v.sector, 2 * v.index)); result.append(TRIANGLE(v.layer, v.sector, 2 * v.index + 1)); if (v.index) { result.append(TRIANGLE(v.layer, v.sector, 2 * v.index - 1)); } else { result.append(TRIANGLE(v.layer, (v.sector + size - 1) % size, 2 * v.layer - 1)); result.append(TRIANGLE(v.layer, (v.sector + size - 1) % size, 2 * v.layer)); } } return result; }
TRIANGLE TET::face(int x) { if (x == 0) return TRIANGLE(*vertices[0], *vertices[1], *vertices[3]); if (x == 1) return TRIANGLE(*vertices[0], *vertices[2], *vertices[1]); if (x == 2) return TRIANGLE(*vertices[3], *vertices[2], *vertices[0]); return TRIANGLE(*vertices[1], *vertices[2], *vertices[3]); }
static void draw_tetra(ModeInfo * mi) { morph3dstruct *mp = &morph3d[MI_SCREEN(mi)]; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]); TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-tetraangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]); TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes); glPopMatrix(); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + tetraangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]); TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + tetraangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]); TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes); }
static void bag_vquad( TRIANGLEBAG& triangles, //{{{ double x1, double y1, double x2, double y2, double z1, double z2 ) { triangles.push_back( TRIANGLE( x1, y1, z1, x2, y2, z1, x2, y2, z2 ) ); triangles.push_back( TRIANGLE( x1, y1, z1, x2, y2, z2, x1, y1, z2 ) ); }
void echoTriangleSet(echoObject *tri, echoPos_t xx0, echoPos_t yy0, echoPos_t zz0, echoPos_t xx1, echoPos_t yy1, echoPos_t zz1, echoPos_t xx2, echoPos_t yy2, echoPos_t zz2) { if (tri && echoTypeTriangle == tri->type) { ELL_3V_SET(TRIANGLE(tri)->vert[0], xx0, yy0, zz0); ELL_3V_SET(TRIANGLE(tri)->vert[1], xx1, yy1, zz1); ELL_3V_SET(TRIANGLE(tri)->vert[2], xx2, yy2, zz2); } return; }
static void draw_tetra( void ) { GLuint list; list = glGenLists( 1 ); glNewList( list, GL_COMPILE ); TRIANGLE(2,seno,edgedivisions,0.5/SQRT6); glEndList(); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); glCallList(list); glPushMatrix(); glRotatef(180,0,0,1); glRotatef(-tetraangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); glCallList(list); glPopMatrix(); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+tetraangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); glCallList(list); glPopMatrix(); glRotatef(180,0,1,0); glRotatef(-180+tetraangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); glCallList(list); glDeleteLists(list,1); }
vec Polygon::FastRandomPointInside(LCG &rng) const { TriangleArray tris = Triangulate(); if (tris.empty()) return vec::nan; int i = rng.Int(0, (int)tris.size()-1); return TRIANGLE(tris[i]).RandomPointInside(rng); }
static void bag_flat_triangle( int layer, //{{{ double x1, double y1, double x2, double y2, double x3, double y3 ) { double z = layer_z[layer]; layer_triangles[layer].push_back( TRIANGLE( x1, y1, z, x2, y2, z, x3, y3, z ) ); }
bool Polygon::Intersects(const Capsule &capsule) const { ///@todo Optimize. TriangleArray tris = Triangulate(); for(size_t i = 0; i < tris.size(); ++i) if (TRIANGLE(tris[i]).Intersects(capsule)) return true; return false; }
vec Polygon::ClosestPoint(const vec &point) const { assume(IsPlanar()); TriangleArray tris = Triangulate(); vec closestPt = vec::nan; float closestDist = FLT_MAX; for(size_t i = 0; i < tris.size(); ++i) { vec pt = TRIANGLE(tris[i]).ClosestPoint(point); float d = pt.DistanceSq(point); if (d < closestDist) { closestPt = pt; closestDist = d; } } return closestPt; }
vec Polygon::ClosestPoint(const LineSegment &lineSegment, vec *lineSegmentPt) const { TriangleArray tris = Triangulate(); vec closestPt = vec::nan; vec closestLineSegmentPt = vec::nan; float closestDist = FLT_MAX; for(size_t i = 0; i < tris.size(); ++i) { vec lineSegPt; vec pt = TRIANGLE(tris[i]).ClosestPoint(lineSegment, &lineSegPt); float d = pt.DistanceSq(lineSegPt); if (d < closestDist) { closestPt = pt; closestLineSegmentPt = lineSegPt; closestDist = d; } } if (lineSegmentPt) *lineSegmentPt = closestLineSegmentPt; return closestPt; }
static void draw_ico( void ) { GLuint list; list = glGenLists( 1 ); glNewList( list, GL_COMPILE ); TRIANGLE(1.5,seno,edgedivisions,(3*SQRT3+SQRT15)/12); glEndList(); glPushMatrix(); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); glCallList(list); glPushMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); glCallList(list); glPopMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); glCallList(list); glPopMatrix(); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]); glCallList(list); glPopMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]); glCallList(list); glPopMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]); glCallList(list); glPopMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]); glCallList(list); glPopMatrix(); glRotatef(180,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]); glCallList(list); glPushMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[12]); glCallList(list); glPopMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[13]); glCallList(list); glPopMatrix(); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[14]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[15]); glCallList(list); glPopMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[16]); glCallList(list); glPopMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[17]); glCallList(list); glPushMatrix(); glRotatef(180,0,1,0); glRotatef(-180+icoangle,0.5,-SQRT3/2,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[18]); glCallList(list); glPopMatrix(); glRotatef(180,0,0,1); glRotatef(-icoangle,1,0,0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[19]); glCallList(list); glDeleteLists(list,1); }
int Sphere::Triangulate(vec *outPos, vec *outNormal, float2 *outUV, int numVertices, bool ccwIsFrontFacing) const { assume(outPos); assume(numVertices >= 24 && "At minimum, sphere triangulation will contain at least 8 triangles, which is 24 vertices, but fewer were specified!"); assume(numVertices % 3 == 0 && "Warning:: The size of output should be divisible by 3 (each triangle takes up 3 vertices!)"); #ifndef MATH_ENABLE_INSECURE_OPTIMIZATIONS if (!outPos) return 0; #endif assume(this->r > 0.f); if (numVertices < 24) return 0; #ifdef MATH_ENABLE_STL_SUPPORT TriangleArray temp; #else Array<Triangle> temp; #endif // Start subdividing from a diamond shape. vec xp = POINT_VEC(r,0,0); vec xn = POINT_VEC(-r, 0, 0); vec yp = POINT_VEC(0, r, 0); vec yn = POINT_VEC(0, -r, 0); vec zp = POINT_VEC(0, 0, r); vec zn = POINT_VEC(0, 0, -r); if (ccwIsFrontFacing) { temp.push_back(Triangle(yp,xp,zp)); temp.push_back(Triangle(xp,yp,zn)); temp.push_back(Triangle(yn,zp,xp)); temp.push_back(Triangle(yn,xp,zn)); temp.push_back(Triangle(zp,xn,yp)); temp.push_back(Triangle(yp,xn,zn)); temp.push_back(Triangle(yn,xn,zp)); temp.push_back(Triangle(xn,yn,zn)); } else { temp.push_back(Triangle(yp,zp,xp)); temp.push_back(Triangle(xp,zn,yp)); temp.push_back(Triangle(yn,xp,zp)); temp.push_back(Triangle(yn,zn,xp)); temp.push_back(Triangle(zp,yp,xn)); temp.push_back(Triangle(yp,zn,xn)); temp.push_back(Triangle(yn,zp,xn)); temp.push_back(Triangle(xn,zn,yn)); } int oldEnd = 0; while(((int)temp.size()-oldEnd+3)*3 <= numVertices) { Triangle cur = temp[oldEnd]; vec a = ((cur.a + cur.b) * 0.5f).ScaledToLength(this->r); vec b = ((cur.a + cur.c) * 0.5f).ScaledToLength(this->r); vec c = ((cur.b + cur.c) * 0.5f).ScaledToLength(this->r); temp.push_back(Triangle(cur.a, a, b)); temp.push_back(Triangle(cur.b, c, a)); temp.push_back(Triangle(cur.c, b, c)); temp.push_back(Triangle(a, c, b)); ++oldEnd; } // Check that we really did tessellate as many new triangles as possible. assert(((int)temp.size()-oldEnd)*3 <= numVertices && ((int)temp.size()-oldEnd)*3 + 9 > numVertices); for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outPos[3*j] = this->pos + TRIANGLE(temp[i]).a; outPos[3*j+1] = this->pos + TRIANGLE(temp[i]).b; outPos[3*j+2] = this->pos + TRIANGLE(temp[i]).c; } if (outNormal) for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outNormal[3*j] = TRIANGLE(temp[i]).a.Normalized(); outNormal[3*j+1] = TRIANGLE(temp[i]).b.Normalized(); outNormal[3*j+2] = TRIANGLE(temp[i]).c.Normalized(); } if (outUV) for(size_t i = oldEnd, j = 0; i < temp.size(); ++i, ++j) { outUV[3*j] = float2(atan2(TRIANGLE(temp[i]).a.y, TRIANGLE(temp[i]).a.x) / (2.f * 3.141592654f) + 0.5f, (TRIANGLE(temp[i]).a.z + r) / (2.f * r)); outUV[3*j+1] = float2(atan2(TRIANGLE(temp[i]).b.y, TRIANGLE(temp[i]).b.x) / (2.f * 3.141592654f) + 0.5f, (TRIANGLE(temp[i]).b.z + r) / (2.f * r)); outUV[3*j+2] = float2(atan2(TRIANGLE(temp[i]).c.y, TRIANGLE(temp[i]).c.x) / (2.f * 3.141592654f) + 0.5f, (TRIANGLE(temp[i]).c.z + r) / (2.f * r)); } return ((int)temp.size() - oldEnd) * 3; }
static void draw_icosa(ModeInfo * mi) { morph3dstruct *mp = &morph3d[MI_SCREEN(mi)]; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glPushMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[12]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[13]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[14]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[15]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[16]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[17]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[18]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); glPopMatrix(); glRotatef(180, 0, 0, 1); glRotatef(-icoangle, 1, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[19]); TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes); }
TriangleList getCommonTriangles(QPointF *points, quint32 size, quint32 layers, Vertex v1, Vertex v2, QPointF *centerPtr) { TriangleList result; if (v1.layer > v2.layer) qSwap(v1, v2); if (!v2.layer) return result; if (v1.layer == 0 && v2.layer == 1) { result.append(TRIANGLE(0, v2.sector, 0)); result.append(TRIANGLE(0, (v2.sector + size - 1) % size, 0)); } else if (v1.sector == v2.sector) { if (v1.layer == v2.layer) { if (v2.index == v1.index + 1) { if (v1.layer < layers) result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2 + 1)); result.append(TRIANGLE(v1.layer - 1, v1.sector, v1.index * 2)); } else if (v2.index == v1.index - 1) { if (v1.layer < layers) result.append(TRIANGLE(v1.layer, v1.sector, v2.index * 2 + 1)); result.append(TRIANGLE(v1.layer - 1, v1.sector, v2.index * 2)); } } else if (v2.layer == v1.layer + 1) { if (v2.index == v1.index) { if (v1.index) result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2 - 1)); else result.append(TRIANGLE(v1.layer, (v1.sector + size - 1) % size, v1.layer * 2)); result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2)); } else if (v2.index == v1.index + 1) { result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2)); result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2 + 1)); } } } else if ((v2.sector == (v1.sector + 1) % size) && v1.index == v1.layer - 1 && v2.index == 0) { if (v1.layer == v2.layer) { result.append(TRIANGLE(v1.layer - 1, v1.sector, v1.index * 2)); if (v1.layer < layers) result.append(TRIANGLE(v1.layer, v1.sector, v1.index * 2 + 1)); } else if (v1.layer == v2.layer + 1) { result.append(TRIANGLE(v2.layer, v1.sector, v1.index * 2 - 1)); result.append(TRIANGLE(v2.layer, v1.sector, v1.index * 2)); } } else if ((v1.sector == (v2.sector + 1) % size) && v2.index == v2.layer - 1 && v1.index == 0) { if (v1.layer == v2.layer) { result.append(TRIANGLE(v1.layer - 1, v2.sector, v2.index * 2)); if (v1.layer < layers) result.append(TRIANGLE(v1.layer, v2.sector, v2.index * 2 + 1)); } else if (v1.layer == v2.layer - 1) { result.append(TRIANGLE(v1.layer, v2.sector, v2.index * 2 - 1)); result.append(TRIANGLE(v1.layer, v2.sector, v2.index * 2)); } } return result; }
/** * @short Calculates the chunk for just an oscillator (actually 4), its is more like a voice. */ void Polybase::Oscillator::oscillatorChunk(float *data, unsigned int nsamples){ if (note==0){ // freq 0 == stopped memset(data,0,sizeof(float)*nsamples); return; } #define NWAVES 5 #define NWAVESBLOCK (128/NWAVES) #define SIN(x) (sin(x*2.0*M_PI)) #define SAW(x) (fmod(1.0f+(x*4.0f),2.0)-1.0) #define TRIANGLE(x) ((x>0.25 && x<0.75) ? - SAW(x) : SAW(x)) #define SQUARE(x) (x < 0.5 ? 1.0 : -1.0); #define NOISE(x) (((float(rand())/RAND_MAX)*2.0) - 1.0) unsigned int i; float *temp=data; float os,ds,v; float sr=poly->samplerate(); float pstep[4]={freq[0]/sr, freq[1]/sr, freq[2]/sr, freq[3]/sr}; for (i=0;i<nsamples;i++){ float r=0; for (int o=0;o<4;o++){ phase[o]+=pstep[o]; float form=(poly->oscillatorForm[o]%NWAVESBLOCK)/float(NWAVESBLOCK); int nform=poly->oscillatorForm[o]/NWAVESBLOCK; float mphase=fmod(phase[o],1.0); //DEBUG("nform %d",nform); switch(nform){ case 0: os=SIN(mphase); ds=SAW(mphase); break; case 1: os=SAW(mphase); ds=TRIANGLE(mphase); break; case 2: os=TRIANGLE(mphase); ds=SQUARE(mphase); break; case 3: os=SQUARE(mphase); ds=SIN(mphase); break; default: //DEBUG("NOISE"); os=NOISE(mphase); ds=NOISE(mphase); } v=(os*(1.0-form)) + (ds*form); r+=v*poly->oscillatorLevel[o]/64.0; } *temp=r; temp++; } phase[0]=fmod(phase[0],1.0); phase[1]=fmod(phase[1],1.0); phase[2]=fmod(phase[2],1.0); phase[3]=fmod(phase[3],1.0); }