void CellularAutomata::handleMouse(bool isPressed, bool isDown, const Ray & mouseRay, const Vector2 & mousePos) { m_transientPlayhead.position = Vector2int16(-5, -5); if (m_paused) { Point2int16 selectedPosition(-1,-1); for (int x = 0; x < m_width; ++x) { for (int y = 0; y < m_height; ++y) { Vector2 normalizedCoord = Vector2(x,y) * Vector2(1.0f / (m_width - 1.0f), 1.0f / (m_height - 1.0f)); const Point3& p = normCoordTo3DPoint(normalizedCoord); if (intersects(mouseRay, p, collisionRadius())) { selectedPosition = Vector2int16(x, y); } } } if (selectedPosition.x >= 0) { m_transientPlayhead.position = selectedPosition; m_transientPlayhead.direction = Direction::DOWN; // Super hackish way to select the direction to point in based on mouse position // from the center (should work on in either mode, but only tested on 2D) // This is the first thing due for a cleanup float minDistance = 10.0f; // Basically infinity... Vector2 normalizedCoord = Vector2(selectedPosition) * Vector2(1.0f / (m_width - 1.0f), 1.0f / (m_height - 1.0f)); const Point3& center = normCoordTo3DPoint(normalizedCoord); float t = mouseRay.intersectionTime(Sphere(center, collisionRadius())); Point3 intersectionPoint = mouseRay.origin() + mouseRay.direction() * t; for (int i = 0; i < 4; ++i) { Vector2 npos = normalizedCoord + Vector2(vecFromDir(Direction(i)))*0.001f; const Point3& p = normCoordTo3DPoint(npos); if ((intersectionPoint - p).length() < minDistance) { minDistance = (intersectionPoint - p).length(); m_transientPlayhead.direction = Direction(i); } } if (isPressed) { bool removed = false; for (int i = m_playhead.size() - 1; i >= 0; --i) { if (selectedPosition == m_playhead[i].position) { m_playhead.remove(i); removed = true; break; } } if (!removed) { m_playhead.append(m_transientPlayhead); } } } } }
// // Behavior orientForOrbitBehavior(target, dist) // Last modified: 07Nov2009 // // Orients the robot with respect to the parameterized target // such that if the robot were moving forward, it would move // in a circular path maintaining the parameterized distance // around the target, returning the appropriate robot behavior. // // Returns: the appropriate robot behavior // Parameters: // target in/out the target to orient to for orbit // dist in the distance to maintain from the target // Behavior Robot::orientForOrbitBehavior(const Vector &target, const GLfloat dist) { GLfloat r = target.magnitude(), dir = 0.0f; if (r > dist + collisionRadius()) dir = 0.0f; else if (r < dist - collisionRadius()) dir = 180.0f; else dir = 180.0f - r * 90.0f / collisionRadius(); return orientToBehavior(target, dir); } // orientForOrbitBehavior(const Vector &, const GLfloat)
// // void step() // Last modified: 27Dec2010 // // Executes the appropriate active behavior. // // Returns: <none> // Parameters: <none> // void Robot::step() { GLfloat collDist = collisionRadius(); vector<Vector> rels = getObjectRelationships(collDist); if (rels.size() > 0) { GLfloat minDist = HUGE; GLint minIndex = 0; for (GLint i = 0, n = rels.size(); i < n; ++i) { GLfloat currDist = rels[i].magnitude(); if (currDist < minDist) { minDist = currDist; minIndex = i; } } //avoid(rels[minIndex], collDist); } if (behavior.isActive()) { translateRelative(getTransVel()); rotateRelative(getAngVel()); } } // step()
// // void draw() // Last modified: 27Aug2006 // // Renders the robot as a circle with a vector heading. // // Returns: <none> // Parameters: <none> // void Robot::draw() { if ((color[GLUT_RED] == COLOR[INVISIBLE][GLUT_RED]) && (color[GLUT_GREEN] == COLOR[INVISIBLE][GLUT_GREEN]) && (color[GLUT_BLUE] == COLOR[INVISIBLE][GLUT_BLUE])) return; vector<Vector> rels = getObjectRelationships(2.0f * collisionRadius()); for (GLint i = 0, n = rels.size(); i < n; ++i) { rels[i].rotated(rotate[2]); rels[i].translated(x, y, z); rels[i].scaled(scale[0]); rels[i].draw(); } // draw a circle representing the robot Circle::draw(); // draw a vector representing the robot heading if (showHeading) { glPushMatrix(); glRotated(rotate[0], 0, 0, 1); glRotated(rotate[1], 0, 0, 1); glRotated(rotate[2], 0, 0, 1); heading.translated(x + translate[0], y + translate[1], z + translate[2]); heading.scaled(radius / DEFAULT_ROBOT_RADIUS); heading.setColor(color); heading.draw(); glPopMatrix(); } } // draw()
bool Camera::collides(const Entity &e) { // return false; float cam_rad = collisionRadius(); if (e.useBoundingBox()) { // return true; BoundingBox bb = e.getBoundingBox(); bb.box.min += e.getPosition(); bb.box.max += e.getPosition(); Eigen::Vector3f our_pos = -translations; if (bb.contains(our_pos)) { return true; } Eigen::Vector3f displacement = (bb.box.center() - our_pos); float distance = displacement.norm(); Eigen::Vector3f direction = displacement.normalized(); if (bb.contains(direction * cam_rad + our_pos)) { return true; } return false; } else { Eigen::Vector3f their_pos = e.getCenterWorld(); Eigen::Vector3f our_pos = translations; their_pos(1) = 0; our_pos(1) = 0; Eigen::Vector3f delta = -their_pos - our_pos; return std::abs(delta.norm()) < cam_rad + e.getRadius(); } /* std::cout << "object pos" << std::endl; std::cout << their_pos << std::endl; std::cout << "cam pos" << std::endl; std::cout << our_pos << std::endl; std::cout << " dist = " << std::abs(delta.norm()) << std::endl; */ }