/** Constructs an antipenumbra from a source portal to a target portal. For each antipenumbral plane p (except the source plane), it is guaranteed to be the case that: - classify_polygon_against_plane(*source, p) == CP_BACK - classify_polygon_against_plane(*target, p) == CP_FRONT @param source The source portal @param target The target portal */ Antipenumbra::Antipenumbra(const Portal_Ptr& source, const Portal_Ptr& target) { m_planes.push_back(make_plane(*source)); // Note: In both cases here, source lies behind the generated planes and target lies in front of them. add_clip_planes(source, target, CP_BACK); // add planes from source to target, with source behind them add_clip_planes(target, source, CP_FRONT); // add planes from target to source, with target in front of them }
ENTRYPOINT void init_hexstrut (ModeInfo *mi) { hexstrut_configuration *bp; MI_INIT (mi, bps, free_hexstrut); bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_hexstrut (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); { double spin_speed = 0.002; double wander_speed = 0.003; double spin_accel = 1.0; bp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, spin_accel, do_wander ? wander_speed : 0, False); bp->trackball = gltrackball_init (True); } /* Let's tilt the scene a little. */ gltrackball_reset (bp->trackball, -0.4 + frand(0.8), -0.4 + frand(0.8)); if (thickness < 0.05) thickness = 0.05; if (thickness < 0.05) MI_IS_WIREFRAME(mi) = True; if (thickness > 1.7) thickness = 1.7; if (speed > 2) speed = 2; bp->ncolors = 64; bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor)); make_smooth_colormap (0, 0, 0, bp->colors, &bp->ncolors, False, 0, False); make_plane (mi); }
/** Create a list of surfaces. */ list356_t* get_surfaces() { list356_t* surfaces = make_list() ; // Table. point3_t vertices[8] = { {0, 0, 1}, {8, 0, 1}, {0, 8, 1}, {8, 8, 1}, {0, 0, -1}, {8, 0, -1}, {0, 8, -1}, {8, 8, -1}, } ; int indices[] = { 0, 1, 3, 0, 3, 2, // top 0, 2, 6, 0, 6, 4, // left 4, 6, 7, 4, 7, 5, // bottom 1, 5, 7, 1, 7, 3, // right 2, 3, 7, 2, 7, 6, // back 0, 4, 5, 0, 5, 1 // front } ; int top_offset = 6 ; int offset = 36 ; list356_t* table_surfaces = make_list() ; for (int i=0; i<top_offset/3; ++i) { lst_add(table_surfaces, make_triangle( vertices[indices[3*i]], vertices[indices[3*i+1]], vertices[indices[3*i+2]], &RED, &RED, &WHITE, 10.0f)) ; } for (int i=top_offset/3; i<offset/3; ++i) { lst_add(table_surfaces, make_triangle( vertices[indices[3*i]], vertices[indices[3*i+1]], vertices[indices[3*i+2]], &GREEN, &GREEN, &WHITE, 10.0f)) ; } // Two purple spheres. lst_add(table_surfaces, make_sphere(6, 6, 1.75+.01, .75, &PURPLE, &PURPLE, &WHITE, 100.0f)) ; lst_add(table_surfaces, make_sphere(5, 2, 1.75+.01, .75, &PURPLE, &PURPLE, &WHITE, 100.0f)) ; // Transparent cube. point3_t cube_vertices[] = { {4, 0, 3}, {5, 0, 3}, {4, 1, 3}, {5, 1, 3}, {4, 0, 1.01}, {5, 0, 1.01}, {4, 1, 1.01}, {5, 1, 1.01}, } ; for (int i=0; i<offset/3; ++i) { surface_t* t = make_triangle( cube_vertices[indices[3*i]], cube_vertices[indices[3*i+1]], cube_vertices[indices[3*i+2]], &BLACK, &BLACK, &WHITE, 10.0f) ; t->refr_index = 1.1f ; t->atten = &GREENISH ; lst_add(surfaces, t) ; } list356_itr_t* itr = lst_iterator(table_surfaces) ; while (lst_has_next(itr)) lst_add(surfaces, lst_next(itr)) ; lst_free(table_surfaces) ; // Plane at z=-1. surface_t* plane = make_plane( (point3_t){0, 0, -1}, (point3_t){1, 0, -1}, (point3_t){1, 1, -1}, &LIGHT_GREY, &LIGHT_GREY, &BLACK, 10.0f) ; plane->refl_color = &LIGHT_GREY ; lst_add(surfaces, plane) ; return surfaces ; }
/*! Draws a fog plane at the far clipping plane to mask out clipping of terrain. \return none \author jfpatry \date Created: 2000-08-31 \date Modified: 2000-08-31 */ void draw_fog_plane() { plane_t left_edge_plane, right_edge_plane; plane_t left_clip_plane, right_clip_plane; plane_t far_clip_plane; plane_t bottom_clip_plane; plane_t bottom_plane, top_plane; scalar_t course_width, course_length; scalar_t course_angle, slope; point_t left_pt, right_pt, pt; point_t top_left_pt, top_right_pt; point_t bottom_left_pt, bottom_right_pt; vector_t left_vec, right_vec; scalar_t height; GLfloat *fog_colour; if ( is_fog_on() == False ) { return; } set_gl_options( FOG_PLANE ); get_course_dimensions( &course_width, &course_length ); course_angle = get_course_angle(); slope = tan( ANGLES_TO_RADIANS( course_angle ) ); left_edge_plane = make_plane( 1.0, 0.0, 0.0, 0.0 ); right_edge_plane = make_plane( -1.0, 0.0, 0.0, course_width ); far_clip_plane = get_far_clip_plane(); left_clip_plane = get_left_clip_plane(); right_clip_plane = get_right_clip_plane(); bottom_clip_plane = get_bottom_clip_plane(); /* Find the bottom plane */ bottom_plane.nml = make_vector( 0.0, 1, -slope ); height = get_terrain_base_height( 0 ); /* Unoptimized version pt = make_point( 0, height, 0 ); bottom_plane.d = -( pt.x * bottom_plane.nml.x + pt.y * bottom_plane.nml.y + pt.z * bottom_plane.nml.z ); */ bottom_plane.d = -height * bottom_plane.nml.y; /* Find the top plane */ top_plane.nml = bottom_plane.nml; height = get_terrain_max_height( 0 ); top_plane.d = -height * top_plane.nml.y; if(get_player_data(local_player())->view.mode == TUXEYE) { bottom_clip_plane.nml = make_vector( 0.0, 1, -slope ); height = get_terrain_base_height( 0 ) - 40; bottom_clip_plane.d = -height * bottom_clip_plane.nml.y; } /* Now find the bottom left and right points of the fog plane */ if ( !intersect_planes( bottom_plane, far_clip_plane, left_clip_plane, &left_pt ) ) return; if ( !intersect_planes( bottom_plane, far_clip_plane, right_clip_plane, &right_pt ) ) return; if ( !intersect_planes( top_plane, far_clip_plane, left_clip_plane, &top_left_pt ) ) return; if ( !intersect_planes( top_plane, far_clip_plane, right_clip_plane, &top_right_pt ) ) return; if ( !intersect_planes( bottom_clip_plane, far_clip_plane, left_clip_plane, &bottom_left_pt ) ) return; if ( !intersect_planes( bottom_clip_plane, far_clip_plane, right_clip_plane, &bottom_right_pt ) ) return; left_vec = subtract_points( top_left_pt, left_pt ); right_vec = subtract_points( top_right_pt, right_pt ); /* Now draw the fog plane */ set_gl_options( FOG_PLANE ); fog_colour = get_fog_colour(); glColor4fv( fog_colour ); #ifdef __APPLE__DISABLED__ #undef glEnableClientState #undef glDisableClientState #undef glVertexPointer #undef glColorPointer #undef glDrawArrays point_t pt1,pt2,pt3,pt4; pt1 = move_point( top_left_pt, left_vec ); pt2 = move_point( top_right_pt, right_vec ); pt3 = move_point( top_left_pt, scale_vector( 3.0, left_vec ) ); pt4 = move_point( top_right_pt, scale_vector( 3.0, right_vec ) ); const GLfloat verticesFog []= { bottom_left_pt.x, bottom_left_pt.y, bottom_left_pt.z, bottom_right_pt.x, bottom_right_pt.y, bottom_right_pt.z, left_pt.x, left_pt.y, left_pt.z, right_pt.x, right_pt.y, right_pt.z, top_left_pt.x, top_left_pt.y, top_left_pt.z, top_right_pt.x, top_right_pt.y, top_right_pt.z, pt1.x, pt1.y, pt1.z, pt2.x, pt2.y, pt2.z, pt3.x, pt3.y, pt3.z, pt4.x, pt4.y, pt4.z }; const GLfloat colorsFog []= { fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3], fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3], fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3], fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3], fog_colour[0], fog_colour[1], fog_colour[2], 0.9 , fog_colour[0], fog_colour[1], fog_colour[2], 0.9 , fog_colour[0], fog_colour[1], fog_colour[2], 0.3 , fog_colour[0], fog_colour[1], fog_colour[2], 0.3 , fog_colour[0], fog_colour[1], fog_colour[2], 0.0 , fog_colour[0], fog_colour[1], fog_colour[2], 0.0 , }; glEnableClientState (GL_VERTEX_ARRAY); // glEnableClientState (GL_COLOR_ARRAY); // glDisableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer (3, GL_FLOAT , 0, verticesFog); glColorPointer(4, GL_FLOAT, 0, colorsFog); glDrawArrays(GL_TRIANGLE_STRIP, 0, 10); //glDisableClientState(GL_COLOR_ARRAY_POINTER); #else glBegin( GL_QUAD_STRIP ); glVertex3f( bottom_left_pt.x, bottom_left_pt.y, bottom_left_pt.z ); glVertex3f( bottom_right_pt.x, bottom_right_pt.y, bottom_right_pt.z ); glVertex3f( left_pt.x, left_pt.y, left_pt.z ); glVertex3f( right_pt.x, right_pt.y, right_pt.z ); glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.9 ); glVertex3f( top_left_pt.x, top_left_pt.y, top_left_pt.z ); glVertex3f( top_right_pt.x, top_right_pt.y, top_right_pt.z ); glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.3 ); pt = move_point( top_left_pt, left_vec ); glVertex3f( pt.x, pt.y, pt.z ); pt = move_point( top_right_pt, right_vec ); glVertex3f( pt.x, pt.y, pt.z ); glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.0 ); pt = move_point( top_left_pt, scale_vector( 3.0, left_vec ) ); glVertex3f( pt.x, pt.y, pt.z ); pt = move_point( top_right_pt, scale_vector( 3.0, right_vec ) ); glVertex3f( pt.x, pt.y, pt.z ); glEnd(); #endif }
/** Determines which planes are necessary for building the expanded brush (including bevel planes). @param brush The initial brush @return The necessary brush planes */ BrushExpander::BrushPlaneSet_Ptr BrushExpander::determine_brush_planes(const ColPolyBrush_CPtr& brush) { BrushPlaneSet_Ptr brushPlanes(new BrushPlaneSet); // Add the planes of all the brush faces. const std::vector<CollisionPolygon_Ptr>& faces = brush->faces(); int faceCount = static_cast<int>(faces.size()); for(int i=0; i<faceCount; ++i) { ColPolyAuxData_Ptr auxData(new ColPolyAuxData(faces[i]->auxiliary_data())); brushPlanes->insert(BrushPlane(make_plane(*faces[i]), auxData)); } // Try and add bevel planes (any unnecessary ones will not be added to the set due to the unique plane predicate). // Add "axial planes going through an edge or corner of the brush that are not already part of the brush". const AABB3d& bounds = brush->bounds(); brushPlanes->insert(BrushPlane(Plane(Vector3d(-1,0,0), -bounds.minimum().x))); brushPlanes->insert(BrushPlane(Plane(Vector3d(0,-1,0), -bounds.minimum().y))); brushPlanes->insert(BrushPlane(Plane(Vector3d(0,0,-1), -bounds.minimum().z))); brushPlanes->insert(BrushPlane(Plane(Vector3d(1,0,0), bounds.maximum().x))); brushPlanes->insert(BrushPlane(Plane(Vector3d(0,1,0), bounds.maximum().y))); brushPlanes->insert(BrushPlane(Plane(Vector3d(0,0,1), bounds.maximum().z))); // Along edges, add "all planes that are parallel to one of the coordinate axes and do not change // the shape of the brush". for(int i=0; i<faceCount; ++i) { int vertCount = faces[i]->vertex_count(); for(int j=0; j<vertCount; ++j) { int k = (j+1)%vertCount; const Vector3d& p1 = faces[i]->vertex(j); const Vector3d& p2 = faces[i]->vertex(k); Plane_Ptr possiblePlanes[] = { make_axial_plane(p1, p2, Vector3d(1,0,0)), make_axial_plane(p1, p2, Vector3d(0,1,0)), make_axial_plane(p1, p2, Vector3d(0,0,1)) }; for(int m=0; m<3; ++m) { if(possiblePlanes[m]) { BrushPlane possiblePlane(*possiblePlanes[m]); BrushPlane flippedPossiblePlane(possiblePlanes[m]->flip()); // If this plane (or its flipped equivalent) isn't currently in the brush plane set. if( brushPlanes->find(possiblePlane) == brushPlanes->end() && brushPlanes->find(flippedPossiblePlane) == brushPlanes->end()) { // If the brush is entirely behind this plane, it's a valid // bevel plane, so add it. If the brush is entirely in front // of it, its inverse plane is a valid bevel plane, so add // that. Otherwise, carry on. switch(classify_brush_against_plane(brush, possiblePlane.plane)) { case CP_BACK: brushPlanes->insert(possiblePlane); break; case CP_FRONT: brushPlanes->insert(flippedPossiblePlane); break; default: break; } } } } } } return brushPlanes; }
ExperimentalApp() : GLFWApp(1280, 800, "Geometric Algorithm Development App") { glfwSwapInterval(0); igm.reset(new gui::ImGuiManager(window)); gui::make_dark_theme(); fixedTimer.start(); lights[0] = {{0, 10, -10}, {0, 0, 1}}; lights[1] = {{0, 10, 10}, {0, 1, 0}}; int width, height; glfwGetWindowSize(window, &width, &height); glViewport(0, 0, width, height); grid = RenderableGrid(1, 100, 100); cameraController.set_camera(&camera); camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0}); simpleShader = make_watched_shader(shaderMonitor, "../assets/shaders/simple_vert.glsl", "assets/shaders/simple_frag.glsl"); normalDebugShader = make_watched_shader(shaderMonitor, "../assets/shaders/normal_debug_vert.glsl", "assets/shaders/normal_debug_frag.glsl"); Renderable debugAxis = Renderable(make_axis(), false, GL_LINES); debugAxis.pose = Pose(float4(0, 0, 0, 1), float3(0, 1, 0)); debugModels.push_back(std::move(debugAxis)); // Initial supershape settings supershape = Renderable(make_supershape_3d(16, 5, 7, 4, 12)); supershape.pose.position = {0, 2, -2}; // Initialize PTF stuff { std::array<float3, 4> controlPoints = {float3(0.0f, 0.0f, 0.0f), float3(0.667f, 0.25f, 0.0f), float3(1.33f, 0.25f, 0.0f), float3(2.0f, 0.0f, 0.0f)}; ptf = make_parallel_transport_frame_bezier(controlPoints, 32); for (int i = 0; i < ptf.size(); ++i) { Renderable p = Renderable(make_cube()); ptfBoxes.push_back(std::move(p)); } } // Initialize Parabolic pointer stuff { // Set up the ground plane used as a nav mesh for the parabolic pointer worldSurface = make_plane(48, 48, 96, 96); for (auto & p : worldSurface.vertices) { float4x4 model = make_rotation_matrix({1, 0, 0}, -ANVIL_PI / 2); p = transform_coord(model, p); } worldSurfaceRenderable = Renderable(worldSurface); parabolicPointer = make_parabolic_pointer(worldSurface, params); } // Initialize objects for ballistic trajectory tests { turret.source = Renderable(make_tetrahedron()); turret.source.pose = Pose({-5, 2, 5}); turret.target = Renderable(make_cube()); turret.target.pose = Pose({0, 0, 40}); turret.bullet = Renderable(make_sphere(1.0f)); } float4x4 tMat = mul(make_translation_matrix({3, 4, 5}), make_rotation_matrix({0, 0, 1}, ANVIL_PI / 2)); auto p = make_pose_from_transform_matrix(tMat); std::cout << tMat << std::endl; std::cout << p << std::endl; gl_check_error(__FILE__, __LINE__); }
static plane make_plane(const vector& P0, const vector& P1, const vector& P2) { const auto N = maths::normalise(cross(P1 - P0, P2 - P0)); return make_plane(P0, N); }
plane(const vector& O, const vector& n) { *this = make_plane(O, n); }