Пример #1
0
void PhysicsSim::updateSphereSphereVelocities(int s1, int s2) {

	shared_ptr<SgTransformNode> n1 = dynamic_pointer_cast<SgTransformNode>(sphericalBodies_[s1]);
	shared_ptr<SgTransformNode> n2 = dynamic_pointer_cast<SgTransformNode>(sphericalBodies_[s2]);

	Cvec3 pos1 = getPathAccumRbt(rootNode_, n1).getTranslation();
	Cvec3 pos2 = getPathAccumRbt(rootNode_, n2).getTranslation();

	SphericalPhysicsBody *sphere1 = dynamic_cast<SphericalPhysicsBody *>(sphericalBodies_[s1]->getPhysicsBody());
	SphericalPhysicsBody *sphere2 = dynamic_cast<SphericalPhysicsBody *>(sphericalBodies_[s2]->getPhysicsBody());

	Cvec3 u1 = sphere1->getVelocity();
	Cvec3 u2 = sphere2->getVelocity();

	double m1 = sphere1->getMass();
	double m2 = sphere2->getMass();

	Cvec3 pos = pos1 - pos2;

	// if positions are too close, choose an arbitrary vector?
	Cvec3 k = Cvec3(1,0,0);

	if (dot(pos, pos) > ((1e-8) * (1e-8))) {
		k = pos.normalize();
	}

	double a = (dot((k * 2.0), (u1 - u2)) * m1 * m2) / (m1 + m2);

	Cvec3 v1 = u1 - (k * (a / m1));
	Cvec3 v2 = u2 + (k * (a / m2));
 
	sphere1->setVelocity(v1 * (1 - damping_));
	sphere2->setVelocity(v2 * (1 - damping_));
}
Пример #2
0
void PhysicsSim::updateSpherePlaneVelocities(int s, int p) {

	SphericalPhysicsBody *sphere = dynamic_cast<SphericalPhysicsBody *>(sphericalBodies_[s]->getPhysicsBody());
	
	PlanarPhysicsBody *plane = dynamic_cast<PlanarPhysicsBody *>(planarBodies_[p]->getPhysicsBody());
	shared_ptr<SgTransformNode> planeNode = dynamic_pointer_cast<SgTransformNode>(planarBodies_[p]);
	
	RigTForm planeRtf = getPathAccumRbt(rootNode_, planeNode);
	Cvec3 planeNormal = planeRtf.getRotation() * plane->getUnitNormal();
	Cvec3 velocity = sphere->getVelocity();
	planeNormal.normalize();
	Cvec3 velDiff = -(planeNormal * (2 * dot(velocity, planeNormal)));

	Cvec3 newVelocity = velocity + velDiff;
	newVelocity *= (1 - damping_);

	sphere->setVelocity(newVelocity);
}
Пример #3
0
static void updateMeshNormals(Mesh &mesh) {
  for (int i = 0, n = mesh.getNumVertices(); i < n; i++) {
    Cvec3 vectorSum = Cvec3(); 
    Mesh::Vertex v = mesh.getVertex(i);

    Mesh::VertexIterator vertexIter(v.getIterator()), iterOrigin(vertexIter);

    // walk around the vertex
    do {
      vectorSum += vertexIter.getFace().getNormal();
    } while (++vertexIter != iterOrigin);

    if (dot(vectorSum, vectorSum) > CS175_EPS2) {
      vectorSum.normalize();
    }
 
    v.setNormal(vectorSum);
  } 
}
Пример #4
0
static void motion(const int x, const int y) {
  const double dx = x - g_mouseClickX;
  const double dy = g_windowHeight - y - 1 - g_mouseClickY;
  const double scale = (g_object == 0 && g_view == 0 && g_skyFrame == 1) ? .01 : g_arcballScale;
  RigTForm m;
  // Allow translation and rotation when the object is not the sky camera, or if it is, allow it ony if the eye frame is also the sky camera.
  if (!(g_object == 0 && g_view != 0)) {
    if (g_mouseLClickButton && !g_mouseRClickButton) { // left button down?
      RigTForm mixedFrame;
      if (g_object != g_view || (g_object == g_view && g_view == 0 && g_skyFrame == 0)) {
        Cvec2 arcballCoord;
        if (g_object == 0) {
          arcballCoord = getScreenSpaceCoord((inv(g_viewRbt) * RigTForm(Cvec3(0, 0, 0))).getTranslation(), makeProjectionMatrix(), g_frustNear, g_frustFovY, g_windowWidth, g_windowHeight);
        }
        else {
          arcballCoord = getScreenSpaceCoord((inv(g_viewRbt) * g_objRbt).getTranslation(), makeProjectionMatrix(), g_frustNear, g_frustFovY, g_windowWidth, g_windowHeight);
        }
        double xCoord = x - arcballCoord[0];
        double yCoord = (g_windowHeight - y - 1) - arcballCoord[1];
        // x**2 + y**2 + z**2 = r**2
        double zSquared = g_arcballScreenRadius * g_arcballScreenRadius - xCoord * xCoord - yCoord * yCoord;
        Cvec3 sphereCoord;
        // Mouse is off of the arcball.  Trackball movement.
        if (zSquared < 0) {
          //sphereCoord == v2
          sphereCoord = Cvec3(xCoord, yCoord, 0);
        }
        else {
          //sphereCoord == v3
          sphereCoord = Cvec3(xCoord, yCoord, sqrt(zSquared));
        }
        sphereCoord.normalize();
        if (g_v1[0] != 0 || g_v1[1] != 0 || g_v1[2] != 0) {
          // [0 sphereCoord][0 -v1]
          m = RigTForm(Quat(0, sphereCoord[0], sphereCoord[1], sphereCoord[2]) * Quat(0, -g_v1[0], -g_v1[1], -g_v1[2]));
        }
        if (g_object == 0 && zSquared >= 0) {
          m = inv(m);
        }
        if (g_object == 0) {
          mixedFrame = RigTForm(Cvec3(0, 0, 0)) * linFact(g_viewRbt);
//          m = mixedFrame * m * inv(mixedFrame);
        }
        else {
          mixedFrame = transFact(g_objRbt) * linFact(g_viewRbt);
//          m = mixedFrame * m * inv(mixedFrame);
        }
//        g_objRbt = m * transFact(g_objRbt) * linFact(g_objRbt);
        g_v1 = sphereCoord;
      }
      // Arcball is not used.
      else {
        m = RigTForm(Quat::makeXRotation(-dy) * Quat::makeYRotation(dx));
        if (g_object == g_view) {
          m = inv(m);
        }
        // Take M to O w.r.t mixedFrame
        mixedFrame = transFact(g_objRbt) * linFact(g_viewRbt);
//        m = mixedFrame * m * inv(mixedFrame);
//        g_objRbt = m * transFact(g_objRbt) * linFact(g_objRbt);
      }
      m = mixedFrame * m * inv(mixedFrame);
      g_objRbt = m * transFact(g_objRbt) * linFact(g_objRbt);
    }
    else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?
      m = RigTForm(Cvec3(dx,dy,0) * scale);
      if (g_skyFrame == 0 && g_object == 0) {
        m = inv(m);
      }
      // Take M to O w.r.t E
      m = g_viewRbt * m * inv(g_viewRbt);
      g_objRbt = transFact(g_objRbt) * m * linFact(g_objRbt);
    }
    else if (g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton)) {  // middle or (left and right) button down?
      m = RigTForm(Cvec3(0,0,-dy) * scale);
      if (g_skyFrame == 0 && g_object == 0) {
        m = inv(m);
      }
      // Take M to O w.r.t E
      m = g_viewRbt * m * inv(g_viewRbt);
      g_objRbt = transFact(g_objRbt) * m * linFact(g_objRbt);
    }
  }

  if (g_mouseClickDown) {
    if (g_object == 0) {
      g_skyRbt = g_objRbt;
    }
    else if (g_object == 1) {
      g_objectRbt[0] = g_objRbt;
    }
    else {
      g_objectRbt[1] = g_objRbt;
    }
    glutPostRedisplay(); // we always redraw if we changed the scene
  }

  g_mouseClickX = x;
  g_mouseClickY = g_windowHeight - y - 1;
}