int calculateGenericTriangleNormals(float * coords , unsigned int coordLength) { //fprintf(stderr,"float xNormals[]={ //X Y Z W\n"); float outputNormal[4]={0}; unsigned int i=0,z=0,z1=0,z2=0,z3=0; for (i=0; i<coordLength/3; i++) { z=(i*3)*3; z1=z; outputNormal[0]=coords[z1+0]; outputNormal[1]=coords[z1+1]; outputNormal[2]=coords[z1+2]; outputNormal[3]=1.0f; z+=3; z2=z; z+=3; z3=z; findNormal(&outputNormal[0], &outputNormal[1], &outputNormal[2] , coords[z2+0] , coords[z2+1] , coords[z2+2], coords[z3+0] , coords[z3+1] , coords[z3+2] ); //fprintf(stderr," %0.4ff,%0.4ff,%0.4ff,\n",outputNormal[0],outputNormal[1],outputNormal[2]); //fprintf(stderr," %0.4ff,%0.4ff,%0.4ff,\n",outputNormal[0],outputNormal[1],outputNormal[2]); //fprintf(stderr," %0.4ff,%0.4ff,%0.4ff,\n",outputNormal[0],outputNormal[1],outputNormal[2]); } //fprintf(stderr,"};\n"); }
void CharacterController::checkCollision(MeshCollider* collider) { Vector3 pos = getGameObject()->getTransform()->getPosition(); Mesh* mesh = collider->getMesh(); std::vector<Vector3>* vertices = mesh->getVertices(); // We basically want to set the mesh to the origin, including its rotation. // If we rotate the mesh, then we need to make sure we rotate the characters bounds too // so that the angle between the mesh and character remains the same. // If we set position to 0, 0, then we need to make the characters bounds box move the same way // (minus the mesh's position) so that it doesn't get closer. Matrix4x4 mat = Matrix4x4::getTrs(collider->getGameObject()->getTransform()->getPosition(), collider->getGameObject()->getTransform()->getRotation(), Vector3(1, 1, 1)); mat = mat.inverse(); Vector3 relPos = mat * pos; Vector3 extents = bounds.extents; extents.y = extents.y / 2.0f; // Set to 20.0f for a large step //********************************************** Collision collision; //collision.relativeVelocity = frameMoveSpeed; for(int v = 0; v < vertices->size(); v+=3) { Vector3 a = vertices->at(v); Vector3 b = vertices->at(v+1); Vector3 c = vertices->at(v+2); if(colliding(relPos, extents, a, b, c) == true) { ContactPoint contact; contact.normal = findNormal(a, b, c); contact.thisCollider = this; contact.otherCollider = collider; contact.a = a; contact.b = b; contact.c = c; collision.contacts.push_back(contact); } } Matrix4x4 rotMat = Matrix4x4::getIdentity(); rotMat = rotMat.rotate(collider->getGameObject()->getTransform()->getRotation() * -1.0f); if(collision.contacts.size() > 0) { //relPos = handleCollision(collision, relPos, extents); //relPos = relPos + (rotMat * handleCollision(collision, relPos, extents)); relPos = relPos + handleCollision(collision, relPos, extents); } //******************************************* /////////////////////////////////// Collision stepCollision; Vector3 stepExtents = bounds.extents; stepExtents.x = stepExtents.x / 2.0f; stepExtents.z = stepExtents.z / 2.0f; stepExtents.y = stepExtents.y + 0.01f; for(int v = 0; v < vertices->size(); v+=3) { Vector3 a = vertices->at(v); Vector3 b = vertices->at(v+1); Vector3 c = vertices->at(v+2); if(colliding(relPos, stepExtents, a, b, c) == true) { ContactPoint contact; contact.normal = findNormal(a, b, c); contact.thisCollider = this; contact.otherCollider = collider; contact.a = a; contact.b = b; contact.c = c; stepCollision.contacts.push_back(contact); } } stepExtents.y = stepExtents.y - 0.01f; if(stepCollision.contacts.size() > 0) { grounded = true; relPos = relPos + (rotMat * handleStep(stepCollision, relPos, stepExtents)); } else { //grounded = false; } /////////////////////////////////// mat = mat.inverse(); getGameObject()->getTransform()->setPosition(mat * relPos); }
void drawMounts() { GLfloat x1, x2, z, norm[3], vertInc = 1.0 / arraySize; // temporary verticy storage (for calculating normals) GLfloat lastx1Vert[3], lastx2Vert[3], newx1Vert[3], newx2Vert[3]; // colors for drawing glPushMatrix(); GLfloat color[] = {0.8,0.4,0,1.0}; GLfloat lakeColor[] = {0, 0.2, 0.8, 1.0}; GLfloat snowColor[] = {1.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT, GL_DIFFUSE, color); // find highest Y value generated, base snow caps on this value findHighestY(); highestY = 0.6*highestY; // replace any negative y values with 0 for lakes for (int h = 0; h < totArraySize; h++) if (yVals[h] < 0) yVals[h] = 0; // generate quad strips along z axis for (int i = 0; i < arraySize; i++){ x1 = i*vertInc; x2 = (i+1)*vertInc; z = 0.0; glBegin(GL_QUAD_STRIP); lastx1Vert[0]=x1; lastx1Vert[1]=yVals[i*(arraySize+1)]; lastx1Vert[2]=z; lastx2Vert[0]=x2; lastx2Vert[1]=yVals[(i+1)*(arraySize+1)]; lastx2Vert[2]=z; for (int j = 0; j <= arraySize; j++) { z += vertInc; newx1Vert[0]=x1; newx1Vert[1]=yVals[i*(arraySize+1)+j]; newx1Vert[2]=z; newx2Vert[0]=x2; newx2Vert[1]=yVals[(i+1)*(arraySize+1)+j]; newx2Vert[2]=z; // if the y value is zero, color the verticy like a lake if (lastx1Vert[1] <= 0) { glMaterialfv(GL_FRONT, GL_DIFFUSE, lakeColor); } // if the y value is above a calculated threshhold, color white else if (lastx1Vert[1] >= highestY) glMaterialfv(GL_FRONT, GL_DIFFUSE, snowColor); // otherwise color as rocks else glMaterialfv(GL_FRONT, GL_DIFFUSE, color); findNormal(lastx1Vert, newx1Vert, lastx2Vert, norm); glNormal3fv(norm); glVertex3fv(lastx1Vert); // repeat for other verticy if (lastx2Vert[1] <= 0) { glMaterialfv(GL_FRONT, GL_DIFFUSE, lakeColor); } else if (lastx2Vert[1] >= highestY) glMaterialfv(GL_FRONT, GL_DIFFUSE, snowColor); else glMaterialfv(GL_FRONT, GL_DIFFUSE, color); findNormal(lastx2Vert, lastx1Vert, newx2Vert, norm); glNormal3fv(norm); glVertex3fv(lastx2Vert); lastx1Vert[0]=newx1Vert[0]; lastx1Vert[1]=newx1Vert[1]; lastx1Vert[2]=newx1Vert[2]; lastx2Vert[0]=newx2Vert[0]; lastx2Vert[1]=newx2Vert[1]; lastx2Vert[2]=newx2Vert[2]; } glNormal3fv(norm); glVertex3fv(lastx1Vert); glNormal3fv(norm); glVertex3fv(lastx2Vert); glEnd(); } glPopMatrix(); }
void Ribbon::draw() { ofSetHexColor(0xffffff); ofDrawBitmapString(ofToString(segments.size()), 10, 10); vector<ofVec3f> middleLine; vector<ofFloatColor> colours; mesh.clear(); ofVec3f lastLeftPoint, lastRightPoint; for(int i = 0; i < segments.size(); i++) { ofNode thisNode = *(segments[i]); ofNode nextNode = (i == segments.size()-1) ? head : *(segments[i+1]); //the further away each node is the thinner the line float thickness = ofMap(thisNode.getPosition().distance( nextNode.getPosition() ), 10, 100, maxThickness, minThickness, true); //attenuate thickness if we are near the tails int tailTaper = 100; thickness *= ofMap(i, segments.size() - MIN(frontTaper,segments.size()), segments.size(), 1.0, 0.0, true); thickness *= ofMap(i, 0, MAX(backTaper,segments.size()), 0.0, 1.0, true); ofVec3f bottomPoint = thisNode.getPosition() + ofVec3f(0, 1, 0) * thickness / 2.0; ofVec3f topPoint = thisNode.getPosition() + ofVec3f(0, -1, 0) * thickness / 2.0; if (fadeInZ) { topPoint.z = i; bottomPoint.z = i; } #ifdef NORMALS ofVec3f bottomPoint2 = nextNode.getPosition() + ofVec3f(0, 1, 0) * thickness / 2.0; ofVec3f topPoint2 = nextNode.getPosition() + ofVec3f(0, -1, 0) * thickness / 2.0; if (fadeInZ) { topPoint2.z = i+1; bottomPoint2.z = i+1; } #endif float alpha = ((float) i ) /segments.size(); mesh.addVertex(bottomPoint); mesh.addColor(ofFloatColor(1, 1, 1, alpha)); mesh.addVertex(topPoint); mesh.addColor(ofFloatColor(1, 1, 1, alpha)); #ifdef NORMALS mesh.addNormal(findNormal(bottomPoint2, topPoint, bottomPoint)); mesh.addNormal(findNormal(bottomPoint, topPoint2, topPoint)); #endif middleLine.push_back((bottomPoint + topPoint) * 0.5); colours.push_back(ofFloatColor(1.0, 0, 0.8, ((float) i ) /segments.size())); // ofSetHexColor(0x0); // ofDrawBitmapString(ofToString(i), bottomPoint.x, bottomPoint.y); } mesh.draw(); if (drawPink) { ofMesh tmesh; tmesh.setMode(OF_PRIMITIVE_LINE_STRIP); tmesh.addVertices(middleLine); tmesh.enableColors(); tmesh.addColors(colours); tmesh.draw(); } }