// // Util.cpp // interface/src // // Created by Philip Rosedale on 8/24/12. // Copyright 2012 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include #include #include #include #include #include #include #include #include #include #include "InterfaceConfig.h" #include "ui/TextRenderer.h" #include "VoxelConstants.h" #include "world.h" #include "Application.h" #include "Util.h" using namespace std; // no clue which versions are affected... #define WORKAROUND_BROKEN_GLUT_STROKES // see http://www.opengl.org/resources/libraries/glut/spec3/node78.html void renderWorldBox() { // Show edge of world float red[] = {1, 0, 0}; float green[] = {0, 1, 0}; float blue[] = {0, 0, 1}; float gray[] = {0.5, 0.5, 0.5}; glDisable(GL_LIGHTING); glLineWidth(1.0); glBegin(GL_LINES); glColor3fv(red); glVertex3f(0, 0, 0); glVertex3f(TREE_SCALE, 0, 0); glColor3fv(green); glVertex3f(0, 0, 0); glVertex3f(0, TREE_SCALE, 0); glColor3fv(blue); glVertex3f(0, 0, 0); glVertex3f(0, 0, TREE_SCALE); glColor3fv(gray); glVertex3f(0, 0, TREE_SCALE); glVertex3f(TREE_SCALE, 0, TREE_SCALE); glVertex3f(TREE_SCALE, 0, TREE_SCALE); glVertex3f(TREE_SCALE, 0, 0); glEnd(); // Draw meter markers along the 3 axis to help with measuring things const float MARKER_DISTANCE = 1.f; const float MARKER_RADIUS = 0.05f; glEnable(GL_LIGHTING); glPushMatrix(); glTranslatef(MARKER_DISTANCE, 0, 0); glColor3fv(red); Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, MARKER_DISTANCE, 0); glColor3fv(green); Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, MARKER_DISTANCE); glColor3fv(blue); Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glColor3fv(gray); glTranslatef(MARKER_DISTANCE, 0, MARKER_DISTANCE); Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); } // Return a random vector of average length 1 const glm::vec3 randVector() { return glm::vec3(randFloat() - 0.5f, randFloat() - 0.5f, randFloat() - 0.5f) * 2.f; } static TextRenderer* textRenderer(int mono) { static TextRenderer* monoRenderer = TextRenderer::getInstance(MONO_FONT_FAMILY); static TextRenderer* proportionalRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT); static TextRenderer* inconsolataRenderer = TextRenderer::getInstance(INCONSOLATA_FONT_FAMILY, -1, QFont::Bold, false); switch (mono) { case 1: return monoRenderer; case 2: return inconsolataRenderer; case 0: default: return proportionalRenderer; } } int widthText(float scale, int mono, char const* string) { return textRenderer(mono)->computeWidth(string) * (scale / 0.10); } void drawText(int x, int y, float scale, float radians, int mono, char const* string, const float* color) { // // Draws text on screen as stroked so it can be resized // glPushMatrix(); glTranslatef(static_cast(x), static_cast(y), 0.0f); glColor3fv(color); glRotated(double(radians * DEGREES_PER_RADIAN), 0.0, 0.0, 1.0); glScalef(scale / 0.1f, scale / 0.1f, 1.f); textRenderer(mono)->draw(0, 0, string); glPopMatrix(); } void renderCollisionOverlay(int width, int height, float magnitude, float red, float blue, float green) { const float MIN_VISIBLE_COLLISION = 0.01f; if (magnitude > MIN_VISIBLE_COLLISION) { glColor4f(red, blue, green, magnitude); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2d(width, 0); glVertex2d(width, height); glVertex2d(0, height); glEnd(); } } void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides) { glm::vec3 perp1 = glm::vec3(surfaceNormal.y, surfaceNormal.z, surfaceNormal.x); glm::vec3 perp2 = glm::vec3(surfaceNormal.z, surfaceNormal.x, surfaceNormal.y); glBegin(GL_LINE_STRIP); for (int i=0; ivalue(name, defaultValue).toFloat(); if (glm::isnan(value)) { value = defaultValue; } return value; } bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection, const glm::vec3& sphereCenter, float sphereRadius, float& distance) { glm::vec3 relativeOrigin = rayStarting - sphereCenter; // compute the b, c terms of the quadratic equation (a is dot(direction, direction), which is one) float b = 2.0f * glm::dot(rayNormalizedDirection, relativeOrigin); float c = glm::dot(relativeOrigin, relativeOrigin) - sphereRadius * sphereRadius; // compute the radicand of the quadratic. if less than zero, there's no intersection float radicand = b * b - 4.0f * c; if (radicand < 0.0f) { return false; } // compute the first solution of the quadratic float root = sqrtf(radicand); float firstSolution = -b - root; if (firstSolution > 0.0f) { distance = firstSolution / 2.0f; return true; // origin is outside the sphere } // now try the second solution float secondSolution = -b + root; if (secondSolution > 0.0f) { distance = 0.0f; return true; // origin is inside the sphere } return false; } bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius) { glm::vec3 diff = point - sphereCenter; double mag = sqrt(glm::dot(diff, diff)); if (mag <= sphereRadius) { return true; } return false; }