int main(int argc, const char *argv[]) try { std::vector<RigidBody> rbs; for (auto const &b : bodysizes) { auto verts = genboxverts(b); auto tris = calchull(verts, 8); rbs.push_back(RigidBody({ Shape(verts, tris) }, float3(0, 0, 0))); } rbscalemass(&rbs[0], 5.0f); // make torso heavier than limb bones rbs[0].position.z = 1.0f; // lift a meter off the ground. DXWin mywin("Joint Drive - powered rag doll model", { 800,600 }); std::vector<Mesh> meshes; for (auto &rb : rbs) { meshes.push_back(MeshSmoothish(rb.shapes[0].verts, rb.shapes[0].tris)); // 1 shape each is known rb.damping = 0.8f; //rb.gravscale = 0; } for (auto &joint : joints) { rbs[joint.b0].ignore.push_back(&rbs[joint.b1]); rbs[joint.b1].ignore.push_back(&rbs[joint.b0]); rbs[joint.b1].position = rbs[joint.b0].pose() * joint.p0 - qrot(rbs[joint.b1].orientation,joint.p1); } WingMesh ground_wm = WingMeshBox({ -5, -5, -2.0f }, { 5, 5, -1.0f }); auto ground = MeshFlatShadeTex(ground_wm.verts, WingMeshTris(ground_wm)); ground.hack = { 0.25f, 0.75f, 0.25f, 1 }; Pose camera = { { 0, -8, 0 }, normalize(float4(0.9f, 0, 0, 1)) }; // where we view the rendered scene from. float time = 0; // our global clock, used to generate the circular animation for upper limbs to follow float torquelimit = 38.0f; // how much torque we let each joint apply each frame while (mywin.WindowUp()) { time += 0.06f; std::vector<LimitAngular> angulars; std::vector<LimitLinear> linears; for (auto const &joint : joints) { Append(linears, ConstrainPositionNailed(&rbs[joint.b0], joint.p0, &rbs[joint.b1], joint.p1)); Append(angulars, ConstrainAngularDrive(&rbs[joint.b0], &rbs[joint.b1], (float4(0, joint.a*cos(time), joint.a*sin(time), sqrt(1.0f - joint.a*joint.a))), torquelimit)); } PhysicsUpdate(Addresses<RigidBody>(rbs), linears, angulars, { &ground_wm.verts }); for (unsigned int i = 0; i < rbs.size(); i++) meshes[i].pose = rbs[i].pose(); mywin.RenderScene(camera, Append(Addresses(meshes), std::vector<Mesh*>({ &ground }))); } return 0; } catch (std::exception e) { MessageBoxA(GetActiveWindow(), e.what(), "FAIL", 0); return -1; }
int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,LPSTR lpszCmdLine, int nCmdShow) // int main(int argc, char *argv[]) { std::cout << "Test tracking\n"; WingMesh box = WingMeshBox({ 0.5, 0.25f, 0.1f }); // our "real world" object used to generate computer vision or depth data input Pose boxpose({ 0, 0, 2 }, normalize(float4( 0.2f, 0.3f, 0.4f, 1.0f ))); RigidBody trackmodel({ AsShape(box) }, { 0, -0.5, 2.25f }); // a tracking model based on the geometry of the real object we are tracking std::vector<RigidBody*> rigidbodies = { &trackmodel }; WingMesh world_slab = WingMeshBox({ -2, -2, -0.75f }, { 2, 2, -0.5f }); // just some ground plane world_geometry GLWin glwin("Tracking single object from depth samples."); InitTex(); glwin.ViewAngle = 60.0f; int2 mouseprev; int animating = 1; float view_dist = 7.0f, view_pitch=20.0f, view_yaw=0; int frame = 0; bool enable_tracking = 0; int sample_resolution = 30; float src_offset = -2.0f; glwin.keyboardfunc = [&](unsigned char key, int x, int y)->void { switch (std::tolower(key)) { case 't': case ' ': enable_tracking = !enable_tracking; break; case 'a': case 's': animating = 1 - animating; break; case '-': case '_': sample_resolution = std::max(sample_resolution - 1, 3); break; case '+': case '=': sample_resolution++; break; case 'q': case 27 : exit(0); break; // ESC case 'x': case 'o': src_offset += 0.5f * ((key == 'X') ? -1.0f : 1.0f); break; case 'r': for (auto &rb : rigidbodies) { rb->position = rb->position_start; rb->orientation = rb->orientation_start; rb->linear_momentum = float3(0, 0, 0); rb->angular_momentum = float3(0, 0, 0); } break; default: std::cout << "unassigned key (" << (int)key << "): '" << key << "'\n"; break; } }; while (glwin.WindowUp()) { frame+=animating; if (glwin.MouseState) // on mouse drag { view_yaw += (glwin.MouseX - mouseprev.x) * 0.3f; // poor man's trackball view_pitch += (glwin.MouseY - mouseprev.y) * 0.3f; } mouseprev = { glwin.MouseX, glwin.MouseY }; view_dist *= powf(1.1f, (float)glwin.mousewheel); boxpose.orientation = normalize(float4(sinf(frame*0.01f),sin(frame*0.035f),sin(frame*0.045f),1.0f)); // animate the source object boxpose.position = float3(sinf(frame*0.01f)*0.75f, cosf(frame*0.01f)*0.75f, boxpose.position.z); std::vector<float3> depthdata; // generated pointcloud for (float y = -1.0f; y <= 1.0f; y += 2.0f/sample_resolution) for (float x = -1.0f; x <= 1.0f; x += 2.0f/sample_resolution) { if (auto hit = ConvexHitCheck(box.faces, boxpose, { 0, 0, 0 }, float3(x, y, 1.0f)*5.0f)) depthdata.push_back(hit.impact); } std::vector<std::pair<float3,float3>> match; if (enable_tracking) { trackmodel.gravscale = 0; trackmodel.damping = 1; std::vector<float4> planesw; for (auto p : box.faces) // should be getting from shape, but oh well planesw.push_back(trackmodel.pose().TransformPlane(p)); std::vector<LimitAngular> angulars; std::vector<LimitLinear> linears; for (auto v : depthdata) { auto plane = planemostbelow(planesw, v); HitInfo hit; auto cp = v - plane.xyz()*dot(plane, float4(v, 1)); // cp is closest point on the plane match.push_back(std::pair<float3, float3>(v, cp)); if (dot(v, plane.xyz()) > 0 && (hit = ConvexHitCheck(planesw, { 0, 0, 0 }, v))) // closest plane is a backface and point is directly behind object linears.push_back(ConstrainAlongDirection(NULL, v, &trackmodel, trackmodel.pose().Inverse()*hit.impact, normalize(v), -50,50)); // push straight backwards else linears.push_back(ConstrainAlongDirection(NULL, v, &trackmodel, trackmodel.pose().Inverse()*cp, plane.xyz(), -50, 50)); } PhysicsUpdate(rigidbodies, linears, angulars, {}); } else { trackmodel.gravscale = 1; trackmodel.damping = 0.1f; PhysicsUpdate(rigidbodies, {}, std::vector<LimitAngular>(0), { &world_slab.verts }); } glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(0, 0, glwin.Width,glwin.Height); // Set up the viewport glClearColor(0.1f, 0.1f, 0.15f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // Set up matrices glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(glwin.ViewAngle, (double)glwin.Width/ glwin.Height, 0.01, 50); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); gluLookAt(0, -view_dist, 0, 0, 0, 0, 0, 0, 1); glRotatef(view_pitch, 1, 0, 0); glRotatef(view_yaw, 0, 0, 1); glDisable(GL_TEXTURE_2D); glColor3f(1.0f, 0.75f, 0.5f); glPushMatrix(); glTranslatef(src_offset, 0, 0); wmwire(box, boxpose); glPopMatrix(); glColor3f(1.0f, 1.0f, 0.0f); glPointSize(2.0f); glBegin(GL_POINTS); for (auto p : depthdata) glVertex3fv(p); glEnd(); glColor3f(0.7f, 0.0f, 0.0f); glPointSize(1.0f); glBegin(GL_LINES); for (auto p : match) glVertex3fv(p.first), glVertex3fv(p.second); // yeah, no braces {} but note the comma glEnd(); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1., 1. / (float)0x10000); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); wmdraw(world_slab); // world_geometry glEnable(GL_TEXTURE_2D); glColor3f(0.5f, 0.5f, 0.5f); for (auto &rb : rigidbodies) rbdraw(rb); glPopAttrib(); // Restore state glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glwin.PrintString({ 0, 0 },"ESC/q quits. SPACE to toggle tracking."); glwin.PrintString({ 0, 1 }, "(t)racking %s. (a)nimating %s. depthres %d", (enable_tracking) ? "ON" : "OFF", (animating) ? "ON" : "OFF", sample_resolution); glwin.SwapBuffers(); } std::cout << "\n"; return 0; }
int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,LPSTR lpszCmdLine, int nCmdShow) // int main(int argc, char *argv[]) { std::cout << "Test Physics\n"; std::vector<RigidBody*> rigidbodies; rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(1)) }, { 1.5f, 0.0f, 1.5f })); rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(1)) }, { -1.5f, 0.0f, 1.5f })); rigidbodies.back()->orientation = normalize(float4(0.1f, 0.01f, 0.3f, 1.0f)); auto seesaw = new RigidBody({ AsShape(WingMeshBox( { 3, 0.5f, 0.1f })) }, { 0, -2.5, 0.25f }); rigidbodies.push_back(seesaw); rigidbodies.push_back( new RigidBody({ AsShape(WingMeshCube(0.25f)) }, seesaw->position_start + float3( 2.5f, 0, 0.4f))); rigidbodies.push_back( new RigidBody({ AsShape(WingMeshCube(0.50f)) }, seesaw->position_start + float3(-2.5f, 0, 5.0f))); rbscalemass(rigidbodies.back(), 4.0f); rigidbodies.push_back(new RigidBody({ AsShape(WingMeshBox({1,0.2f,0.2f})),AsShape(WingMeshBox({0.2f,1,0.2f})),AsShape(WingMeshBox({0.2f,0.2f,1})) }, { -1.5f, 0.5f, 7.5f })); for (float z = 5.5f; z < 14.0f; z += 3.0f) rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.5f)) }, { 0.0f, 0.0f, z })); for (float z = 15.0f; z < 20.0f; z += 3.0f) rigidbodies.push_back(new RigidBody({ AsShape(WingMeshDual(WingMeshCube(0.5f), 0.65f)) }, { 2.0f, -1.0f, z })); WingMesh world_slab = WingMeshBox({ -10, -10, -5 }, { 10, 10, -2 }); // world_geometry GLWin glwin("TestPhys sample"); glwin.ViewAngle = 60.0f; glwin.keyboardfunc = [&](unsigned char key, int x, int y)->void { switch (std::tolower(key)) { case ' ': g_simulate = !g_simulate; break; case 'q': case 27: // ESC exit(0); break; case 'r': for (auto &rb : rigidbodies) { rb->position = rb->position_start; //rb->orientation = rb->orientation_start; // when commented out this provides some variation rb->linear_momentum = float3(0, 0, 0); rb->angular_momentum = float3(0, 0, 0); } seesaw->orientation = { 0, 0, 0, 1 }; break; default: std::cout << "unassigned key (" << (int)key << "): '" << key << "'\n"; break; } }; InitTex(); int2 mouseprev; while (glwin.WindowUp()) { if (glwin.MouseState) // on mouse drag { g_yaw += (glwin.MouseX - mouseprev.x) * 0.3f; // poor man's trackball g_pitch += (glwin.MouseY - mouseprev.y) * 0.3f; } mouseprev = { glwin.MouseX, glwin.MouseY }; if (g_simulate) { std::vector<LimitAngular> angulars; std::vector<LimitLinear> linears; Append(linears , ConstrainPositionNailed(NULL, seesaw->position_start, seesaw, { 0, 0, 0 })); Append(angulars, ConstrainAngularRange(NULL, seesaw, { 0, 0, 0, 1 }, { 0, -20, 0 }, { 0, 20, 0 })); PhysicsUpdate(rigidbodies, linears, angulars, { &world_slab.verts }); } glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(0, 0, glwin.Width,glwin.Height); // Set up the viewport glClearColor(0.1f, 0.1f, 0.15f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // Set up matrices glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(glwin.ViewAngle, (double)glwin.Width/ glwin.Height, 0.01, 50); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); gluLookAt(0, -8, 5, 0, 0, 0, 0, 0, 1); glRotatef(g_pitch, 1, 0, 0); glRotatef(g_yaw, 0, 0, 1); wmdraw(world_slab); // world_geometry glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1., 1. / (float)0x10000); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glColor3f(0.5f, 0.5f, 0.5f); for (auto &rb : rigidbodies) rbdraw(rb); glPopAttrib(); // Restore state glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glwin.PrintString("ESC/q quits. SPACE to simulate. r to restart", 5, 0); char buf[256]; sprintf_s(buf, "simulation %s", (g_simulate)?"ON":"OFF"); glwin.PrintString(buf, 5, 1); glwin.SwapBuffers(); } std::cout << "\n"; return 0; }
int main(int argc, char *argv[]) try { physics_driftmax = 0.0025f; GLWin glwin("point cloud push interaction"); RSCam dcam; dcam.Init((argc == 2) ? argv[1] : NULL); Image<unsigned short> dimage(dcam.dcamera()); glwin.ViewAngle = dcam.fov().y; float viewdist = 2.0f; float yaw = 120; int mousexold = 0; Mesh mesh; bool pause = false; bool debuglines=false; int center = 0; bool chains = true; bool usehull = false; std::vector<RigidBody*> rigidbodies; std::vector < std::pair<RigidBody*, RigidBody*>> links; for (float x = -0.2f; x < 0.2f; x+= 0.07f) for(float z: {0.350f}) for (float y = -0.2f; y <= 0.2f; y += 0.07f) { rigidbodies.push_back(new RigidBody({ AsShape(WingMeshDual(WingMeshCube(0.025f),0.028f)) }, { x,y,z })); //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.025f) ) }, { x,y,z })); links.push_back({(y > -0.2f)?rigidbodies[rigidbodies.size() - 2]:NULL , rigidbodies.back()}); } //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.05f)) }, { 0,0,0.50f })); auto seesaw = new RigidBody({ AsShape(WingMeshBox({ 0.20f, 0.015f, 0.05f })) }, { 0,0,0.45f }); rigidbodies.push_back(seesaw); glwin.keyboardfunc = [&](unsigned char key, int x, int y)->void { switch (std::tolower(key)) { case 'q': case 27: exit(0); break; // 27 is ESC case ' ': pause = !pause; break; case 'c': chains = !chains; break; case 'd': debuglines = !debuglines; break; case 'h': usehull = !usehull; break; case 'r': for (auto &rb : rigidbodies) { rb->angular_momentum = rb->linear_momentum = float3(0.0f);rb->pose() = { rb->position_start,rb->orientation_start }; } break; default: std::cout << "unassigned key (" << (int)key << "): '" << key << "'\n"; break; } }; if (dcam.dev->supports_option(rs::option::r200_lr_auto_exposure_enabled)) dcam.dev->set_option(rs::option::r200_lr_auto_exposure_enabled, 1); while (glwin.WindowUp()) { if (glwin.MouseState) { yaw += glwin.mousepos.x - mousexold; } mousexold = glwin.mousepos.x; viewdist *= powf(1.1f, (float)glwin.mousewheel); if (!pause) dimage = dcam.GetDepth(); glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(0, 0, glwin.res.x, glwin.res.y); glClearColor(0.1f, 0.1f, 0.15f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(glwin.ViewAngle, (double)glwin.aspect_ratio(), 0.01f, 50.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); gluLookAt(0, 0, viewdist, 0, 0, 0, 0, -1, 0); glEnable(GL_DEPTH_TEST); glTranslatef(0, 0, 0.35f); glRotatef(yaw, 0, 1, 0); glTranslatef(0, 0, -0.35f); std::vector<float3> pts; std::vector<float3> outliers; std::vector<float3> vpts; glDisable(GL_BLEND); float2 wrange = { 0.20f,0.60f }; auto dp_image_c = Transform(dimage, [](unsigned short s) {return byte3((unsigned char)clamp(255 - s / 4, 0, 255)); }); drawimage(dp_image_c, { 0.78f,0.22f }, { 0.2f,-0.2f }, 3); float depth_scale = (dcam.dev) ? dcam.dev->get_depth_scale() : 0.001f; // to put into meters // if file assume file is mm for (auto p : rect_iteration(dimage.dim())) // p is int2 from 0,0 to w,h of dcam { float d = dimage.pixel(p) * depth_scale; // d is in meters, whereas depth[i] is in camera units mm for R200, .125mm for SR300 ivycam if (p.x<5 || p.x> dimage.dim().x - 5 || p.y<5 || p.y>dimage.dim().y - 5) continue; // crop, seems to be lots of noise at the edges if (d > 1.0f) // just too far continue; float3 v = dimage.cam.deprojectz(asfloat2(p), d); if (d>wrange.x && d < wrange.y) pts.push_back(v); else outliers.push_back(v); } vpts = ObtainVoxelPointCloud(pts, 0.0082f, 8); std::vector<std::pair<float3, float3>> lines; std::vector<std::pair<float3, float3>> glines; if (1)// && pts.size()) { std::vector<LimitLinear> linears; std::vector<LimitAngular> angulars; physics_gravity = { 0, (float) chains,0 }; // ugg y is down if(!usehull) for(auto rb:rigidbodies) { if (!rb->shapes[0].planes.size()) rb->shapes[0].planes = Planes(rb->shapes[0].verts, rb->shapes[0].tris); auto planes = Transform(rb->shapes[0].planes, [&](float4 p) { return rb->pose().TransformPlane(p);}); rb->gravscale = (float)chains; float separation = FLT_MAX; float3 pushpoint = float3(0, 0, 0); // float4 pushplane; for (auto p : vpts) { auto plane = mostabove(planes, p); float sep; if ((sep = dot(plane, float4(p, 1))) < separation) { pushpoint = p; pushplane = plane; separation = sep; } } if (separation > 0.1f) continue; float3 closestpoint = ProjectOntoPlane(pushplane, pushpoint); pushplane = float4({ -pushplane.xyz(), -dot(-pushplane.xyz(),pushpoint) }); linears.push_back(ConstrainAlongDirection(NULL, pushpoint, rb, rb->pose().inverse()*closestpoint, pushplane.xyz(), 0, 100.0f)); // FLT_MAX)); lines.push_back({ closestpoint,pushpoint }); auto cp=Separated(rb->shapes[0].verts, rb->position, rb->orientation, { pushpoint }, { 0,0,0 }, { 0,0,0,1 }, 1); glines.push_back({ cp.p0w, cp.p1w }); } Append(linears, ConstrainPositionNailed(NULL, seesaw->position_start, seesaw, { 0, 0, 0 })); Append(angulars, ConstrainAngularRange(NULL, seesaw, { 0, 0, 0, 1 }, { 0, 0,-20 }, { 0, 0,20 })); if (chains) for (auto link : links) Append(linears, ConstrainPositionNailed(link.first,link.first? float3(0, 0.035f, 0) : link.second->position_start-float3(0, -0.035f, 0) , link.second, { 0,-0.035f,0 })); if(!pause) if(usehull && vpts.size()>5) PhysicsUpdate(rigidbodies, linears, angulars, { &vpts }); else PhysicsUpdate(rigidbodies, linears, angulars, std::vector<std::vector<float3>*>()); } glColor3f(1, 1, 1); glwirefrustumz(dcam.deprojectextents(), { 0.1f,1.0f }); // draw the camera frustum volume glPushAttrib(GL_ALL_ATTRIB_BITS); glPointSize(1); glBegin(GL_POINTS); glColor3f(0, 1, 0.5f); for (auto p : pts) glVertex3fv(p); glColor3f(1, 0.15f, 0.15f); for (auto p : outliers) glVertex3fv(p); glEnd(); glPointSize(3); glBegin(GL_POINTS); glColor3f(1, 1, 1); for (auto p : vpts) // was: spts glVertex3fv(p); glEnd(); glPopAttrib(); if (debuglines) { glBegin(GL_LINES); glColor3f(0, 1, 1); if (0)for (auto line : lines) glVertex3fv(line.first), glVertex3fv(line.second); glColor3f(1, 1, 0); for (auto line : glines) glVertex3fv(line.first), glVertex3fv(line.second); glEnd(); } if (usehull && vpts.size() > 5) { auto tris = calchull(vpts, 0); glBegin(GL_LINES); glColor3f(1, 1, 1); for (auto t : tris) for( int i : {0,1,1,2,2,0}) glVertex3fv(vpts[t[i]]); glEnd(); } if (chains) { glBegin(GL_LINES); glColor3f(1, 0, 1); for (auto link : links) { if(link.first) glVertex3fv(link.first->pose()* float3(0, 0, 0)), glVertex3fv(link.first->pose()* float3(0, 0.035f, 0)); glVertex3fv(link.second->pose()* float3(0, 0, 0)) , glVertex3fv(link.second->pose()* float3(0, -0.035f, 0)); } glEnd(); } glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glColor3f(0.5f, 0.5f, 0.5f); for (auto &rb : rigidbodies) rbdraw(rb); glPopAttrib(); // Restore state // Restore state glPopMatrix(); //should be currently in modelview mode glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); glMatrixMode(GL_MODELVIEW); glwin.PrintString({ 0,0 }, "esc to quit."); glwin.PrintString({ 0,1 }, "[h] collision %s ",(usehull)?"hull":"points"); glwin.SwapBuffers(); } return 0; } catch (const char *c) { MessageBox(GetActiveWindow(), c, "FAIL", 0); } catch (std::exception e) { MessageBox(GetActiveWindow(), e.what(), "FAIL", 0); }