void glTerrain::renderTerrain() { int X = 0, Y = 0; int x, y, z; if(!pHeightMap) return; bRender = true; if(bRender) glBegin( GL_QUADS ); else glBegin( GL_LINES ); for ( X = 0; X < MAP_SIZE; X += STEP_SIZE ) for ( Y = 0; Y < MAP_SIZE; Y += STEP_SIZE ) { x = X; y = Height(X, Y ); z = Y; setVertexColor(x, z); glVertex3i(x, y, z); x = X; y = Height(X, Y + STEP_SIZE ); z = Y + STEP_SIZE ; setVertexColor(x, z); glVertex3i(x, y, z); x = X + STEP_SIZE; y = Height(X + STEP_SIZE, Y + STEP_SIZE ); z = Y + STEP_SIZE ; setVertexColor(x, z); glVertex3i(x, y, z); x = X + STEP_SIZE; y = Height(X + STEP_SIZE, Y ); z = Y; setVertexColor(x, z); glVertex3i(x, y, z); } glEnd(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); }
bool Map::Init(){ if(map==NULL || map->data==NULL){ return false; } list=glGenLists(1); glNewList(list,GL_COMPILE_AND_EXECUTE); glBegin(GL_TRIANGLE_FAN); glColor3f(0,0,0.3); glVertex3f(0,-1,0); glVertex3f(map->sizeX,-1,0); glVertex3f(map->sizeX,-1,map->sizeY); glVertex3f(0,-1,map->sizeY); glEnd(); unsigned char y=0; for(unsigned int x=0;x<map->sizeX-precision;x+=precision) for(unsigned int z=0;z<map->sizeY-precision;z+=precision){ glBegin(GL_TRIANGLE_FAN); y=get_point(map,x,z); setVertexColor(y); glVertex3f(x,y,z); y=get_point(map,x+precision,z); setVertexColor(y); glVertex3f(x+precision,y,z); y=get_point(map,x+precision,z+precision); setVertexColor(y); glVertex3f(x+precision,y,z+precision); y=get_point(map,x,z+precision); setVertexColor(y); glVertex3f(x,y,z+precision); glEnd(); } glEndList(); return true; }
// Render // desc: handles drawing of scene void Terrain::render() { glEnable(GL_TEXTURE_2D); Color3f *color; //server->parseData(); handleMessages(); //########################################### //## For taking cross-section screenshots ### //########################################### //glMatrixMode(GL_MODELVIEW); //glPushMatrix(); //glTranslatef(0.0f, minY*(MAP_SCALE/20) + 0.045f, 0.0f); //glClipPlane(GL_CLIP_PLANE2, topPlaneEq); //glPopMatrix(); //glPushMatrix(); //glTranslatef(0.0f, minY*(MAP_SCALE/20) +0.045f, 0.0f); //glClipPlane(GL_CLIP_PLANE3, botPlaneEq); //glPopMatrix(); //glEnable(GL_CLIP_PLANE2); //glEnable(GL_CLIP_PLANE3); //################################# //***Drawing original Terrain***// //################################# // set the current texture to the land texture //glBindTexture(GL_TEXTURE_2D, land); //glPushMatrix(); ////glTranslatef(((MAP_X*MAP_SCALE)/2.0f), 0.0, -((MAP_Z*MAP_SCALE)/2.0f)); //translate back from origin ////glMultMatrixf(rotMatrix); //rotate via Vicon //glTranslatef(-((MAP_X*MAP_SCALE)/2.0f), 0.0, ((MAP_Z*MAP_SCALE)/2.0f)); //translate to origin //for (int z = 0; z < MAP_Z-1; z++) //{ // glBegin(GL_TRIANGLE_STRIP); // for (int x = 0; x < MAP_X-1; x++) // { // pathColor->setRGB(terrain[x][z][1]/255.0f); // glColor3f(pathColor->getRed(), pathColor->getGreen(), pathColor->getBlue()); // //glColor3f(d, d, d); // glTexCoord2f(0.0f, 0.0f); // glVertex3f(terrain[x][z][0], terrain[x][z][1] * (MAP_SCALE/20.0f), terrain[x][z][2]); // pathColor->setRGB(terrain[x+1][z][1]/255.0f); // // draw vertex 1 // glTexCoord2f(1.0f, 0.0f); // //glColor3f(terrain[x+1][z][1]/255.0f, terrain[x+1][z][1]/255.0f, terrain[x+1][z][1]/255.0f); // glColor3f(pathColor->getRed(), pathColor->getGreen(), pathColor->getBlue()); // glVertex3f(terrain[x+1][z][0], terrain[x+1][z][1] * (MAP_SCALE/20.0f), terrain[x+1][z][2]); // pathColor->setRGB(terrain[x][z+1][1]/255.0f); // // draw vertex 2 // glTexCoord2f(0.0f, 1.0f); // glColor3f(pathColor->getRed(), pathColor->getGreen(), pathColor->getBlue()); // glVertex3f(terrain[x][z+1][0], terrain[x][z+1][1] * (MAP_SCALE/20.0f), terrain[x][z+1][2]); // pathColor->setRGB(terrain[x+1][z+1][1]/255.0f); // // draw vertex 3 // glColor3f(pathColor->getRed(), pathColor->getGreen(), pathColor->getBlue()); // glTexCoord2f(1.0f, 1.0f); // glVertex3f(terrain[x+1][z+1][0], terrain[x+1][z+1][1] * (MAP_SCALE/20.0f), terrain[x+1][z+1][2]); // } // glEnd(); //} //glPopMatrix(); glMatrixMode(GL_MODELVIEW); //############################ //##Draw Holo-Mobile Terrain## //############################ glBindTexture(GL_TEXTURE_2D, land); glPushMatrix(); //Save pre-terrain view matrix glTranslatef(loc->x, loc->y, loc->z); //Positions Terrain glMultMatrixf(rotMatrix); //Rotates Terrain glTranslatef(-((MAP_X*MAP_SCALE)/2.0f), 0.0, ((MAP_Z*MAP_SCALE)/2.0f)); //Moves terrain to origin glPushMatrix(); //Save pre-clip view matrix //Determine which clipping plane is the upper and which is lower //based on their height relative to one another. // ------first => upper OR -------second => upper // ------second => lower -------first => lower if(firstClipY > secondClipY){ botClipY = secondClipY; topClipY = firstClipY; } else{ botClipY = firstClipY; topClipY = secondClipY; } //Position & initialize clipping planes glTranslatef(0.0f, botClipY, 0.0f); glClipPlane(GL_CLIP_PLANE0, botPlaneEq); glTranslatef(0.0f, topClipY - botClipY, 0.0f); glClipPlane(GL_CLIP_PLANE1, topPlaneEq); //Enable clipping planes if(enableFirstClip){ if(firstClipY > secondClipY){ glEnable(GL_CLIP_PLANE0); } else{ glEnable(GL_CLIP_PLANE1); } } if(enableSecondClip){ if(secondClipY > firstClipY){ glEnable(GL_CLIP_PLANE0); } else{ glEnable(GL_CLIP_PLANE1); } } glPopMatrix(); //Restore pre-clip (post-terrain) view matrix // we are going to loop through all of our terrain's data points, // but we only want to draw one triangle strip for each set along the x-axis. for (int z = 0; z < MAP_Z-1; z++) { glBegin(GL_TRIANGLE_STRIP); for (int x = 0; x < MAP_X-1; x++) { // for each vertex, we calculate the grayscale shade color, // we set the texture coordinate, and we draw the vertex. /* the vertices are drawn in this order: 0 ---> 1 / / |/ 2 ---> 3 */ // draw vertex 0 setVertexColor(x, z); glTexCoord2f(0.0f, 0.0f); glVertex3f(terrain[x][z][0], terrain[x][z][1] * (MAP_SCALE/20.0f), terrain[x][z][2]); // draw vertex 1 setVertexColor(x+1, z); glTexCoord2f(1.0f, 0.0f); glVertex3f(terrain[x+1][z][0], terrain[x+1][z][1] * (MAP_SCALE/20.0f), terrain[x+1][z][2]); // draw vertex 2 setVertexColor(x, z+1); glTexCoord2f(0.0f, 1.0f); glVertex3f(terrain[x][z+1][0], terrain[x][z+1][1] * (MAP_SCALE/20.0f), terrain[x][z+1][2]); // draw vertex 3 setVertexColor(x+1, z+1); glTexCoord2f(1.0f, 1.0f); glVertex3f(terrain[x+1][z+1][0], terrain[x+1][z+1][1] * (MAP_SCALE/20.0f), terrain[x+1][z+1][2]); } glEnd(); } glColor3f(1.0f, 1.0f, 1.0f); //Try drawing text to the screen //glutStrokeString(GLUT_STROKE_ROMAN, (unsigned char*)"some text"); //############################ //## Draw Markers ## //############################ if(start){ startCube->setRotMat(rotMatrix); startCube->setPosition(MHTypes::Point3D(start->x, (terrain[(int)(start->x *(1/MAP_SCALE))][(int)(start->z *(1/MAP_SCALE))][1]* (MAP_SCALE/20.0f)) + 0.02f , start->z)); startCube->render(); } if(end){ endCube->setRotMat(rotMatrix); endCube->setPosition(MHTypes::Point3D(end->x, (terrain[(int)(end->x *(1/MAP_SCALE))][(int)(end->z *(1/MAP_SCALE))][1]* (MAP_SCALE/20.0f)) + 0.02f , end->z)); endCube->render(); } roiCube->setRotMat(rotMatrix); roiCube->setPosition(MHTypes::Point3D(roi.x, (terrain[(int)(roi.x *(1/MAP_SCALE))][(int)(roi.z *(1/MAP_SCALE))][1]* (MAP_SCALE/20.0f)) + 0.02f , roi.z)); roiCube->render(); poiCube->setRotMat(rotMatrix); poiCube->setPosition(MHTypes::Point3D(poi.x, (terrain[(int)(poi.x *(1/MAP_SCALE))][(int)(poi.z *(1/MAP_SCALE))][1]* (MAP_SCALE/20.0f)) + 0.02f , poi.z)); poiCube->render(); //render lightingCube once, so lighting is applied, then hide. (is what I'm assuming is happening here) if(isFirst){ lightingCube->render(); isFirst = false; } glPopMatrix(); // enable blending glEnable(GL_BLEND); // enable read-only depth buffer glDepthMask(GL_FALSE); // set the blend function to what we use for transparency glBlendFunc(GL_SRC_ALPHA, GL_ONE); // set back to normal depth buffer mode (writable) glDepthMask(GL_TRUE); // disable blending glDisable(GL_BLEND); //############################################ //############ Renders Selection Ray ######### //############################################ glPushMatrix(); glTranslatef(loc->x, loc->y, loc->z); glMultMatrixf(rotMatrix); glTranslatef(-((MAP_X*MAP_SCALE)/2.0f), 0.0, ((MAP_Z*MAP_SCALE)/2.0f)); glLineWidth(10.0f); //Determine selection ray color //red => not intersecting, not pinching //blue => intersecting, not pinching //green => pinching glColor3f(1.0f, 0.0f, 0.0f); if(intersecting){ glColor3f(0.0f, 0.0f, 1.0f); } if(pinch || pinchHold){ glColor3f(0.0f, 1.0f, 0.0f); } //Draw SelectorRay glBegin(GL_LINES); //Disable SelectorRay (comment following 2 lines out to disable) glVertex3f(selectorRay.x, -1000.0f, selectorRay.z); glVertex3f(selectorRay.x, 1000.0f, selectorRay.z); glEnd(); //####################################### //########### Renders Clip Plane ######## //####################################### //Set up transparency for clip plane visualizations glColor4f(0.0f, 0.0f, 1.0f, 0.5f); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //If enabled, render the visualization of the first clip plane if(enableFirstClipVis){ glPushMatrix(); glTranslatef(0.0f, clipPlaneFirstVisOffset, 0.0f); glBegin(GL_QUADS); glVertex3f(0.0f, firstClipY, -MAP_Z*MAP_SCALE); glVertex3f(0.0f, firstClipY, 0.0f); glVertex3f(MAP_X*MAP_SCALE, firstClipY, 0.0f); glVertex3f(MAP_X*MAP_SCALE, firstClipY, -MAP_Z*MAP_SCALE); glEnd(); glPopMatrix(); } //If enabled, render the visualization of the second clip plane if(enableSecondClipVis){ glPushMatrix(); glTranslatef(0.0f, clipPlaneSecondVisOffset, 0.0f); glBegin(GL_QUADS); glVertex3f(0.0f, secondClipY, -MAP_Z*MAP_SCALE); glVertex3f(0.0f, secondClipY, 0.0f); glVertex3f(MAP_X*MAP_SCALE, secondClipY, 0.0f); glVertex3f(MAP_X*MAP_SCALE, secondClipY, -MAP_Z*MAP_SCALE); glEnd(); glPopMatrix(); } //If enabled, render the height selector if(enableHeightVis){ glPushMatrix(); glTranslatef(0.0f, 0.0f, 0.0f); glBegin(GL_QUADS); glVertex3f(0.0f, selectorRay.y, -MAP_Z*MAP_SCALE); glVertex3f(0.0f, selectorRay.y, 0.0f); glVertex3f(MAP_X*MAP_SCALE, selectorRay.y, 0.0f); glVertex3f(MAP_X*MAP_SCALE, selectorRay.y, -MAP_Z*MAP_SCALE); glEnd(); glPopMatrix(); } glPopMatrix(); glFlush(); }
PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) { /* Vertex */ // create groupbox QGroupBox *groupV = new QGroupBox( tr("Vertex") ); // create buttons QPushButton *btnVertex = new QPushButton( tr("Set Color") ); // create color label m_labelVertex = new QLabel; m_labelVertex->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create size label QLabel *labelSizeV = new QLabel( tr("Set Size") ); // create lineedit m_editSizeV = new QLineEdit; // connect to actions connect( btnVertex, SIGNAL(clicked()), this, SLOT(setVertexColor()) ); connect( m_editSizeV, SIGNAL(textChanged(const QString&)), this, SLOT(setVertexSize(const QString&)) ); // lay out the buttons QGridLayout *layoutV = new QGridLayout; layoutV->addWidget( btnVertex, 0, 0 ); layoutV->addWidget( m_labelVertex, 0, 1 ); layoutV->addWidget( labelSizeV, 1, 0 ); layoutV->addWidget( m_editSizeV, 1, 1 ); groupV->setLayout( layoutV ); /* Delaunau Edge */ // create groupbox QGroupBox *groupDE = new QGroupBox( tr("Delaunay Edge") ); // create button QPushButton *btnDEdge = new QPushButton( tr("Set Color") ); // create color label m_labelDEdge = new QLabel; m_labelDEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create size label QLabel *labelSizeDE = new QLabel( tr("Set Size") ); // create lineedit m_editSizeDE = new QLineEdit; // connect to actions connect( btnDEdge, SIGNAL(clicked()), this, SLOT(setDEdgeColor()) ); connect( m_editSizeDE, SIGNAL(textChanged(const QString&)), this, SLOT(setDEdgeSize(const QString&)) ); // lay out the buttons QGridLayout *layoutDE = new QGridLayout; layoutDE->addWidget( btnDEdge, 0, 0 ); layoutDE->addWidget( m_labelDEdge, 0, 1 ); layoutDE->addWidget( labelSizeDE, 1, 0 ); layoutDE->addWidget( m_editSizeDE, 1, 1 ); groupDE->setLayout( layoutDE ); /* Voronoi Edge */ // create groupbox QGroupBox *groupVE = new QGroupBox( tr("Voronoi Edge") ); // create button QPushButton *btnVEdge = new QPushButton( tr("Set Color") ); // create color label m_labelVEdge = new QLabel; m_labelVEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create size label QLabel *labelSizeVE = new QLabel( tr("Set Size") ); // create lineedit m_editSizeVE = new QLineEdit; // connect to actions connect( btnVEdge, SIGNAL(clicked()), this, SLOT(setVEdgeColor()) ); connect( m_editSizeVE, SIGNAL(textChanged(const QString&)), this, SLOT(setVEdgeSize(const QString&)) ); // lay out the buttons QGridLayout *layoutVE = new QGridLayout; layoutVE->addWidget( btnVEdge, 0, 0 ); layoutVE->addWidget( m_labelVEdge, 0, 1 ); layoutVE->addWidget( labelSizeVE, 1, 0 ); layoutVE->addWidget( m_editSizeVE, 1, 1 ); groupVE->setLayout( layoutVE ); /* Facet */ // create groupbox QGroupBox *groupF = new QGroupBox( tr("Facet") ); // create button QPushButton *btnFacet = new QPushButton( tr("Set Color") ); // create color label m_labelFacet = new QLabel; m_labelFacet->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create label and spinbox QLabel *labelFacetA = new QLabel( tr("Transparency") ); m_spinAlphaF = new QSpinBox; m_spinAlphaF->setRange(0, 255); // connect to actions connect( btnFacet, SIGNAL(clicked()), this, SLOT(setFacetColor()) ); connect( m_spinAlphaF, SIGNAL(valueChanged(int)), this, SLOT(setFacetAlpha()) ); // lay out the buttons QGridLayout *layoutF = new QGridLayout; layoutF->addWidget( btnFacet, 0, 0 ); layoutF->addWidget( m_labelFacet, 0, 1 ); layoutF->addWidget( labelFacetA, 1, 0 ); layoutF->addWidget( m_spinAlphaF, 1, 1 ); groupF->setLayout( layoutF ); /* Trackball */ // create groupbox QGroupBox *groupB = new QGroupBox( tr("Trackball") ); // create button QPushButton *btnBall = new QPushButton( tr("Set Color") ); // create color label m_labelBall = new QLabel; m_labelBall->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create label and spinbox QLabel *labelBallA = new QLabel( tr("Transparency") ); m_spinAlphaB = new QSpinBox; m_spinAlphaB->setRange(0, 255); // create label and spinbox QLabel *labelStep = new QLabel( tr("Step-long of Resizing") ); m_spinStep = new QSpinBox; m_spinStep->setRange(1, 300); // connect to actions connect( btnBall, SIGNAL(clicked()), this, SLOT(setTrackballColor()) ); connect( m_spinAlphaB, SIGNAL(valueChanged(int)), this, SLOT(setTrackballAlpha()) ); connect( m_spinStep, SIGNAL(valueChanged(int)), this, SLOT(setStepLong()) ); // lay out the buttons QGridLayout *layoutB = new QGridLayout; layoutB->addWidget( btnBall, 0, 0 ); layoutB->addWidget( m_labelBall, 0, 1 ); layoutB->addWidget( labelBallA, 1, 0 ); layoutB->addWidget( m_spinAlphaB, 1, 1 ); layoutB->addWidget( labelStep, 2, 0 ); layoutB->addWidget( m_spinStep, 2, 1 ); groupB->setLayout( layoutB ); /* Empty Sphere */ // create groupbox QGroupBox *groupS = new QGroupBox( tr("Empty Sphere") ); // create color label m_labelSphere = new QLabel; m_labelSphere->setFrameStyle(QFrame::Sunken | QFrame::Panel); // create button QPushButton *btnSphere = new QPushButton( tr("Set Color") ); // create label and spinbox QLabel *labelSphereA = new QLabel( tr("Transparency") ); m_spinAlphaS = new QSpinBox; m_spinAlphaS->setRange(0, 255); // connect to actions connect( btnSphere, SIGNAL(clicked()), this, SLOT(setEmptySphereColor()) ); connect( m_spinAlphaS, SIGNAL(valueChanged(int)), this, SLOT(setEmptySphereAlpha()) ); // lay out the buttons QGridLayout *layoutS = new QGridLayout; layoutS->addWidget( btnSphere, 0, 0 ); layoutS->addWidget( m_labelSphere, 0, 1 ); layoutS->addWidget( labelSphereA, 1, 0 ); layoutS->addWidget( m_spinAlphaS, 1, 1 ); groupS->setLayout( layoutS ); /* OK buttons */ // create groupbox QGroupBox *groupBtn = new QGroupBox(); // buttons QPushButton *ok = new QPushButton( tr("OK") ); QPushButton *apply = new QPushButton( tr("Apply") ); QPushButton *cancel = new QPushButton( tr("Cancel") ); cancel->setFocus(); // connect to actions connect( ok, SIGNAL(clicked()), this, SLOT(okClicked()) ); connect( apply, SIGNAL(clicked()), this, SLOT(applyClicked()) ); connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); // lay out the buttons QGridLayout *layoutBtn = new QGridLayout; layoutBtn->addWidget( ok, 0, 0 ); layoutBtn->addWidget( cancel, 0, 1 ); layoutBtn->addWidget( apply, 0, 2 ); groupBtn->setLayout( layoutBtn ); /* dialog layout */ // lay out the buttons QGridLayout *main = new QGridLayout; main->addWidget( groupV, 0, 1 ); main->addWidget( groupDE, 0, 2 ); main->addWidget( groupVE, 0, 3 ); main->addWidget( groupF, 1, 1 ); main->addWidget( groupB, 1, 2 ); main->addWidget( groupS, 1, 3 ); main->addWidget( groupBtn, 2, 2, 2, 3 ); setLayout( main ); // set dialog title setWindowTitle( tr("Preferences") ); }
//------------------------------------------------------------------------------ void NiceGraph::makeStrangersBanquetGraph(int numVertices, int groups, float density, float mu) { makeEmptyGraph(numVertices); // first initialize all the vertices makeUndirected(); // the SB is only undirected for now... if (groups > numVertices) // bounds checking on number of groups groups = numVertices; for (int c = 0; c < numVertices; c++) // now subdivide into groups { for (int g = 0; g < groups; g++) { if (c % groups == g) setVertexColor(c,g); } } // make declining edge scheme to speed things up int total_edges = numVertices * (numVertices - 1) / 2; vector<Edge> proposals (total_edges); int edgeIndex = 0; for (int froms = 0; froms < numVertices; froms++) { for (int tos = 0; tos < numVertices; tos++) { if ((froms != tos) && (froms < tos)) { proposals[edgeIndex].from = vertexList[froms]; proposals[edgeIndex].to = vertexList[tos]; edgeIndex++; } } } // propose connections and build graph int num_edges = (int) (density * (float) total_edges); int edge_counter = 0; while (edge_counter < num_edges) { // use declining proposal list to speed things up... int randIndex = rand() % proposals.size(); // choose two vertices to make the proposal int vertex1 = proposals[randIndex].from->vID; int vertex2 = proposals[randIndex].to->vID; if ((vertex1 != vertex2) && (!testConnected(vertex1,vertex2))) // if isn't itself, and aren't already connected { // now check to see if they are accepted if (vertexList[vertex1]->vColor == vertexList[vertex2]->vColor) { // if same color approve match addEdge(vertex1, vertex2); // add edge edge_counter++; if (!proposals.empty()) proposals.erase(proposals.begin()+randIndex); // remove from list } else // if different colors check against mu { float chance1 = rand() / (RAND_MAX+1.0); float chance2 = rand() / (RAND_MAX+1.0); if ((chance1 < mu) || (chance2 < mu)) continue; // if either one rejects the connection do nothing else { // approve the connection addEdge(vertex1, vertex2); // add edge edge_counter++; if (!proposals.empty()) proposals.erase(proposals.begin()+randIndex); // remove from list } } } } }
static void getCollisionObjectVertices(SingleFrameScreen2D * self, struct vertex_p2f_c4f * outVertices, GLuint * outIndexes, unsigned int * ioVertexCount, unsigned int * ioIndexCount) { size_t objectIndex; CollisionObject * object; struct vertex_p2f_c4f vertex; bool colliding; CollisionRecord collision; for (objectIndex = 0; objectIndex < self->resolver->objectCount; objectIndex++) { object = self->resolver->objects[objectIndex]; colliding = CollisionResolver_querySingle(self->resolver, object, &collision); switch (object->shapeType) { case COLLISION_SHAPE_RECT_2D: { CollisionRect2D * rect = (CollisionRect2D *) object; unsigned int vertexIndex; if (outVertices != NULL) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_RECT_LAST_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_RECT_LAST_POSITION); } vertex.position[0] = xtof(rect->lastPosition.x); vertex.position[1] = xtof(rect->lastPosition.y); outVertices[*ioVertexCount + 0] = vertex; vertex.position[0] = xtof(rect->lastPosition.x + rect->lastSize.x); outVertices[*ioVertexCount + 1] = vertex; vertex.position[1] = xtof(rect->lastPosition.y + rect->lastSize.y); outVertices[*ioVertexCount + 2] = vertex; vertex.position[0] = xtof(rect->lastPosition.x); outVertices[*ioVertexCount + 3] = vertex; if (colliding) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_RECT_POSITION_COLLIDING_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_RECT_POSITION_COLLIDING); } } else { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_RECT_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_RECT_POSITION); } } vertex.position[0] = xtof(rect->position.x); vertex.position[1] = xtof(rect->position.y); outVertices[*ioVertexCount + 4] = vertex; vertex.position[0] = xtof(rect->position.x + rect->size.x); outVertices[*ioVertexCount + 5] = vertex; vertex.position[1] = xtof(rect->position.y + rect->size.y); outVertices[*ioVertexCount + 6] = vertex; vertex.position[0] = xtof(rect->position.x); outVertices[*ioVertexCount + 7] = vertex; } if (outIndexes != NULL) { bool solid[4] = {rect->solidBottom, rect->solidRight, rect->solidTop, rect->solidLeft}; for (vertexIndex = 0; vertexIndex < 4; vertexIndex++) { if (solid[vertexIndex]) { outIndexes[(*ioIndexCount)++] = *ioVertexCount + vertexIndex; outIndexes[(*ioIndexCount)++] = *ioVertexCount + (vertexIndex + 1) % 4; } } for (vertexIndex = 0; vertexIndex < 4; vertexIndex++) { outIndexes[(*ioIndexCount)++] = *ioVertexCount + 0 + vertexIndex; outIndexes[(*ioIndexCount)++] = *ioVertexCount + 4 + vertexIndex; } for (vertexIndex = 0; vertexIndex < 4; vertexIndex++) { if (solid[vertexIndex]) { outIndexes[(*ioIndexCount)++] = *ioVertexCount + 4 + vertexIndex; outIndexes[(*ioIndexCount)++] = *ioVertexCount + 4 + (vertexIndex + 1) % 4; } } } else { *ioIndexCount += 8 + 4 * rect->solidLeft + 4 * rect->solidRight + 4 * rect->solidBottom + 4 * rect->solidTop; } *ioVertexCount += 8; if (colliding) { Vector2x collidingPosition = Vector2x_interpolate(rect->lastPosition, rect->position, collision.time); Vector2x collidingSize = Vector2x_interpolate(rect->lastSize, rect->size, collision.time); if (outVertices != NULL) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_RECT_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_RECT_POSITION); } vertex.position[0] = xtof(collidingPosition.x); vertex.position[1] = xtof(collidingPosition.y); outVertices[*ioVertexCount + 0] = vertex; vertex.position[0] = xtof(collidingPosition.x + collidingSize.x); outVertices[*ioVertexCount + 1] = vertex; vertex.position[1] = xtof(collidingPosition.y + collidingSize.y); outVertices[*ioVertexCount + 2] = vertex; vertex.position[0] = xtof(collidingPosition.x); outVertices[*ioVertexCount + 3] = vertex; } if (outIndexes != NULL) { bool solid[4] = {rect->solidBottom, rect->solidRight, rect->solidTop, rect->solidLeft}; for (vertexIndex = 0; vertexIndex < 4; vertexIndex++) { if (solid[vertexIndex]) { outIndexes[(*ioIndexCount)++] = *ioVertexCount + vertexIndex; outIndexes[(*ioIndexCount)++] = *ioVertexCount + (vertexIndex + 1) % 4; } } } else { *ioIndexCount += 2 * rect->solidLeft + 2 * rect->solidRight + 2 * rect->solidBottom + 2 * rect->solidTop; } *ioVertexCount += 4; getArrowVertices(VECTOR2x(collidingPosition.x + collidingSize.x / 2, collidingPosition.y + collidingSize.y / 2), collision.normal, outVertices, outIndexes, ioVertexCount, ioIndexCount); } break; } case COLLISION_SHAPE_CIRCLE: { CollisionCircle * circle = (CollisionCircle *) object; unsigned int tesselationIndex; if (outVertices != NULL) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_CIRCLE_LAST_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_CIRCLE_LAST_POSITION); } for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { vertex.position[0] = xtof(circle->lastPosition.x) + xtof(circle->radius) * cos(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); vertex.position[1] = xtof(circle->lastPosition.y) + xtof(circle->radius) * sin(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); outVertices[*ioVertexCount + tesselationIndex] = vertex; } if (colliding) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_CIRCLE_POSITION_COLLIDING_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_CIRCLE_POSITION_COLLIDING); } } else { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_CIRCLE_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_CIRCLE_POSITION); } } for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { vertex.position[0] = xtof(circle->position.x) + xtof(circle->radius) * cos(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); vertex.position[1] = xtof(circle->position.y) + xtof(circle->radius) * sin(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); outVertices[*ioVertexCount + CIRCLE_TESSELATIONS + tesselationIndex] = vertex; } } if (outIndexes != NULL) { float angle; int bestEdgeIndex; for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { outIndexes[*ioIndexCount + tesselationIndex * 2 + 0] = *ioVertexCount + tesselationIndex; outIndexes[*ioIndexCount + tesselationIndex * 2 + 1] = *ioVertexCount + (tesselationIndex + 1) % CIRCLE_TESSELATIONS; } angle = atan2(circle->position.y - circle->lastPosition.y, circle->position.x - circle->lastPosition.x); bestEdgeIndex = round((angle + M_PI / 2) * CIRCLE_TESSELATIONS / (M_PI * 2)); bestEdgeIndex = (bestEdgeIndex % CIRCLE_TESSELATIONS + CIRCLE_TESSELATIONS) % CIRCLE_TESSELATIONS; outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 0] = *ioVertexCount + bestEdgeIndex; outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 1] = *ioVertexCount + bestEdgeIndex + CIRCLE_TESSELATIONS; bestEdgeIndex += CIRCLE_TESSELATIONS / 2; bestEdgeIndex %= CIRCLE_TESSELATIONS; outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 2] = *ioVertexCount + bestEdgeIndex; outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 3] = *ioVertexCount + bestEdgeIndex + CIRCLE_TESSELATIONS; for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 4 + tesselationIndex * 2] = *ioVertexCount + CIRCLE_TESSELATIONS + tesselationIndex; outIndexes[*ioIndexCount + CIRCLE_TESSELATIONS * 2 + 5 + tesselationIndex * 2] = *ioVertexCount + CIRCLE_TESSELATIONS + (tesselationIndex + 1) % CIRCLE_TESSELATIONS; } } *ioVertexCount += CIRCLE_TESSELATIONS * 2; *ioIndexCount += CIRCLE_TESSELATIONS * 4 + 4; if (colliding) { Vector2x collidingPosition = Vector2x_interpolate(circle->lastPosition, circle->position, collision.time); if (outVertices != NULL) { if (objectIndex == self->selectedObjectIndex) { setVertexColor(&vertex, COLOR_CIRCLE_POSITION_HIGHLIGHT); } else { setVertexColor(&vertex, COLOR_CIRCLE_POSITION); } for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { vertex.position[0] = xtof(collidingPosition.x) + xtof(circle->radius) * cos(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); vertex.position[1] = xtof(collidingPosition.y) + xtof(circle->radius) * sin(tesselationIndex * M_PI * 2 / CIRCLE_TESSELATIONS); outVertices[*ioVertexCount + tesselationIndex] = vertex; } } if (outIndexes != NULL) { for (tesselationIndex = 0; tesselationIndex < CIRCLE_TESSELATIONS; tesselationIndex++) { outIndexes[*ioIndexCount + tesselationIndex * 2 + 0] = *ioVertexCount + tesselationIndex; outIndexes[*ioIndexCount + tesselationIndex * 2 + 1] = *ioVertexCount + (tesselationIndex + 1) % CIRCLE_TESSELATIONS; } } *ioVertexCount += CIRCLE_TESSELATIONS; *ioIndexCount += CIRCLE_TESSELATIONS * 2; getArrowVertices(collidingPosition, collision.normal, outVertices, outIndexes, ioVertexCount, ioIndexCount); } break; } } } }