   2D demo of sphere sliding walls.
  Hello, does anyone have some code just of basic wall sliding? with obtuse and not-obtuse corners?pleeease send a pm to me so i can get the code.If anyone know a good sample on the net, please tell me the url.iam stuck in 99.9999% working collision response. my problem is sliding around corners...   
  Do you mean walking into and sliding along one wall, and eventually reaching a corner, or do you want to adjust the movement when walking straight into a wall close to a corner, as to automatically walk around it?Are the walls made up of lines, that you mathematically detect collisions against, or are we talking about per-pixel collisions?We need much more information to give you a good response.   ;  all I can offer is this.//===========================================================================//// INCLUDES////===========================================================================#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <math.h>#include <gl/glut.h>//===========================================================================//// DECLARE////===========================================================================typedef unsigned char   u_char;typedef unsigned short  u_short;typedef unsigned int    u_int;typedef unsigned long   u_long;float mouse_x= 0.0f;float mouse_y= 0.0f;int   mouse_b= 0;float width= 640;float height= 480;class Vector;void printString(int x, int y, bool pixelcoords, unsigned int rgba, const char* str, ...);void renderSegment(const Vector& A, const Vector& B, u_int uARGBLine, u_short uStipple=0xFF);void renderBox(const Vector& Min, const Vector& Max, u_int uARGBFill, u_int uARGBLine);void renderBox(const Vector& Pos, const Vector& Ext, float orient, u_int uARGBFill, u_int uARGBLine);void renderArrow(const Vector& P, const Vector& D, float length, u_int uARGB);void renderDisk(const Vector& xPos, float fRad, u_int uARGBFill, u_int uARGBLine);void renderPoint(const Vector& xPos, float fRad, u_int uARGB);void renderPolygon(const Vector& xPos, const Vector* Verts, int numverts, u_int uARGBFill, u_int uARGBLine);//===========================================================================//// MATHS////===========================================================================inline float sign(float x){return (x < 0.0f)? -1.0f : 1.0f;}inline float frand(float x=1.0f){return (rand() / (float) RAND_MAX) * x;}inline float frand(float a, float b){return a + frand(1.0f) * (b - a);}inline void swapf(float& a, float& b){float c = a;a = b;b = c;}inline float pi(){    static const float s_pi = atan(1.0f) * 4.0f;return s_pi;}inline float twopi(){static const float s_twopi = 2.0f * pi();return s_twopi;}inline float radiansToDegrees(float rad){static const float k = 180.0f / pi();return rad * k;}inline float degreesToRadians(float deg){static const float k = pi() / 180.0f;return deg * k;}//===========================================================================//// VECTORS////===========================================================================class Vector{public:float x,y;static const Vector& zero() { static const Vector v(0, 0); return v; }public:inline Vector(void){}inline Vector(float inx,float iny): x(inx), y(iny){}inline Vector &operator /=(const float s){ x /= s; y /= s; return *this; }inline Vector &operator *=(const float s){ x *= s; y *= s; return *this; }inline Vector &operator +=(const Vector &other) { x += other.x;y += other.y; return *this; }inline Vector &operator -=(const Vector &other) { x -= other.x;y -= other.y; return *this;}inline Vector operator * (float s) const {return Vector(x*s, y*s); }inline Vector operator / (float s) const {return Vector(x/s, y/s); }inline Vector operator + (const Vector &other) const {return Vector(x+other.x, y+other.y); }inline Vector operator - (const Vector &other) const {return Vector(x-other.x, y-other.y); }friend Vector operator * (float k, const Vector& other) { return Vector(other.x*k, other.y*k); }inline Vector operator -(void) const { return Vector(-x, -y); }inline float operator ^ (const Vector &other) const { return (x * other.y) - (y * other.x); } // cross productinline float operator * (const Vector &other) const { return (x * other.x) + (y * other.y); } // dot productinline float length(void) const { return (float) sqrt(x*x + y*y); }inline float dotProduct(const Vector& other) const { return (*this) * other; }inline float crossProduct(const Vector& other) const { return (*this) ^ other; }Vector& randomPosition(const Vector& min, const Vector& max){x = frand(min.x, max.x);y = frand(min.y, max.y);return *this;}Vector& randomDirection(){float a = frand(twopi());x = cos(a);y = sin(a);return *this;}Vector direction(void) const{Vector temp(*this);temp.normalise();return temp;}float normalise(void) {float l = length();if (l == 0.0f) return 0.0f; (*this) *= (1.0f / l); return l;}Vector& minBound(const Vector& a, const Vector& b){x = (a.x < b.x)? a.x : b.x;y = (a.y < b.y)? a.y : b.y;return (*this);}Vector& maxBound(const Vector& a, const Vector& b){x = (a.x > b.x)? a.x : b.x;y = (a.y > b.y)? a.y : b.y;return *this;}Vector& rotate(float angle){float tempx = x;float tempy = y;float co = (float) cos(angle);float si = (float) sin(angle);x = tempx * co - tempy * si;y = tempx * si + tempy * co;return *this;}Vector& transform(const Vector& position, float orientation){rotate(orientation);(*this) += position;return (*this);}};//===========================================================================//// TOOLS////===========================================================================#define ARGB_A(u) (((u)>>24) & 0x000000FF)#define ARGB_R(u) (((u)>>16) & 0x000000FF)#define ARGB_G(u) (((u)>> 8) & 0x000000FF)#define ARGB_B(u) (((u)>> 0) & 0x000000FF)void renderColour(u_int col){glColor4ub(ARGB_R(col), ARGB_G(col), ARGB_B(col), ARGB_A(col));}void renderPoint(const Vector& pos, float rad, u_int col){renderColour(col);glPointSize(rad);glBegin(GL_POINTS);glVertex2f(pos.x, pos.y);glEnd();}void renderDisk(const Vector& pos, float rad, u_int fill, u_int line){static int glDiskList = -1;static int glCircleList = -1;static int numVerts = 64;if (!glIsList(glCircleList)){glCircleList = glGenLists(1);glNewList(glCircleList, GL_COMPILE_AND_EXECUTE);glBegin(GL_LINE_LOOP);for(int i = 0; i < numVerts + 1; i ++){Vector p(cos(twopi() * (i / (float) numVerts)), sin(twopi() * (i / (float) numVerts)));glVertex2f(p.x, p.y);}glEnd();glEndList();}if (!glIsList(glDiskList)){glDiskList = glGenLists(1);glNewList(glDiskList, GL_COMPILE_AND_EXECUTE);glBegin(GL_TRIANGLE_FAN);glVertex2f(0, 0);for(int i = 0; i < numVerts + 1; i ++){Vector p(cos(twopi() * (i / (float) numVerts)), sin(twopi() * (i / (float) numVerts)));glVertex2f(p.x, p.y);}glEnd();glEndList();}glPushMatrix();glTranslatef(pos.x, pos.y, 0.0f);glScalef(rad, rad, rad);renderColour(fill);glCallList(glDiskList);renderColour(line);glCallList(glCircleList);glPopMatrix();}void renderPolygon(const Vector& pos, const Vector* verts, int numverts, u_int fill, u_int line){glPushMatrix();glTranslatef(pos.x, pos.y, 0.0f);renderColour(fill);glBegin(GL_TRIANGLE_FAN);glVertex2f(0, 0);for(int i = 0;  i < numverts; i ++){glVertex2f(verts.x, verts.y);}glVertex2f(verts[0].x, verts[0].y);glEnd();renderColour(line);glBegin(GL_LINE_LOOP);for(int i = 0;  i < numverts; i ++){glVertex2f(verts.x, verts.y);}glEnd();glPopMatrix();}void renderArrow(const Vector& pos, const Vector& dir, float length, u_int col){float angle = atan2(dir.y, dir.x);glPushMatrix();glTranslatef(pos.x, pos.y, 0.0f);glRotatef(radiansToDegrees(angle), 0.0f, 0.0f, 1.0f);glScalef(length, length, 1.0f);renderColour(col);glBegin(GL_LINES);glVertex2f(0.0f, 0.0f);glVertex2f(1.0f, 0.0f);glVertex2f(1.0f, 0.0f);glVertex2f(0.75f, 0.2f);glVertex2f(1.0f, 0.0f);glVertex2f(0.75f,-0.2f);glEnd();glPopMatrix();}void renderSegment(const Vector& a, const Vector& b, u_int col, u_short stipple){renderColour(col);glEnable(GL_LINE_STIPPLE);glLineStipple(2, stipple);glBegin(GL_LINES);glVertex2f(a.x, a.y);glVertex2f(b.x, b.y);glEnd();glDisable(GL_LINE_STIPPLE);}void renderBox(const Vector& pos, const Vector& halfsize, float orient, u_int fill, u_int line){glPushMatrix();glTranslatef(pos.x, pos.y, 0.0f);glRotatef(orient * 180.0f / pi(), 0, 0, 1);glScalef(halfsize.x, halfsize.y, 1.0f);renderColour(fill);glBegin(GL_QUADS);glVertex2f(-1, -1);glVertex2f(-1,  1);glVertex2f( 1,  1);glVertex2f( 1, -1);glEnd();renderColour(line);glBegin(GL_LINE_LOOP);glVertex2f(-1, -1);glVertex2f(-1,  1);glVertex2f( 1,  1);glVertex2f( 1, -1);glEnd();glPopMatrix();}void renderBox(const Vector& min, const Vector& max, u_int fill, u_int line){renderColour(fill);glBegin(GL_QUADS);glVertex2f(min.x, min.y);glVertex2f(max.x, min.y);glVertex2f(max.x, max.y);glVertex2f(min.x, max.y);glEnd();renderColour(line);glBegin(GL_LINE_LOOP);glVertex2f(min.x, min.y);glVertex2f(max.x, min.y);glVertex2f(max.x, max.y);glVertex2f(min.x, max.y);glEnd();}void printString(int x, int y, bool pixelcoords, unsigned int col, const char* str, ...){static char buffer[512];va_list params;va_start(params, str);vsprintf_s(buffer, sizeof(buffer), str, params);va_end(params);glPushMatrix();renderColour(col);float fx = x;float fy = y;if (!pixelcoords){x *= 8;y *= 13;glRasterPos2f(x, y);}else{glRasterPos2f(x, y);}char* c = buffer;while(*c){glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c);c++;}glPopMatrix();}//===========================================================================//// MAIN////===========================================================================void  gameInit();void  gameShutdown();void  gameUpdate(float dt);void  gameRender(void);void  gameOnKeyCallback(int keypressed);void  gameMouse(float x, float y, int buttons);void display(){//--------------------------------------------------------------------------// render stuff//--------------------------------------------------------------------------glClearColor(0.2f, 0.2f, 0.2f, 0.2f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0, width, 0, height);//-----------------------------------------------------------------// Setup the model view matrix//-----------------------------------------------------------------glMatrixMode(GL_MODELVIEW);glLoadIdentity();gameMouse(mouse_x, height - mouse_y, mouse_b);gameUpdate(1.0f / 60.0f);gameRender();glutSwapBuffers();}void mouse(int buttons, int state, int x, int y){mouse_x = x;mouse_y = y;if (buttons == GLUT_LEFT_BUTTON){if (state == GLUT_DOWN)mouse_b |= 1;elsemouse_b &= ~1;}if (buttons == GLUT_RIGHT_BUTTON){if (state == GLUT_DOWN)mouse_b |= 2;elsemouse_b &= ~2;}}void passiveMotion(int x, int y){mouse_x = x;mouse_y = y;}void motion(int x, int y){mouse_x = x;mouse_y = y;}void timer(int t){display();glutTimerFunc(t, timer, (int) 500.0f / 60.0f);}void reshape(int w, int h){width  = w;height = h;glViewport(0, 0, w, h);}void keyboard(unsigned char key, int x, int y){if (key == 27)exit(0);gameOnKeyCallback(key);}void extKeyboard(int key, int x, int y){gameOnKeyCallback(key);}void main(int argc, char** argv){//--------------------------------------------------------------------------// OpenGL / GLUT init//--------------------------------------------------------------------------    glutInit( &argc, argv );glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowSize(width, height);glutInitWindowPosition(0, 0);glutCreateWindow("Swept volume polygon collision");glPointSize(3.0f);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glDisable(GL_CULL_FACE);glDisable(GL_LIGHTING);glutDisplayFunc(display);glutReshapeFunc(reshape);glutTimerFunc(0, timer, (int) 100.0f / 60.0f);glutPassiveMotionFunc(passiveMotion);glutMouseFunc(mouse);glutMotionFunc(motion);glutKeyboardFunc(keyboard);glutSpecialFunc(extKeyboard);gameInit();glutMainLoop();gameShutdown();}//===========================================================================//// GAME CODE////===========================================================================// segments to populate the worldVector segments[1000][2];int numsegments=0;Vector spherePos;Vector targetPos;float sphereRad;bool sphereSegmentIntersect( const Vector& start, const Vector& end,  const Vector& SpherePos, float radius, Vector& Dcoll);void calculateRandomSegment(Vector& start, Vector& end, float scale){Vector centre;centre.randomPosition(Vector(0, 0), Vector(width, height));Vector dir;dir.randomDirection();float s = scale * frand(0.8f, 1.2f);start = centre + dir * (s * 0.5f);end = centre - dir * (s * 0.5f);}void gameShutdown(void){}void gameInit(void){numsegments = rand() % 100 + 40;for(int i = 0; i < numsegments; i ++){calculateRandomSegment(segments[0], segments[1], width / 15.0f);}sphereRad = frand(width / 30, width / 35);spherePos.randomPosition(Vector(width * 0.30f, height* 0.30f), Vector(width * 0.70f, height * 0.70f));targetPos = spherePos;}void gameUpdate(float dt){Vector movement = (targetPos - spherePos);if (movement.length() > (sphereRad * 0.25f)){movement.normalise();movement *= (sphereRad * 0.25f);}spherePos += movement;for(int i = 0; i < numsegments; i ++){Vector dcoll;// Check if the sphere will collide with the polygon at some point while moving to it's new position.if (sphereSegmentIntersect(segments[0], segments[1], spherePos, sphereRad, dcoll)){// apply mtd to move spehre away from intersection.spherePos += dcoll;}}}void gameRender(void){renderDisk(targetPos, sphereRad, 0x8000FF00, 0xFFFFFFFF);renderDisk(spherePos, sphereRad, 0x80FFFF80, 0xFFFFFFFF);renderArrow(spherePos, (targetPos - spherePos).direction(), (targetPos - spherePos).length(), 0xffffffff);for(int i = 0; i < numsegments; i ++){renderSegment(segments[0], segments[1], 0xFFFFFFFF, 0xFFFF);}}void gameOnKeyCallback(int keypressed){switch(keypressed){case ' ':gameInit();break;case GLUT_KEY_DOWN:spherePos.y -= 2.0f;break;case GLUT_KEY_UP:spherePos.y += 2.0f;break;case GLUT_KEY_LEFT:spherePos.x -= 2.0f;break;case GLUT_KEY_RIGHT:spherePos.x += 2.0f;break;}}void gameMouse(float x, float y, int buttons){// Set the sphere's movement vector from the sphere's current location to the mouse's location.targetPos = Vector(x, y);}//===========================================================================//// COLLISION CODE////===========================================================================Vector closestPointOnSegment( const Vector& point, const Vector& start, const Vector& end){Vector e = end - start;Vector h = point - start;float t = (e * h) / (e * e);if(t < 0.0f) t = 0.0f;if(t > 1.0f) t = 1.0f;Vector closest = start + e * t;return closest;}bool sphereSegmentIntersect( const Vector& start, const Vector& end,  const Vector& spherePos, float radius, Vector& dcoll){Vector closest = closestPointOnSegment(spherePos, start, end);Vector diff = (spherePos - closest);float dist2 = (diff * diff);if(dist2 > radius * radius)return false;float dist = sqrt(dist2);if(dist < 0.000001f){dcoll = Vector(0, 0);return true;}dcoll = diff * (radius - dist) / dist;return true;}it's opengl with the glut library.;  thanks oliii and other post. i think olii send me what i needed.This works beautifully in 2D, hope it will work in 3D also.i had to change some code, can´t take diff * diff in C++ D3d.is this right?bool sphereSegmentIntersect( const D3DXVECTOR3& start, const D3DXVECTOR3& end,  const D3DXVECTOR3& spherePos, float radius, D3DXVECTOR3& dcoll){//D3DXVECTOR3 closest = closestPointOnSegment(spherePos, start, end);D3DXVECTOR3 closest = ClosestPoint(spherePos);D3DXVECTOR3 diff = (spherePos - closest); float dist2 = D3DXVec3Length(&diff);//float dist2 = (diff * diff);if(dist2 > radius * radius)return false; float dist = sqrt(dist2);if(dist < 0.000001f){dcoll = D3DXVECTOR3(0, 0, 0);return true;}dcoll = diff * (radius - dist) / dist;return true;}thanks oliii, solved my problem (if it also will work in 3d where the gamespeed is faster)[Edited by - Meshboy on May 8, 2009 5:54:52 AM]