// points the camera at the given point in 3d space void Camera::pointAt(float* targetVec) { float tempVec[3]; float up[3] = { 0.0f, 0.0f, 1.0f }; forwardVec[0] = targetVec[0] - position[0]; forwardVec[1] = targetVec[1] - position[1]; forwardVec[2] = targetVec[2] - position[2]; normalizeVec(forwardVec); rotateAroundVec(forwardVec, up, -1.57079632679f, tempVec); tempVec[2] = 0; normalizeVec(tempVec); vectorCopy(rightVec, tempVec); rotateAroundVec(forwardVec, rightVec, 1.57079632679f, tempVec); vectorCopy(upVec, tempVec); }
vector<float> GaussianKernel1D(float sigma) { assert (sigma > 0); int dim = (int) max(3.0f, 2 * GAUSSKERN * sigma + 1.0f); // make dim odd if (dim % 2 == 0) dim++; //printf("GaussianKernel1D(): Creating 1x%d vector for sigma=%.3f gaussian kernel\n", dim, sigma); vector<float> kern(dim); float s2 = sigma * sigma; int c = dim / 2; for (int i = 0; i < (dim + 1) / 2; i++) { float v = 1 / (2 * PI * s2) * exp(-(i*i) / (2 * s2)); kern[c+i] = v; kern[c-i] = v; } normalizeVec(kern); //for (unsigned int i = 0; i < kern.size(); i++) // printf("%f\n", kern[i]); return kern; }
animation::animation(sf::Vector2f start, sf::Vector2f end, sf::CircleShape shape, float speed): start(start), end(end), shape(shape), speed(speed) { this->increment = MOVE_DISTANCE * speed; this->direction = normalizeVec(end - start); this->finished = false; this->position = start; }
void animation::update(sf::Vector2f start, sf::Vector2f end, float speed) { this->start = start; this->end = end; this->speed = speed; this->position = start; this->increment = MOVE_DISTANCE * speed; this->direction = normalizeVec(end - start); finished = false; }
void HarmonicBond::interact() const { // Call parent class. Bond::interact(); // Get the number of bonds. left and right will have the same size - we checked this last time // updateLocalIDs was called. int nbonds = left.size(); // Check if local ids need updating. if (simData->getNeedsRemake()) updateLocalIDs(); // Get simdata, check if the local ids need updating RealType **x = simData->X(); RealType **f = simData->F(); RealType *dX = new RealType[sim_dimensions]; for (int i=0; i<nbonds; ++i) { // Get the global, then local ids of the particles. int id1 = left[i], id2 = right[i]; // Calculate displacement Base::gflow->getDisplacement(x[id1], x[id2], dX); RealType r = magnitudeVec(dX, sim_dimensions); // Calculate displacement from equilibrium RealType dr = r - distance[i]; // Makes nX the unit vector of dX normalizeVec(dX, sim_dimensions); // nX is now the force vector scalarMultVec(springConstant*dr, dX, sim_dimensions); // Add forces to particles minusEqVec(f[id1], dX, sim_dimensions); plusEqVec (f[id2], dX, sim_dimensions); } // Clean up. delete [] dX; }
//-------------------------------------------------------------------- void RglSphereN (float radius, float zmin, float zmax, float thetamax, int detail, MVertex &nscale) { int ixy; int iz; int zDensity; int xyDensity; float x,y,z; float xySize; float rad; float zrad; float zradStep; float radStep; float zminRad; float zmaxRad; //-- do some quick error checking if (!radius || !thetamax || zmin == zmax ) return; if (thetamax > 360.0f) thetamax = 360.0f; if (thetamax < -360.0f) thetamax = -360.0f; if (zmin < -radius) zmin = -radius; if (zmin > radius) zmin = radius; if (zmax < -radius) zmax = -radius; if (zmax > radius) zmax = radius; //-- set number of y polygons to half that of detail, & account for partial spheres zDensity = abs((int)( ((zmax-zmin)/radius)*(float)detail )/3); if (zDensity < 2) zDensity = 2; xyDensity = abs((int)( (D2RAD(thetamax)/(2.0*M_PI))*(float)detail )); if (xyDensity < 4) xyDensity = 4; //-- make space for vertices RglPoint **verts = new RglPoint*[zDensity+1]; RglPoint **norms = new RglPoint*[zDensity+1]; for (iz = 0; iz < (zDensity+1); iz++) { norms[iz] = new RglPoint[xyDensity+1]; verts[iz] = new RglPoint[xyDensity+1]; } zmaxRad = -acos(zmax/radius); zminRad = -acos(zmin/radius); zradStep = (zmaxRad-zminRad)/(float)(zDensity); radStep = D2RAD(thetamax)/(float)xyDensity; zrad = zmaxRad; for (iz = 0; iz < zDensity+1; iz++) { z = cos(zrad) * radius; rad = -M_PI/2.0; xySize = sin(zrad) * radius; for(ixy = 0; ixy < (xyDensity+1); ixy++) { x = sin (rad)*xySize; y = cos (rad)*xySize; verts[iz][ixy][0] = norms[iz][ixy][0] = x; verts[iz][ixy][1] = norms[iz][ixy][1] = y; verts[iz][ixy][2] = norms[iz][ixy][2] = z; normalizeVec(norms[iz][ixy]); rad += radStep; } zrad -= zradStep; } MVertex N1, N2, T; float s1, t1, t2, zd, xyd; zd = zDensity-1.0; xyd = xyDensity-1.0; for (iz = 0; iz < zDensity; iz++) { t1 = 1.0 - (zd-iz)/zd; t2 = 1.0 - (zd-iz-1.0)/zd; glBegin(GL_QUAD_STRIP); if(zmin < zmax) //-- if we want to flip the normals, swap zmin and zmax for(ixy = 0; ixy <= xyDensity; ixy++) { s1 = ixy/xyd; T = norms[iz+1][ixy]; N1 = nscale.scale(T); T = norms[iz][ixy]; N2 = nscale.scale(T); glTexCoord2f_M0(s1, t2); glTexCoord2f_M1(s1, t2); glNormal3fv( N1.xyz() ); glVertex3fv(verts[iz+1][ixy]); glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glNormal3fv( N2.xyz() ); glVertex3fv(verts[iz][ixy]); } else for(ixy = 0; ixy <= xyDensity; ixy++) { s1 = ixy/xyd; glTexCoord2f_M0(s1, t2); glTexCoord2f_M1(s1, t2); glNormal3f( -norms[iz+1][ixy][0], -norms[iz+1][ixy][1], -norms[iz+1][ixy][2]); glVertex3fv(verts[iz+1][ixy]); glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glNormal3f( -norms[iz][ixy][0], -norms[iz][ixy][1], -norms[iz][ixy][2]); glVertex3fv(verts[iz][ixy]); } glEnd(); } //-- cleanup for (iz = 0; iz < (zDensity+1); iz++) { delete []verts[iz]; delete []norms[iz]; } delete []verts; delete []norms; }
//-------------------------------------------------------------------- void RglCylinder (float radius, float zmin, float zmax, float thetamax, int detail, bool dcomp) { int zDensity; int xyDensity; int ixy; int iz; float x; float y; float rad; float radStep; //-- do some quick error checking if (!radius || !thetamax) return; if (thetamax > 360.0f) thetamax = 360.0f; if (thetamax < -360.0f) thetamax = -360.0f; //-- calculate tesselation xyDensity = abs((int)( (D2RAD(thetamax)/(2.0*M_PI))*(float)detail )); if(dcomp) zDensity = abs((int)(((zmax-zmin)/radius)*((float)detail/10.0f))); else zDensity = 3; if (xyDensity < 4) xyDensity = 4; else if (xyDensity > 100) xyDensity = 100; if (zDensity < 2) zDensity = 2; else if(zDensity > 100) zDensity = 100; //-- make space for vertices RglPoint **verts = new RglPoint*[zDensity+1]; RglPoint **norms = new RglPoint*[zDensity+1]; for (iz = 0; iz < (zDensity+1); iz++) { norms[iz] = new RglPoint[xyDensity+1]; verts[iz] = new RglPoint[xyDensity+1]; for(ixy = 0; ixy < xyDensity+1; ixy++) { norms[iz][ixy][0] = 0.0f; norms[iz][ixy][1] = 0.0f; norms[iz][ixy][2] = 0.0f; } } //-- calculate min and max radStep = (D2RAD(thetamax))/( (float)xyDensity ); rad = M_PI/2.0; for (ixy = 0; ixy < xyDensity+1; ixy++) { x = sin (rad)*radius; y = cos (rad)*radius; verts[0][ixy][0] = verts[zDensity-1][ixy][0] = x; verts[0][ixy][1] = verts[zDensity-1][ixy][1] = y; verts[0][ixy][2] = zmin; verts[zDensity-1][ixy][2] = zmax; norms[0][ixy][0] = norms[zDensity-1][ixy][0] = x; norms[0][ixy][1] = norms[zDensity-1][ixy][1] = y; norms[0][ixy][2] = norms[zDensity-1][ixy][2] = 0.0; normalizeVec(norms[0][ixy]); normalizeVec(norms[zDensity-1][ixy]); rad += radStep; } //-- interpolate tesselation float izf; float zDf = (float)zDensity-1; for(iz = 1; iz < zDensity-1; iz++) { izf = (float)iz; for (ixy = 0; ixy < xyDensity+1; ixy++) { verts[iz][ixy][0] = verts[0][ixy][0]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][0]*(izf/zDf); verts[iz][ixy][1] = verts[0][ixy][1]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][1]*(izf/zDf); verts[iz][ixy][2] = verts[0][ixy][2]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][2]*(izf/zDf); norms[iz][ixy][0] = norms[0][ixy][0]; norms[iz][ixy][1] = norms[0][ixy][1]; norms[iz][ixy][2] = norms[0][ixy][2]; } } //-- Draw cylinder float s1, t1, t2, zd, xyd; zd = zDensity-1.0; xyd = xyDensity-1.0; for(iz = 0; iz < zDensity-1; iz++) { t1 = (zd-iz)/zd; t2 = (zd-iz-1.0)/zd; izf = (float)iz; glBegin(GL_TRIANGLE_STRIP); for (ixy = 0; ixy < xyDensity+1; ixy++) { s1 = ixy/xyd; glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glNormal3fv(norms[iz][ixy]); glVertex3fv(verts[iz][ixy]); glTexCoord2f_M0(s1, t2); glTexCoord2f_M1(s1, t2); glNormal3fv(norms[iz+1][ixy]); glVertex3fv(verts[iz+1][ixy]); } glEnd(); } //-- Cleanup for (iz = 0; iz < (zDensity+1); iz++) { delete []verts[iz]; delete []norms[iz]; } delete []verts; delete []norms; }
//-------------------------------------------------------------------- void RglDisk (float height, float radius, float thetamax, int detail, bool dcomp) { int zDensity; int xyDensity; int ixy; int iz; float x,y; float rad; float radStep; float norm[3]; //-- do some kludgy error checking if ( radius == 0.0f || thetamax == 0.0f ) return; if (thetamax > 360.0f) thetamax = 360.0f; if (thetamax < -360.0f) thetamax = -360.0f; //-- calculate tesselation xyDensity = abs((int)( (D2RAD(thetamax)/(2.0*M_PI))*(float)detail )); if(dcomp) zDensity = abs((int)((float)detail/4.0f)); else zDensity = 2; if (xyDensity < 4) xyDensity = 4; else if (xyDensity > 100) xyDensity = 100; if (zDensity < 2) zDensity = 2; else if(zDensity > 100) zDensity = 100; //-- make space for vertices RglPoint **verts = new RglPoint*[zDensity+1]; RglPoint **norms = new RglPoint*[zDensity+1]; for (iz = 0; iz < (zDensity+1); iz++) { norms[iz] = new RglPoint[xyDensity+1]; verts[iz] = new RglPoint[xyDensity+1]; for(ixy = 0; ixy < xyDensity+1; ixy++) { norms[iz][ixy][0] = 0.0f; norms[iz][ixy][1] = 0.0f; norms[iz][ixy][2] = 0.0f; } } //-- Calculate tip and base radStep = (D2RAD(thetamax))/( (float)xyDensity ); rad = M_PI/2.0; for (ixy = 0; ixy < xyDensity+1; ixy++) { //-- verts for tip verts[0][ixy][0] = verts[0][ixy][1] = 0.0f; verts[0][ixy][2] = height; //-- verts for base x = sin (rad)*radius; y = cos (rad)*radius; verts[zDensity-1][ixy][0] = x; verts[zDensity-1][ixy][1] = y; verts[zDensity-1][ixy][2] = height; if (ixy > 0) { if(thetamax < 0.0f) calcNormal (norm, verts[0][ixy-1], verts[zDensity-1][ixy-1], verts[zDensity-1][ixy]); else calcNormal (norm, verts[0][ixy-1], verts[zDensity-1][ixy], verts[zDensity-1][ixy-1]); norms[0][ixy][0] += norm[0]; norms[0][ixy][1] += norm[1]; norms[0][ixy][2] += norm[2]; norms[0][ixy-1][0] += norm[0]; norms[0][ixy-1][1] += norm[1]; norms[0][ixy-1][2] += norm[2]; } rad += radStep; } norms[0][0][0] += norms[0][xyDensity][0]; norms[0][0][1] += norms[0][xyDensity][1]; norms[0][0][2] += norms[0][xyDensity][2]; norms[0][xyDensity][0] += norms[0][0][0]; norms[0][xyDensity][1] += norms[0][0][1]; norms[0][xyDensity][2] += norms[0][0][2]; for(ixy = 0; ixy < xyDensity+1; ixy++) { normalizeVec(norms[0][ixy]); norms[zDensity-1][ixy][0] = norms[0][ixy][0] ; norms[zDensity-1][ixy][1] = norms[0][ixy][1] ; norms[zDensity-1][ixy][2] = norms[0][ixy][2] ; } //-- Interpolate tesselation float zDf = (float)zDensity-1; float izf; for(iz = 1; iz < zDensity-1; iz++) { izf = (float)iz; for (ixy = 0; ixy < xyDensity+1; ixy++) { verts[iz][ixy][0] = verts[0][ixy][0]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][0]*(izf/zDf); verts[iz][ixy][1] = verts[0][ixy][1]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][1]*(izf/zDf); verts[iz][ixy][2] = verts[0][ixy][2]*((zDf-izf)/zDf) + verts[zDensity-1][ixy][2]*(izf/zDf); norms[iz][ixy][0] = norms[0][ixy][0]; norms[iz][ixy][1] = norms[0][ixy][1]; norms[iz][ixy][2] = norms[0][ixy][2]; } } //-- Draw tip float s1, t1, t2, zd, xyd; zd = zDensity-1.0; xyd = xyDensity-1.0; s1 = 0.0; t1 = 1.0; glBegin(GL_TRIANGLE_FAN); glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glNormal3fv(norms[0][0]); glVertex3fv(verts[0][0]); for (ixy = xyDensity; ixy >= 0; ixy--) { s1 = ixy/xyd; glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glVertex3fv(verts[1][ixy]); } glEnd(); //-- Draw the rest for(iz = 1; iz < zDensity-1; iz++) { t1 = (zd-iz)/zd; t2 = (zd-iz-1.0)/zd; glBegin(GL_QUAD_STRIP); izf = (float)iz; for (ixy = 0; ixy < xyDensity+1; ixy++) { s1 = ixy/xyd; glTexCoord2f_M0(s1, t2); glTexCoord2f_M1(s1, t2); glVertex3fv(verts[iz+1][ixy]); glTexCoord2f_M0(s1, t1); glTexCoord2f_M1(s1, t1); glVertex3fv(verts[iz][ixy]); } glEnd(); } //-- cleanup for (iz = 0; iz < (zDensity+1); iz++) { delete []verts[iz]; delete []norms[iz]; } delete []verts; delete []norms; }