void testApp::generateVBOs() { // If the meshes have already been generated once, we need to clear their data vboMeshOriginal.clear(); vboMeshMirrored.clear(); // Shorthand to make the equations more readable // r is the radius of a circle that is inscribed by the display window // a is the current angle heading we will use to sample the image // da is half the span of the triangle float r = minWindowDimension/2.0; float a = ofDegToRad(imageSectionHeading); float da = ofDegToRad(triangleAngularWidth/2); // Define the vertices of the triangular face ofVec3f triangleBottom(0, 0, 0); ofVec3f triangleLeft(r*cos(a+da), -r*sin(a+da), 0); // Flip because of drawing ofVec3f triangleRight(r*cos(a-da), -r*sin(a-da), 0); // Flip because of drawing float cx = imageSectionCenter.x; float cy = imageSectionCenter.y; r = minImageDimension/2.0; // Define the triangular section of the image that we want to draw on the face ofVec2f textureBottom(cx, cy); ofVec2f textureLeft(cx+r*cos(a+da), cy-r*sin(a+da)); ofVec2f textureRight(cx+r*cos(a-da), cy-r*sin(a-da)); // Add the vertices to the VBO mesh to form a triangle addFace(vboMeshOriginal, triangleBottom, triangleLeft, triangleRight); addFace(vboMeshMirrored, triangleBottom, triangleLeft, triangleRight); // Add the texture coordinates to the mesh addTexture(vboMeshOriginal, textureBottom, textureLeft, textureRight); addTexture(vboMeshMirrored, textureBottom, textureRight, textureLeft); }
void UltraEyeRenderer::drawHenshinInstruction() { XuSkeletonJointInfo jrh, jh, jre; m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_RIGHT_HAND, &jrh); m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_HEAD, &jh); m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_RIGHT_ELBOW, &jre); if (!isConfident(jrh) || !isConfident(jh) || !isConfident(jre)) return; const float CIRCLE_RADIUS = 100; XV3 fv(m_henshinDetector->getUserDetector()->getForwardVector()); XV3 uv(m_henshinDetector->getUserDetector()->getUpVector()); XV3 armDirection((jrh.position - jre.position).normalize()); XV3 adjustedRightHand(jrh.position + armDirection * 30); // slightly move to the fingertip side XV3 adjustedHead(jh.position + fv * 100); // slightly move forward XV3 arrowTip(adjustedRightHand.interpolate(adjustedHead, 0.95f)); XV3 arrowBottom(adjustedRightHand.interpolate(adjustedHead, 0.0f)); float len = (arrowTip - arrowBottom).magnitude(); XV3 triangleBottom(arrowBottom.interpolate(arrowTip, 0.8f)); XV3 triangleOpening = (arrowTip - arrowBottom).cross(armDirection).normalize() * len * 0.1f; XV3 arrowPlaneNorm = (arrowTip - arrowBottom).cross(triangleOpening).normalize(); XV3 triangleEnd1(triangleBottom + triangleOpening); XV3 triangleEnd2(triangleBottom - triangleOpening); float maxAlpha = cramp((len - 50.0f) / 150.0f, 0, 1); float blinkSpeed = 1000.0f / std::max(len - 100.0f, 100.f); m_phase += m_ticker.tick() * blinkSpeed; float alpha = square(std::sin(m_phase)) * maxAlpha; M3DVector4f arrowColor = { 0.7f, 0.0f, 0.0f, alpha }; m_rctx->shaderMan->UseStockShader(GLT_SHADER_FLAT, m_rctx->transform.GetModelViewProjectionMatrix(), arrowColor); const float THICKNESS = 2; glDisable(GL_DEPTH_TEST); glLineWidth(getPointSize() * THICKNESS); glPointSize(getPointSize() * THICKNESS); glBegin(GL_LINES); if (len > CIRCLE_RADIUS) { glVertex3fv(XV3toM3D(arrowBottom + (arrowTip - arrowBottom).normalize() * CIRCLE_RADIUS)); glVertex3fv(XV3toM3D(arrowTip)); } glVertex3fv(XV3toM3D(arrowTip)); glVertex3fv(XV3toM3D(triangleEnd1)); glVertex3fv(XV3toM3D(arrowTip)); glVertex3fv(XV3toM3D(triangleEnd2)); glEnd(); glBegin(GL_LINE_LOOP); XV3 r0((arrowTip - arrowBottom).normalize() * CIRCLE_RADIUS); GLFrame f; f.SetForwardVector(0, 0, 1); // invert Z const int SEGMENTS = 24; const float STEP_ANGLE = float(M_PI * 2 / SEGMENTS); for (int i = 0; i < SEGMENTS; i++) { f.RotateLocal(STEP_ANGLE, arrowPlaneNorm.X, arrowPlaneNorm.Y, arrowPlaneNorm.Z); M3DVector3f r; f.TransformPoint(XV3toM3D(r0), r); glVertex3fv(XV3toM3D(arrowBottom + r)); } glEnd(); if (m_isNewUser) { XV3 p(-0.95f, 0.80f, 0.0f), s(0.001f, 0.0015f, 1.0f); renderStrokeText(m_rctx, "Put your Ultra Eye On! Now!", p, s, 3.0f, arrowColor); } glEnable(GL_DEPTH_TEST); }