ObjectNode* genTree(int branching, int maxDepth, int density, float scaleFactor, float seasonProb, float height, const mat4& initTrans, const mat4& initSkew) { ObjectNode* tree = new ObjectNode(nullptr,initTrans, initSkew); mat4 tempRotate = rX(M_PI/2.0); mat4 tempTrans = distort(1.0, 0.2, 1.0); mat4 tempSkew = distort(1.0, 5.0, 1.0); mat4 tempMove = translate(0.0, -2.0, 0.0); tree->addChild( *new ObjectNode( Global::treeCone, tempMove * tempTrans * tempRotate, tempSkew * tempRotate) ); tempTrans = distort(0.3, height, 0.3); tempMove[1][3] = height - 2.0; tree->addChild( *new ObjectNode(Global::treeCylinder, tempMove * tempTrans * tempRotate, tempRotate) ); tempMove[1][3] = height * 0.6 + 0.1; tree->addChild( *genBranch(branching, maxDepth, density, scaleFactor, seasonProb, tempMove) ); mat4 rotMat = rY(2.0 * M_PI/4.0); tempSkew = rZ(M_PI/4.0); for (int i = 0; i < 4; ++i) { tempSkew = rotMat * tempSkew; tree->addChild( *genBranch(branching, maxDepth, density, scaleFactor, seasonProb, tempMove * tempSkew, tempSkew) ); } tree->addChild( *genLeafBunch(M_PI/2.0, 3.0, 0.5, density, translate(0.0, height, 0.0) * scale(0.7)) ); return tree; }
ObjectNode* genBranch(int branching, int maxDepth, int density, float scaleFactor, float seasonProb, const mat4& initTrans, const mat4& initSkew, int currentDepth) { mat4 tempTrans = distort(0.2, 1.0, 0.2); mat4 tempMove = translate(0.0, 1.0, 0.0); mat4 tempSkew = distort(5.0, 1.0, 5.0); mat4 tempRotate = rX(M_PI/2.0); ObjectNode* branch = new ObjectNode(nullptr, initTrans, initSkew); branch->addChild(*new ObjectNode( Global::treeCone, tempMove * tempTrans * tempRotate, tempSkew * tempRotate ) ); if (currentDepth < maxDepth) { const int branchFact = branching; mat4 tempRotate = rZ(M_PI/6.0); mat4 rotMat = rY(2.0 * M_PI / branchFact); tempTrans = scale(scaleFactor); tempMove = translate(0.0, 1.5, 0.0); mat4 twist = rY(M_PI / branchFact) * tempMove; mat4 loopTemp = rotMat * tempRotate; for (int i = 0; i < branchFact; ++i) { loopTemp = rotMat * loopTemp; branch->addChild( *genBranch( branching, maxDepth, density, scaleFactor, seasonProb, twist * loopTemp * tempTrans, loopTemp, currentDepth + 1 ) ); } } return branch; }
Direction PlayerState::getRelativeXZDirection(const RealCoords & rc) { const double diffX = rX(rc) - rX(position); const double diffZ = rZ(rc) - rZ(position); if (std::abs(diffX) > std::abs(diffZ)) { // We compare on the x axis if (diffX > 0) return BLOCK_XPLUS; else return BLOCK_XMINUS; } else { // We compare on the z axis if (diffZ > 0) return BLOCK_ZPLUS; else return BLOCK_ZMINUS; } }
ObjectNode* genWheel(const mat4& initTrans, const mat4& initSkew) { ObjectNode* wheel = new ObjectNode(nullptr, initTrans, initSkew); mat4 rotMat = rX(M_PI/2.0); mat4 tempTransform = distort(0.1, 0.1, 0.6); wheel->addChild( *new ObjectNode(Global::wheelCylinder, rotMat * tempTransform, rotMat, rotateWheel) ); mat4 tempRotate = rZ(M_PI/4.0); wheel->addChild( *new ObjectNode( Global::wheelCylinder, tempRotate * rotMat * tempTransform, tempRotate * rotMat, rotateWheel ) ); tempRotate = rZ(M_PI/2.0); wheel->addChild( *new ObjectNode( Global::wheelCylinder, tempRotate * rotMat * tempTransform, tempRotate * rotMat, rotateWheel ) ); tempRotate = rZ(-M_PI/4.0); wheel->addChild( *new ObjectNode( Global::wheelCylinder, tempRotate * rotMat * tempTransform, tempRotate * rotMat, rotateWheel ) ); wheel->addChild( *new ObjectNode( Global::wheelTube, distort(1.0, 1.0, 0.2), MatMath::ID, rotateWheel ) ); return wheel; }
ObjectNode* genChair(const mat4& initTrans, const mat4& initSkew) { ObjectNode* chair = new ObjectNode(nullptr, initTrans, initSkew); chair->addChild( *new ObjectNode(Global::furnCube1, distort(0.5, 0.2, 0.4)) ); chair->addChild( *new ObjectNode( Global::furnCube1, translate(-0.5, 0.5, 0.0) * rZ(M_PI/8.0) * distort(0.15, 0.45, 0.4), rZ(M_PI/8.0)) ); chair->addChild( *new ObjectNode( Global::furnCube1, translate(0.0, 0.3, 0.45) * distort(0.4, 0.1, 0.1)) ); chair->addChild( *new ObjectNode( Global::furnCube1, translate(0.0, 0.3, -0.45) * distort(0.4, 0.1, 0.1)) ); chair->addChild( *new ObjectNode( Global::treeCylinder, translate(-0.4, -0.3, 0.3) * scale(0.1) * rX(M_PI/2.0), rX(M_PI/2.0)) ); chair->addChild( *new ObjectNode( Global::treeCylinder, translate(0.4, -0.3, 0.3) * scale(0.1) * rX(M_PI/2.0), rX(M_PI/2.0)) ); chair->addChild( *new ObjectNode( Global::treeCylinder, translate(0.4, -0.3, -0.3) * scale(0.1) * rX(M_PI/2.0), rX(M_PI/2.0)) ); chair->addChild( *new ObjectNode( Global::treeCylinder, translate(-0.4, -0.3, -0.3) * scale(0.1) * rX(M_PI/2.0), rX(M_PI/2.0)) ); return chair; }
void timer(int t) //animates the scene { if (Global::animating) { Global::sunVec = rZ(M_PI/2000.0) * Global::sunVec; if (Global::sun != nullptr) Global::sun->animate(M_PI/250.0); //By keeping a pointer to the car scene, I can call animate() on it without incurring the overhead //of calling the function recursively on the rest of the object tree, Global::when only the car is animated. if (Global::root != nullptr) Global::root->animate(M_PI/250.0); glutPostRedisplay(); } glutTimerFunc(20, timer, 0); }
ObjectNode* genLeafBunch(float rho, float radius, float prob, int numLeaves, const mat4& initTrans, const mat4& initSkew) { ObjectNode* bunch = new ObjectNode(nullptr, initTrans, initSkew); mat4 rotMat = MatMath::ID; mat4 tempTrans = translate(0.0, radius, 0.0); mat4 tempRotate = rY( randNum(0.0, 2.0 * M_PI) ) * rZ(randNum(0.0, rho) ); ObjectNode* temp = new ObjectNode(nullptr, tempRotate * tempTrans, tempRotate); temp->addChild(*genLeaf(prob)); bunch->addChild(*temp); for (int i = 1; i < numLeaves; ++i) { rotMat = rY( randNum(0.0, 2.0 * M_PI) ) * rX( randNum(0.0, M_PI/2.0) ); tempRotate = rY( randNum(0.0, 2.0 * M_PI) ) * rX( randNum(0.0, rho) ); temp = new ObjectNode(nullptr, tempRotate * tempTrans * rotMat, tempRotate * rotMat); temp->addChild(*genLeaf(prob)); bunch->addChild(*temp); } return bunch; }
//Model Animations mat4 rotateSun(float theta) { return rZ(theta/8.0f); }
ObjectNode* genFirePlace(const mat4& initTrans, const mat4& initSkew) { return new ObjectNode(Global::furnTube, initTrans * rZ(M_PI/4.0), initSkew * rZ(M_PI/4.0)); }
mat4 rotateWheel(float theta) { return rZ(25 * theta); }
ObjectNode* genLeaf(float prob, const mat4& initTrans, const mat4& initSkew) { const int colorInd = bernoulli() < prob ? 1 : 0; return new ObjectNode( Global::leaf[colorInd], initTrans * rZ(M_PI/12.0), initSkew * rZ(M_PI/12.0) ); }
//Begin ConeGen void ConeGen::generate(int numEdgePoints, const color4& baseColor, const color4& pointColor) { int numPoints = numEdgePoints + 1; //numEdgePoints + 2 points, 2 colors, 2 * numEdgePoints + 1 normals //numEdgePoints wedges, 2 triangles per wedge, 3 vertices per triangle, 3 attributes per vertex numElements = 3 * numEdgePoints + 5; numVertices = numPoints + 2 * numEdgePoints; numIndices = numVertices * 3; elements = new vec4[numElements]; data = new vec4[3 * numVertices]; indices = new unsigned char[numIndices]; sizeData = numVertices * 3 * sizeof(vec4); sizeIndices = numIndices * sizeof(GLubyte); colors = numVertices * sizeof(vec4); normals = numVertices * 2 * sizeof(vec4); const float theta = 2.0 * M_PI / numEdgePoints; //set vertices for (int i = 0; i < numEdgePoints; ++i) elements[i] = point4(cos(i * theta), sin(i * theta), 1.0, 1.0); elements[numEdgePoints] = point4(0.0, 0.0, 1.0, 1.0); elements[numPoints] = point4(0.0, 0.0, -1.0, 1.0); //set colors elements[numEdgePoints + 2] = baseColor; elements[numEdgePoints + 3] = pointColor; //set normals elements[numEdgePoints + 4] = MatMath::zNORM; int temp = numEdgePoints + 5; mat4 tempRotate; const normal4 tempNorm1 = normal4(0.4472, 0.0, -0.1056, 0.0); const normal4 tempNorm2 = rZ(theta/2.0) * tempNorm1; for (int i = 0; i < numEdgePoints; ++i) { tempRotate = rZ(i * theta); elements[i + temp] = tempRotate * tempNorm1; elements[i + numEdgePoints + temp] = tempRotate * tempNorm2; } //points //base for (int i = 0; i < numEdgePoints; ++i) data[i] = elements[i]; data[numEdgePoints] = elements[numEdgePoints]; //edge for (int i = 0; i < numEdgePoints; ++i) data[i + numPoints] = elements[i]; //tip for (int i = 0; i < numEdgePoints; ++i) data[i + 2 * numEdgePoints + 1] = elements[numPoints]; //colors //base for (int i = 3 * numEdgePoints + 1; i < 5 * numEdgePoints + 2; ++i) data[i] = baseColor; //tip for (int i = 5 * numEdgePoints + 2; i < 6 * numEdgePoints + 2; ++i) data[i] = pointColor; //normals //base for (int i = 6 * numEdgePoints + 2; i < 7 * numEdgePoints + 3; ++i) data[i] = MatMath::zNORM; //edge temp = 7 * numEdgePoints + 3; for (int i = 0; i < numEdgePoints; ++i) data[i + temp] = elements[i + numEdgePoints + 5]; //tip temp = 8 * numEdgePoints + 3; for (int i = 0; i < numEdgePoints; ++i) data[i + temp] = elements[i + 2 * numEdgePoints + 5]; //indices //base for (int i = 0; i < numEdgePoints - 1; ++i) { indices[3 * i] = numEdgePoints; indices[3 * i + 1] = i; indices[3 * i + 2] = i + 1; } indices[3 * numEdgePoints - 3] = numEdgePoints; indices[3 * numEdgePoints - 2] = numEdgePoints - 1; indices[3 * numEdgePoints - 1] = 0; //cone for (int i = 0; i < numEdgePoints - 1; ++i) { indices[3 * (i + numEdgePoints)] = i + 1 + numPoints; indices[3 * (i + numEdgePoints) + 1] = i + numPoints; indices[3 * (i + numEdgePoints) + 2] = i + numPoints + numEdgePoints; } indices[6 * numEdgePoints - 3] = numPoints; indices[6 * numEdgePoints - 2] = numPoints + numEdgePoints - 1; indices[6 * numEdgePoints - 1] = 3 * numEdgePoints; }
void keyboard(unsigned char key, int x, int y) { switch (key) { //exit on Esc key case 033: exit( EXIT_SUCCESS ); return; //restor to beginning on R case 'r': case 'R': Global::positMat = Global::initPosit; Global::pitchMat = Global::rollMat = Global::yawMat = MatMath::ID; Global::animating = true; glutPostRedisplay(); return; //roll right on E case 'e': case 'E': Global::rollMat = rZ(M_PI/12.0) * Global::rollMat; glutPostRedisplay(); return; //roll left on Q case 'q': case 'Q': Global::rollMat = rZ(-M_PI/12.0) * Global::rollMat; glutPostRedisplay(); return; //move forward on W case 'w': case 'W': Global::positMat[2][3] += Global::SPEED; glutPostRedisplay(); return; //move backward on S case 's': case 'S': Global::positMat[2][3] -= Global::SPEED; glutPostRedisplay(); return; //move left on A case 'a': case 'A': Global::positMat[0][3] += Global::SPEED; glutPostRedisplay(); return; //move right on D case 'd': case 'D': Global::positMat[0][3] -= Global::SPEED; glutPostRedisplay(); return; //crouch on C case 'c': case 'C': if (Global::crouching) { Global::positMat[1][3] -= Global::CROUCH_DIST; Global::crouching = false; } else { Global::positMat[1][3] += Global::CROUCH_DIST; Global::crouching = true; } glutPostRedisplay(); return; //scale Global::positMat on I (zoom in) case 'i': case 'I': Global::positMat = scale(Global::ZOOMIN) * Global::positMat; glutPostRedisplay(); return; //scale down Global::positMat on O (zoom out) case 'o': case 'O': Global::positMat = scale(Global::ZOOMOUT) * Global::positMat; glutPostRedisplay(); return; //Pause and play animation on T case 't': case 'T': Global::animating = !Global::animating; } }