Advertisement Jump to content
  • Advertisement

tharuin

Member
  • Content Count

    11
  • Joined

  • Last visited

Community Reputation

100 Neutral

About tharuin

  • Rank
    Member
  1. tharuin

    SAT bouncing resolution

    I've tried to reduce the whole collision checking to a minimum now. ( ProjectPlygon() and GapWidth() stayed the same ) static public void ResolveCollisions() { GameObject currentObj; for (int i = 0; i < _Objects.Count; i++) { currentObj = _Objects; for (int x = 0; x < _Objects.Count; x++) { if (currentObj != _Objects[x]) { if (!currentObj.IsStatic) { CollisionInfo Collision = CollisionCheck.Collide(currentObj.Polygon, _Objects[x].Polygon, currentObj.Velocity); if (Collision.Collided) { currentObj.Velocity = (currentObj.Velocity - 2 * Vector2.Dot(currentObj.Velocity, Collision.Normal) * Collision.Normal * 0.9f); currentObj.Position = currentObj.PreviousPosition; ((Player)currentObj).Acceleration = Vector2.Zero; Console.WriteLine(Collision.Normal); } } } } } } public static CollisionInfo Collide(Polygon A, Polygon B, Vector2 relativeVelocity) { if (A.Points.Count > 0 && B.Points.Count > 0) { List<Vector2> Axis = new List<Vector2>(); for (int i = 0; i < A.Points.Count; i++) { Vector2 a, b; a = A.Points; if (i + 1 >= A.Points.Count) b = A.Points[0]; else b = A.Points[i + 1]; Axis.Add(b - a); } for (int i = 0; i < B.Points.Count; i++) { Vector2 a, b; a = B.Points; if (i + 1 >= B.Points.Count) b = B.Points[0]; else b = B.Points[i + 1]; Axis.Add(b - a); } CollisionInfo CollisionInfo = new CollisionInfo(); Vector2 TranslationAxis = Vector2.Zero; foreach (Vector2 axis in Axis) { Vector2 Normal = Vector2.Normalize(new Vector2(-axis.Y, axis.X)); float minA = 0, minB = 0, maxA = 0, maxB = 0; ProjectPolygon(Normal, A, ref minA, ref maxA); ProjectPolygon(Normal, B, ref minB, ref maxB); float Gap = GapWidth(minA, maxA, minB, maxB); if (Gap > 0) { return new CollisionInfo(false); } else { CollisionInfo.Collided = true; if (Math.Min(Gap, CollisionInfo.Gap) < CollisionInfo.Gap) { CollisionInfo.Gap = Gap; CollisionInfo.Normal = Normal; } } } return CollisionInfo; } else { return new CollisionInfo(false); } } Now its sometimes stuck inside another polygon and still resolves wrong. [/quote] I solved this problem by rewriting the whole code. I can'T say what it was but I think I messed up something critical in my previous code.
  2. tharuin

    SAT bouncing resolution

    I've tried to reduce the whole collision checking to a minimum now. ( ProjectPlygon() and GapWidth() stayed the same ) static public void ResolveCollisions() { GameObject currentObj; for (int i = 0; i < _Objects.Count; i++) { currentObj = _Objects; for (int x = 0; x < _Objects.Count; x++) { if (currentObj != _Objects[x]) { if (!currentObj.IsStatic) { CollisionInfo Collision = CollisionCheck.Collide(currentObj.Polygon, _Objects[x].Polygon, currentObj.Velocity); if (Collision.Collided) { currentObj.Velocity = (currentObj.Velocity - 2 * Vector2.Dot(currentObj.Velocity, Collision.Normal) * Collision.Normal * 0.9f); currentObj.Position = currentObj.PreviousPosition; ((Player)currentObj).Acceleration = Vector2.Zero; Console.WriteLine(Collision.Normal); } } } } } } public static CollisionInfo Collide(Polygon A, Polygon B, Vector2 relativeVelocity) { if (A.Points.Count > 0 && B.Points.Count > 0) { List<Vector2> Axis = new List<Vector2>(); for (int i = 0; i < A.Points.Count; i++) { Vector2 a, b; a = A.Points; if (i + 1 >= A.Points.Count) b = A.Points[0]; else b = A.Points[i + 1]; Axis.Add(b - a); } for (int i = 0; i < B.Points.Count; i++) { Vector2 a, b; a = B.Points; if (i + 1 >= B.Points.Count) b = B.Points[0]; else b = B.Points[i + 1]; Axis.Add(b - a); } CollisionInfo CollisionInfo = new CollisionInfo(); Vector2 TranslationAxis = Vector2.Zero; foreach (Vector2 axis in Axis) { Vector2 Normal = Vector2.Normalize(new Vector2(-axis.Y, axis.X)); float minA = 0, minB = 0, maxA = 0, maxB = 0; ProjectPolygon(Normal, A, ref minA, ref maxA); ProjectPolygon(Normal, B, ref minB, ref maxB); float Gap = GapWidth(minA, maxA, minB, maxB); if (Gap > 0) { return new CollisionInfo(false); } else { CollisionInfo.Collided = true; if (Math.Min(Gap, CollisionInfo.Gap) < CollisionInfo.Gap) { CollisionInfo.Gap = Gap; CollisionInfo.Normal = Normal; } } } return CollisionInfo; } else { return new CollisionInfo(false); } } Now its sometimes stuck inside another polygon and still resolves wrong.
  3. tharuin

    SAT bouncing resolution

    Hi, This multiplication does seem a bit fishy.In general what you want to do with collision normal depends a lot how do you want to resolve the collision. Good first bet would be to reflect the velocity using the normal, so that would be:currentObj.Velocity = currentObj.Velocity - 2*dot(currentObj.Velocity,Collision) * Collision;http://mathworld.wol...Reflection.html [/quote] Hello, first of all: thanks for your reply! I've adjusted my collision detection code based on an example I found on the internet. I also added your reflection code. It looks like this now: static public void ResolveCollisions() { GameObject currentObj; for (int i = 0; i < _Objects.Count; i++) { currentObj = _Objects; for (int x = 0; x < _Objects.Count; x++) { if (currentObj != _Objects[x]) { if (!currentObj.IsStatic) { CollisionInfo Collision = CollisionCheck.Collide(currentObj.Polygon, _Objects[x].Polygon, currentObj.Velocity); if (Collision.WillCollide) { currentObj.Velocity = currentObj.Velocity - 2 * Vector2.Dot(currentObj.Velocity, Collision.Normal) * Collision.Normal; currentObj.Position = currentObj.PreviousPosition + currentObj.Velocity; Console.WriteLine(Collision); } } } } } } struct CollisionInfo { public CollisionInfo(bool collided) { Collided = collided; WillCollide = false; Gap = 0; Normal = Vector2.Zero; TranslationVector = Vector2.Zero; } public bool Collided; public bool WillCollide; public float Gap; public Vector2 Normal; public Vector2 TranslationVector; public override string ToString() { string ret = "Collided: " + Collided + " | Will Collide: " + WillCollide + " | Normal: " + Normal + " | Translation Vector: " + TranslationVector; return ret; } } static class CollisionCheck { public static CollisionInfo Collide(Polygon A, Polygon B, Vector2 relativeVelocity) { if (A.Points.Count > 0 && B.Points.Count > 0) { List<Vector2> Axis = new List<Vector2>(); for (int i = 0; i < A.Points.Count; i++) { Vector2 a, b; a = A.Points; if (i + 1 >= A.Points.Count) b = A.Points[0]; else b = A.Points[i + 1]; Axis.Add(b - a); } for (int i = 0; i < B.Points.Count; i++) { Vector2 a, b; a = B.Points; if (i + 1 >= B.Points.Count) b = B.Points[0]; else b = B.Points[i + 1]; Axis.Add(b - a); } CollisionInfo CollisionInfo = new CollisionInfo(); Vector2 translationAxis = Vector2.Zero; foreach (Vector2 axis in Axis) { //Step 1 Vector2 normal = Vector2.Normalize(new Vector2(-axis.Y, axis.X)); float minA = 0, minB = 0, maxA = 0, maxB = 0; ProjectPolygon(normal, A, ref minA, ref maxA); ProjectPolygon(normal, B, ref minB, ref maxB); float gap = GapWidth(minA, maxA, minB, maxB); if (gap > 0) { return new CollisionInfo(false); } else { CollisionInfo.Collided = true; if (Math.Min(gap, CollisionInfo.Gap) < CollisionInfo.Gap) { CollisionInfo.Gap = gap; CollisionInfo.Normal = normal; } } //Step 2 float velocityProjection = Vector2.Dot(axis, relativeVelocity); if (velocityProjection < 0) minA += velocityProjection; else maxA += velocityProjection; //Repeat Step 1 with the new min/max gap = GapWidth(minA, maxA, minB, maxB); if (gap > 0) CollisionInfo.WillCollide = false; else CollisionInfo.WillCollide = true; if (!CollisionInfo.Collided && !CollisionInfo.WillCollide) break; CollisionInfo.Gap = Math.Abs(gap); if (CollisionInfo.Gap < float.PositiveInfinity) { translationAxis = axis; Vector2 d = A.Center - B.Center; if (Vector2.Dot(d, translationAxis) < 0) translationAxis = -translationAxis; } } return CollisionInfo; } else { return new CollisionInfo(false); } } static private float GapWidth(float minA, float maxA, float minB, float maxB) { if (minA < minB) return minB - maxA; else return minA - maxB; } static private void ProjectPolygon(Vector2 Axis, Polygon Polygon, ref float min, ref float max) { float dotProduct = Vector2.Dot(Axis, Polygon.Points[0]); min = dotProduct; max = dotProduct; for (int i = 0; i < Polygon.Points.Count; i++) { dotProduct = Vector2.Dot(Polygon.Points, Axis); if (dotProduct < min) min = dotProduct; else if (dotProduct > max) max = dotProduct; } } } The resolution works perfect for 1/4 of all edges, but is messed up for all the others. The following images shows the working edges ( green ones ): [attachment=6004:UnbenannteZeichnung(2).png] You can download the binary here ( http://dl.dropbox.co...375/Release.rar ), I hope its okay to post it. You can turn debug draw on by pressing "T" ( to see the polygons )
  4. tharuin

    SAT bouncing resolution

    Heyho, for a game I managed to get SAT-collision testing working by mixing some examples and codes I've found. My problem now is that while resolving my collision I want my object ( only 1 moving object, all others are static ) to bounce from the edge of the collided polygon. My code looks like this: static public void ResolveCollisions() { GameObject currentObj; for (int i = 0; i < _Objects.Count; i++) { currentObj = _Objects; for (int x = 0; x < _Objects.Count; x++) { if (currentObj != _Objects[x]) { if (!currentObj.IsStatic) { Vector2 Collision = CollisionCheck.Collide(currentObj.Polygon, _Objects[x].Polygon); if (Collision != Vector2.Zero) { currentObj.Velocity *= Vector2.Normalize(Collision); } } } } } } public static Vector2 Collide(Polygon A, Polygon B) { if (A.Points.Count > 0 && B.Points.Count > 0) { List<Vector2> Axis = new List<Vector2>(); for (int i = 0; i < A.Points.Count; i++) { Vector2 a, b; a = A.Points; if (i + 1 >= A.Points.Count) b = A.Points[0]; else b = A.Points[i + 1]; Axis.Add(b - a); } for (int i = 0; i < B.Points.Count; i++) { Vector2 a, b; a = B.Points; if (i + 1 >= B.Points.Count) b = B.Points[0]; else b = B.Points[i + 1]; Axis.Add(b - a); } Vector2 CollisionNormal = Vector2.Zero; foreach (Vector2 axis in Axis) { Vector2 normal = Vector2.Normalize(new Vector2(-axis.Y, axis.X)); float minA = 0, minB = 0, maxA = 0, maxB = 0; ProjectPolygon(normal, A, ref minA, ref maxA); ProjectPolygon(normal, B, ref minB, ref maxB); float gap = GapWidth(minA, maxA, minB, maxB); if (gap > 0) { return Vector2.Zero; } else { CollisionNormal = normal; } } return CollisionNormal; } else return Vector2.Zero; } static private float GapWidth(float minA, float maxA, float minB, float maxB) { if (minA < minB) return minB - maxA; else return minA - maxB; } static private void ProjectPolygon(Vector2 Axis, Polygon Polygon, ref float min, ref float max) { float dotProduct = Vector2.Dot(Axis, Polygon.Points[0]); min = dotProduct; max = dotProduct; for (int i = 0; i < Polygon.Points.Count; i++) { dotProduct = Vector2.Dot(Polygon.Points, Axis); if (dotProduct < min) min = dotProduct; else if (dotProduct > max) max = dotProduct; } } The collisions are detected correct, the resoultion is really weird, though. In some cases it works ( even if the leaving angle isn't correct imo ). In others the object just stopps moving. Here I have a pictures showing the behaviour: [attachment=6001:UnbenannteZeichnung.png] Is there anything I did wrong? ( The idea with multiplying the velocity by the normal I read on a yt video comment :S )
  5. Heyho, maybe this is a bit off topic but a while ago I saw a map editor made with XNA and Winforms or WPF. The editor in this video is not exactly the one I saw but it uses the same control. at 0:15 you can see this coordinate system where you can add and manipulate points. Does somebody know what the name of this control is and maybe where I can get it? Thanks for your help!
  6. Heyho, I'm trying to implement facebook authentification to my silverlight application. I got everything set up on facebook and the application is already connected there. While searching for some samples about how to manage that I didn't found any example which doesn't use an asp.net host application. Is there a way to actually manage this without having a windows server running...? I found one example for Silverlight apps, but this one is only for Silverlight apps running out of browser, because of the Webbrowser-Control not working in-browser. ( http://blog.prabir.me/post/Facebook-CSharp-SDK-Writing-your-first-Facebook-Application.aspx ). What I have so far is basically everything provided in that link, except the part where the browser comes in: public string accesstoken; public MainPage() { InitializeComponent(); LoginToFacebook(); } void LoginToFacebook() { string appId = "app_id_here"; string[] extendedPermissions = new[] { "publish_stream", "offline_access" }; var oauth = new FacebookOAuthClient() { AppId = appId }; var parameters = new Dictionary<string, object> { { "response_type", "code" }, { "display", "popup" } }; if (extendedPermissions != null && extendedPermissions.Length > 0) { var scope = new StringBuilder(); scope.Append(string.Join(",", extendedPermissions)); parameters["scope"] = scope.ToString(); } var loginUrl = oauth.GetLoginUrl(parameters); } void oauth_GetApplicationAccessTokenCompleted(object sender, FacebookApiEventArgs e) { } I hope you can help me Sincerely, xbaalx
  7. Does nobody have an idea or a hint for me? I already changed the collision to test pixel ( mask ) to player ( rectangle ), but this didn't change the basic behaviour.
  8. Heyho everybody! I'm currently trying to make the collision working for a sidescrolling ( platformer ) game. It uses a collision mask ( like this one: http://dl.dropbox.co...lisionmask1.png BIG IMAGE!!! ). My current code for this is this one: override public void OnUpdate(GameTime gameTime) { //Input check if (state != State.Jumping) { state = Player.State.Standing; if (Keyboard.GetState().IsKeyDown(Keys.A)) { Velocity = new Vector2(WalkSpeed*-1, Velocity.Y); direction = Player.Direction.Left; state = Player.State.Walking; } else if (Keyboard.GetState().IsKeyDown(Keys.D)) { Velocity = new Vector2(WalkSpeed, Velocity.Y); direction = Player.Direction.Right; state = Player.State.Walking; } else Velocity = new Vector2(0, Velocity.Y); if (Keyboard.GetState().IsKeyDown(Keys.Space)) { state = Player.State.Jumping; Velocity = new Vector2(Velocity.X, JumpPower*-1); } } //Position update lastPosition = Position; Velocity += Acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; Position += Velocity; switch (state) { case State.Walking: SetAnimation("Walk"); break; case State.Jumping: SetAnimation("Jump"); break; case State.Standing: default:SetAnimation("Stand"); break; } //Collision check int check = Level.GetCollisionMaskIndex(this); //Check if player is already standing ( should mean that he collided the frame before ) if (state != State.Standing) { if (CheckCollision(check) != new Vector2(1.337f, 1.337f)) { state = State.Standing; Position = new Vector2(Position.X, Position.Y - (Size.Y / 2) - Vector2.Subtract(GetCenter(), CheckCollision(check)).Y + 5); MoveToContact(check); Velocity = new Vector2(Velocity.X, 0); } } else { Position = new Vector2(Position.X, lastPosition.Y); } base.OnUpdate(gameTime); } private void MoveToContact(int Index) { Vector2 beforeCollision = Position; int direction = 0; if (CheckCollision(Index) != new Vector2(1.337f, 1.337f)) direction = -1; else direction = 1; while (CheckCollision(Index) != new Vector2(1.337f, 1.337f)) { beforeCollision = Position; Position += new Vector2(0, direction); } Position = beforeCollision; } private Vector2 CheckCollision(int Index) { Rectangle rectangleA, rectangleB; rectangleA = new Rectangle((int)Position.X, (int)Position.Y, (int)Size.X, (int)Size.Y); rectangleB = new Rectangle((int)Level.CollisionMasks[Index].Position.X, (int)Level.CollisionMasks[Index].Position.Y, Level.CollisionMasks[Index].Texture.Width, Level.CollisionMasks[Index].Texture.Height); Color[] dataA, dataB; dataA = colorData; dataB = Level.CollisionMasks[Index].colorInfo; // Find the bounds of the rectangle intersection int top = Math.Max(rectangleA.Top, rectangleB.Top); int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom); int left = Math.Max(rectangleA.Left, rectangleB.Left); int right = Math.Min(rectangleA.Right, rectangleB.Right); // Check every point within the intersection bounds for (int y = top; y < bottom; y++) { for (int x = left; x < right; x++) { // Get the color of both pixels at this point Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width]; Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width]; // If both pixels are not completely transparent, if (colorA.A != 0 && colorB.A != 0) { // then an intersection has been found return new Vector2(x, y); } } } // No intersection found return new Vector2(1.337f, 1.337f); } This code has some bugs and behaviors that I actually don't want. First of all its not very efficient. Its reducing the FPS when passing bigger slopes and when I'm changing to another window and go back the character just falls through the ground sometimes. Also its possible to walk over any slope, I don't want it to move against a wall and appear on the top of the wall. My next point is the fact that it is currently only checking for vertical collision. I want it to check for all collision, so jumping against a platform over you makes you stopping and falling back. I was google'ing and searching for the last days and didn't found any nice resource or examples for this. Are there any common ways to solve this? ( This is meant to be pixelperfect and big collision mask based, not rectangle and tiled collision masks ) I hope you can give me some hints or links. Thank you!
  9. Heyho together, I'm planing to work a bit with websockets. Well I know that they are pretty "easy" ways to do that with php and others, but I want to program the server with c++ and the clients to be connected via websockets with the server. Now I'm searching for a while but I'm not able to find a good and easy solution to let the server handle the websocket I already found things like http://www.webtoolkit.eu/ or http://www.boost.org...boost_asio.html but I don't know how the hell I can use them X_x I think they are a bit highlevel for me. Is there a easy lib or framework that can handle websockets ideally just as easy as http://www.sfml-dev....ork-sockets.php I hope you can help me! Sincerely, ~
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!