/** Two slanted green ramps. */ void Demo::insertRamps() { { Box b(Vector3(-1, 0, -5), Vector3(1, .25f, 5.5f)); CoordinateFrame c; c.lookAt(Vector3(0, 1, 2)); c.translation = Vector3(-2.5f, 2.25f, 5.5f); scene.insertStatic(new BoxObject(c.toWorldSpace(b), (Color3::green() + Color3::white()) / 2)); } // Corner ramp { Box b(Vector3(-1, 0, -5), Vector3(1, .25f, 5.5f)); CoordinateFrame c; c.lookAt(Vector3(-2, 2, -2)); c.translation = Vector3(-11.2f, 2.85f, -7.2f); scene.insertStatic(new BoxObject(c.toWorldSpace(b), (Color3::green() + Color3::white()) / 2)); } }
void Demo::insertSpiralSlide() { int i; for (i = 0; i < 41; ++i) { double angle = pi() * i / 10.0; double angle2 = pi() * (i - 0.6) / 10.0; // Outer spiral CoordinateFrame c; Box b(Vector3(-1, -1, -.1f), Vector3(1, 1, .1f)); c.translation = Vector3(cos(angle) * 2.9f, i / 3.5f + 1.5f, sin(angle) * 2.9f); c.lookAt(Vector3(cos(angle2) * 1.5f, i / 3.5 + 2.2f, sin(angle2) * 1.5f)); scene.insertStatic(new BoxObject(c.toWorldSpace(b), (Color3::yellow() + Color3::white()) / 2)); // Inner inner spiral { Box b(Vector3(-.3f, -.3f, -.1f), Vector3(.25f, .25f, .1f)); c.translation = Vector3(cos(angle) * 1.2f, i / 3.5f + 1, sin(angle) * 1.2f); c.lookAt(Vector3(cos(angle2) * 3, i / 3.5f + 2, sin(angle2) * 3)); scene.insertStatic(new BoxObject(c.toWorldSpace(b), (Color3::yellow() + Color3::white()) / 2)); } } scene.insertDynamic(new SimSphere(Sphere(Vector3(1.9f, 13, -1), .75f), Vector3(-2,-.5f,-2), Color3::blue())); }
void VisibleEntity::onPose(Array<shared_ptr<Surface> >& surfaceArray) { // We have to pose in order to compute bounds that are used for selection in the editor // and collisions in simulation, so pose anyway if not visible, // but then roll back. debugAssert(isFinite(m_frame.translation.x)); debugAssert(! isNaN(m_frame.rotation[0][0])); const int oldLen = surfaceArray.size(); const bool boundsChangedSincePreviousFrame = poseModel(surfaceArray); // Compute bounds for objects that moved if (m_lastAABoxBounds.isEmpty() || boundsChangedSincePreviousFrame || (m_lastChangeTime > m_lastBoundsTime)) { m_lastSphereBounds = Sphere(m_frame.translation, 0); const CFrame& myFrameInverse = frame().inverse(); m_lastObjectSpaceAABoxBounds = AABox::empty(); m_lastBoxBoundArray.fastClear(); // Look at all surfaces produced for (int i = oldLen; i < surfaceArray.size(); ++i) { AABox b; Sphere s; const shared_ptr<Surface>& surf = surfaceArray[i]; // body to world transformation for the surface CoordinateFrame cframe; surf->getCoordinateFrame(cframe, false); debugAssertM(cframe.translation.x == cframe.translation.x, "NaN translation"); surf->getObjectSpaceBoundingSphere(s); s = cframe.toWorldSpace(s); m_lastSphereBounds.radius = max(m_lastSphereBounds.radius, (s.center - m_lastSphereBounds.center).length() + s.radius); // Take the entity's frame out of consideration, so that we get tight AA bounds // in the Entity's frame CFrame osFrame = myFrameInverse * cframe; surf->getObjectSpaceBoundingBox(b); m_lastBoxBoundArray.append(cframe.toWorldSpace(b)); const Box& temp = osFrame.toWorldSpace(b); m_lastObjectSpaceAABoxBounds.merge(temp); } // Box can't represent an empty box, so we make empty boxes into real boxes with zero volume here if (m_lastObjectSpaceAABoxBounds.isEmpty()) { m_lastObjectSpaceAABoxBounds = AABox(Point3::zero()); m_lastAABoxBounds = AABox(frame().translation); } m_lastBoxBounds = frame().toWorldSpace(m_lastObjectSpaceAABoxBounds); m_lastBoxBounds.getBounds(m_lastAABoxBounds); m_lastBoundsTime = System::time(); } if (! m_visible) { // Discard my surfaces if I'm invisible; they were only needed for bounds surfaceArray.resize(oldLen, false); } }