void GLUTMotion(int x, int y) { // Invert y coordinate y = GLUTwindow_height - y; // Compute mouse movement int dx = x - GLUTmouse[0]; int dy = y - GLUTmouse[1]; // Process mouse motion event if ((dx != 0) || (dy != 0)) { R3Point mesh_center = mesh->Center(); if ((GLUTbutton[0] && (GLUTmodifiers & GLUT_ACTIVE_SHIFT)) || GLUTbutton[1]) { // Scale world double factor = (double) dx / (double) GLUTwindow_width; factor += (double) dy / (double) GLUTwindow_height; factor = exp(2.0 * factor); factor = (factor - 1.0) / factor; R3Vector translation = (mesh_center - camera_eye) * factor; camera_eye += translation; glutPostRedisplay(); } else if (GLUTbutton[0] && (GLUTmodifiers & GLUT_ACTIVE_CTRL)) { // Translate world double length = R3Distance(mesh_center, camera_eye) * tan(camera_yfov); double vx = length * (double) dx / (double) GLUTwindow_width; double vy = length * (double) dy / (double) GLUTwindow_height; R3Vector camera_right = camera_up % camera_towards; R3Vector translation = -((camera_right * vx) + (camera_up * vy)); camera_eye += translation; glutPostRedisplay(); } else if (GLUTbutton[0]) { // Rotate world double vx = (double) dx / (double) GLUTwindow_width; double vy = (double) dy / (double) GLUTwindow_height; double theta = 4.0 * (fabs(vx) + fabs(vy)); R3Vector camera_right = camera_up % camera_towards; R3Vector vector = (camera_right * vx) + (camera_up * vy); R3Vector rotation_axis = vector % camera_towards; rotation_axis.Normalize(); camera_eye.Rotate(R3Line(mesh_center, rotation_axis), theta); camera_towards.Rotate(rotation_axis, theta); camera_up.Rotate(rotation_axis, theta); camera_right = camera_up % camera_towards; camera_up = camera_towards % camera_right; camera_towards.Normalize(); camera_up.Normalize(); glutPostRedisplay(); } } // Remember mouse position GLUTmouse[0] = x; GLUTmouse[1] = y; }
void R3Point:: Rotate(const R3Vector& axis, RNAngle theta) { // Rotate point counterclockwise around axis through origin by radians ??? R3Vector v = Vector(); v.Rotate(axis, theta); *this = v.Point(); }
void R3Point:: Rotate(const R3Line& axis, RNAngle theta) { // Translate axis to origin R3Vector v = *this - axis.Point(); // Rotate point counterclockwise around axis through origin by radians ??? v.Rotate(axis.Vector(), theta); // Translate axis back from origin *this = axis.Point() + v; }
void GenerateParticles(R3Scene *scene, double current_time, double delta_time) { for (int i = 0; i < scene->NParticleSources(); i++) { R3ParticleSource *source = scene->ParticleSource(i); // spheres if (source->shape->type == R3_SPHERE_SHAPE) { // remainder term for fraction of particle double numberweshouldmake = delta_time * source->rate + source->remainder; int nparts = (int) floor(numberweshouldmake); source->remainder = numberweshouldmake - nparts; for (int p = 0; p < nparts; p++) { R3Particle *newpart = new R3Particle(); // calculate position and velocity double u = RandomNumber(); double theta = 2*PI*u; double v = RandomNumber(); double phi = acos(2*v-1); double r = source->shape->sphere->Radius(); R3Point center = source->shape->sphere->Center(); double x = r*cos(theta)*sin(phi); double y = r*sin(theta)*sin(phi); double z = r*cos(phi); R3Vector n = R3Vector(x,y,z); n.Normalize(); // find tangent vector, use lecture notes to get velocity R3Plane plane = R3Plane(R3Point(0,0,0),n); R3Vector a; do { a = R3Vector(RandomNumber(),RandomNumber(),RandomNumber()); a.Project(plane); } while (a.Length() == 0.0); a.Normalize(); double t1 = 2*PI*RandomNumber(); double t2 = sin(source->angle_cutoff)*RandomNumber(); a.Rotate(n,t1); R3Vector vec = R3Vector(a); R3Vector cross = R3Vector(vec); cross.Cross(n); vec.Rotate(cross,acos(t2)); newpart->position = center + n*r; newpart->velocity = vec*source->velocity; //update newpart->mass = source->mass; newpart->fixed = source->fixed; newpart->drag = source->drag; newpart->elasticity = source->elasticity; newpart->lifetime = source->lifetime; newpart->lifetimeactive = source->lifetimeactive; newpart->material = source->material; scene->particles.push_back(newpart); } } // CIRCLE if (source->shape->type == R3_CIRCLE_SHAPE) { double numberweshouldmake = delta_time * source->rate + source->remainder; int nparts = (int) floor(numberweshouldmake); source->remainder = numberweshouldmake - nparts; for (int p = 0; p < nparts; p++) { R3Particle *newpart = new R3Particle(); // calculate position and velocity double r = source->shape->circle->Radius(); R3Point center = source->shape->circle->Center(); R3Plane plane = source->shape->circle->Plane(); R3Vector n = plane.Normal(); n.Normalize(); // get a random point on a circle double xcirc, ycirc; do { xcirc = 2*r*(RandomNumber() - 0.5); ycirc = 2*r*(RandomNumber() - 0.5); } while (xcirc*xcirc + ycirc*ycirc > r*r); // get basis vectors of circle R3Vector tang; do { tang = R3Vector(RandomNumber(),RandomNumber(),RandomNumber()); tang.Project(plane); } while (tang.Length() == 0.0); R3Vector othertang = R3Vector(tang); othertang.Cross(n); othertang.Normalize(); tang.Normalize(); R3Point pos = center + tang*xcirc + othertang*ycirc; R3Vector a = R3Vector(tang); double t1 = 2*PI*RandomNumber(); double t2 = sin(source->angle_cutoff)*RandomNumber(); a.Rotate(n,t1); R3Vector vec = R3Vector(a); R3Vector cross = R3Vector(vec); cross.Cross(n); vec.Rotate(cross,acos(t2)); newpart->position = pos; newpart->velocity = vec*source->velocity; newpart->mass = source->mass; newpart->fixed = source->fixed; newpart->drag = source->drag; newpart->elasticity = source->elasticity; newpart->lifetime = source->lifetime; newpart->lifetimeactive = source->lifetimeactive; newpart->material = source->material; scene->particles.push_back(newpart); } } } for (int i = 0; i < (int)scene->enemies.size(); i++) { R3Enemy *enemy = scene->enemies[i]; // spheres if (enemy->shape->type == R3_SPHERE_SHAPE) { // remainder term for fraction of particle double numberweshouldmake = delta_time * enemy->rate + enemy->remainder; int nparts = (int) floor(numberweshouldmake); enemy->remainder = numberweshouldmake - nparts; for (int p = 0; p < nparts; p++) { R3Particle *newpart = new R3Particle(); // calculate position and velocity double u = RandomNumber(); double theta = 2*PI*u; double v = RandomNumber(); double phi = acos(2*v-1); double r = enemy->shape->sphere->Radius(); R3Point center = enemy->shape->sphere->Center(); double x = r*cos(theta)*sin(phi); double y = r*sin(theta)*sin(phi); double z = r*cos(phi); R3Vector n = R3Vector(x,y,z); n.Normalize(); // find tangent vector, use lecture notes to get velocity R3Plane plane = R3Plane(R3Point(0,0,0),n); R3Vector a; do { a = R3Vector(RandomNumber(),RandomNumber(),RandomNumber()); a.Project(plane); } while (a.Length() == 0.0); a.Normalize(); double t1 = 2*PI*RandomNumber(); double t2 = sin(enemy->angle_cutoff)*RandomNumber(); a.Rotate(n,t1); R3Vector vec = R3Vector(a); R3Vector cross = R3Vector(vec); cross.Cross(n); vec.Rotate(cross,acos(t2)); newpart->position = center + n*r; newpart->velocity = vec*enemy->velocity; //update newpart->mass = enemy->mass; newpart->fixed = enemy->fixed; newpart->drag = enemy->drag; newpart->elasticity = enemy->elasticity; newpart->lifetime = enemy->lifetime; newpart->lifetimeactive = enemy->lifetimeactive; newpart->material = enemy->material; scene->particles.push_back(newpart); } } // CIRCLE if (enemy->shape->type == R3_CIRCLE_SHAPE) { double numberweshouldmake = delta_time * enemy->rate + enemy->remainder; int nparts = (int) floor(numberweshouldmake); enemy->remainder = numberweshouldmake - nparts; for (int p = 0; p < nparts; p++) { R3Particle *newpart = new R3Particle(); // calculate position and velocity double r = enemy->shape->circle->Radius(); R3Point center = enemy->shape->circle->Center(); R3Plane plane = enemy->shape->circle->Plane(); R3Vector n = plane.Normal(); n.Normalize(); // get a random point on a circle double xcirc, ycirc; do { xcirc = 2*r*(RandomNumber() - 0.5); ycirc = 2*r*(RandomNumber() - 0.5); } while (xcirc*xcirc + ycirc*ycirc > r*r); // get basis vectors of circle R3Vector tang; do { tang = R3Vector(RandomNumber(),RandomNumber(),RandomNumber()); tang.Project(plane); } while (tang.Length() == 0.0); R3Vector othertang = R3Vector(tang); othertang.Cross(n); othertang.Normalize(); tang.Normalize(); R3Point pos = center + tang*xcirc + othertang*ycirc; R3Vector a = R3Vector(tang); double t1 = 2*PI*RandomNumber(); double t2 = sin(enemy->angle_cutoff)*RandomNumber(); a.Rotate(n,t1); R3Vector vec = R3Vector(a); R3Vector cross = R3Vector(vec); cross.Cross(n); vec.Rotate(cross,acos(t2)); newpart->position = pos; newpart->velocity = vec * 1.0; newpart->mass = enemy->mass; newpart->fixed = enemy->fixed; newpart->drag = enemy->drag; newpart->elasticity = enemy->elasticity; newpart->lifetime = enemy->lifetime; newpart->lifetimeactive = enemy->lifetimeactive; newpart->material = enemy->material; scene->particles.push_back(newpart); } } } }