Getting contact points on bodies in Cocos2d & Box2d - iphone

I'm very new to Cocos2d and Box2d, I
have been following tutorials and
generally hacking. However, I have one
problem I cannot solve.
I create 2 bodies and fixtures (in the Box2d world) and create a "Contact Listener" object. This object stores a list of contacts along with the "contact point".
When the two bodies collide a contact point is reported but this (I think) is in the world co-ordinate system.
My problem is I can't seem to convert the contact point to a usable co-ordinate on both of the bodies.
I want to add a crack graphic to the
sprite (connected to the body) at the
point of contact on both
bodies/fixtures.
Has anyone solved this? I may be storing the "contact point" relative to the "world" is completely the wrong way to go.

Here is how to get the world-point (or points, max of 2 points are returned) where the collision took place. Within your B2ContactListener object, in BeginContact or EndContact functions:
b2WorldManifold worldManifold;
contact->GetWorldManifold(&worldManifold);
std::cout << "Contact point X: " << worldManifold.points[0].x * Ascengine::Physics::PIXEL_TO_METER_RATIO << " Contact point Y: " << worldManifold.points[0].y * Ascengine::Physics::PIXEL_TO_METER_RATIO << std::endl;
From here, as Jason F mentioned, you can then use b2Body::GetLocalPoint(const b2Vec2 &worldPoint) to convert this world point to local object space. I just wanted to add my own answer to include the whole part about getting the world contact points, since this seems to be omitted altogether in the accepted answer.

check out this. Take a look at b2Body::GetLocalPoint(const b2Vec2 &worldPoint)

Related

Get world space Oriented Boundin Box 8 points in unreal (C++)

Does anybody know how to retrieve an actor's world space oriented bounding box 8 points in C++. Im reading the official documentation but it's a bit vague as it never specifies whether the bounds objects (FBox, FBoxShpereBounds) are local space, world space, axis aligned etc
I'm thinking something like below but I'm not sure if that's right
UStaticMeshComponent* pMesh = Cast<UStaticMeshComponent>(actor->GetComponentByClass(UStaticMeshComponent::StaticClass()));
if (pMesh)
{
UStaticMesh* pStaticMesh = pMesh->GetStaticMesh();
if (pStaticMesh && pStaticMesh->GetRenderData())
{
FStaticMeshRenderData* pRenderData = pStaticMesh->GetRenderData();
if (pRenderData)
FBoxSphereBounds bounds = pRenderData->Bounds;
bounds.TransformBy(actor>GetActorTransform());
}
}
Unreal maintains it's bounds as axis-aligned (AABB). This is often done in game engines for efficiency in the physics/collision subsystem. To get an AABB for an actor, you can use the following function - this is essentially equivalent to what you did above with pRenderData->Bounds but is independent of the actor implementation.
FBox GetActorAABB(const AActor& Actor)
{
FVector ActorOrigin;
FVector BoxExtent;
// First argument is bOnlyCollidingComponents - if you want to get the bounds for components that don't have collision enabled then set to false
// Last argument is bIncludeFromChildActors. Usually this won't do anything but if we've child-ed an actor - like a gun child-ed to a character then we wouldn't want the gun to be part of the bounds so set to false
Actor.GetActorBounds(true, ActorOrigin, BoxExtent, false);
return FBox::BuildAABB(ActorOrigin, BoxExtent);
}
From code above it looks like you want an oriented bounded box (OBB) since you are applying the transform to it. Trouble is the AABB Unreal maintains will be "fit" to the world space axes and what you are essentially doing just rotates the center point of the AABB which will not give a "tight fit" for rotation angles far from the world axes. The following two UE forum posts provide some insight into how you might do this:
https://forums.unrealengine.com/t/oriented-bounding-box-from-getlocalbounds/241396
https://forums.unrealengine.com/t/object-oriented-bounding-box-from-either-aactor-or-mesh/326571/4
If you want a true OBB, FOrientedBox is what you need, but the engine lacks documented utilities to do intersection or overlap tests with this structure depending on what you are trying to do, but these things do exist in the engine but you have to hunt through the source code to find them. In general, the separating axis theorem (SAT) can be used to find collisions between two convex hull shapes, which an OBB is by definition.

Unity - Tilemap Contains - how to read if Tilemap contains a tile on a specific coordinate in world?

I'm a complete noob in gamedev, but I've watched a number of videos on generating a 2D array to setup Grid-based combat (pathing, obstacles etc), and I don't find the programmable approach intuitive or visually friendly.
Is it possible to setup such level with obstacles using multiple tilemaps?
1st tilemap would include the whole level zone (I named it "General Tilemap"):
2nd tilemap would only contain tiles that would be marked as collision when being read (I named it "Collision Tilemap") and player wouldn't be able to move to them:
My logic would be to read the adjacent tiles around the player, and if:
A tile exists on the General tilemap, but not on the Collision tilemap, player can click it and move there.
A tile exists on both tilemaps, it is marked as collision, it cannot be clicked.
A tile doesn't exist, it is out of boundaries, it cannot be clicked.
Could you please let me know if this is a valid approach (for smaller levels at least, I won't be making anything large so scalability is not an issue), or have I gone completely off course and there's a superior way to do this properly?
I'm currently stuck at the very first step - reading whether the tile on a coordinate (next to player) is existing or null for both tilemaps. Doing my best to figure it out though.
Thanks!
Managed to check if tilemap contains a tile on xy coordinates in Start function, by finding the relevant Tilemap and using hasTile to read it it has value or not. This returns a boolean.
Tilemap generalTilemap = GameObject.Find("General Tilemap").GetComponent<Tilemap>();
hasGTile = generalTilemap.HasTile(playerTileCoord);
Still not sure if this approach will work for me long-term, especially when I get to the pathfinding algorithm, but we'll see!

Physics contacts in SpriteKit

Is it possible to explain how bitmasking works for just this simplistic situation:
A big (blue) ball. Contact BitMask 0b0001
A medium (red) ball. Contact BitMask 0b0010
A small (white) ball. Contact BitMask 0b0100
They have no collisions between them, because somehow this is turned off between them. I assume by setting their collision masks to 00 all the way through the 32 bits... but let's leave that for another question, I haven't yet figured out how to turn these off.
Having set each ball to have a unique contact bit mask, what is done that gives contact information when they contact?
How is it possible to know which two balls have contacted each other?
Is it possible to have the contact information only received by the biggest ball in any given contact?
UPDATE:
I'm not necessarily after code. If you need code to explain what's what, how it works, and why whatever does what, go for it.
But what I'm really after is an understanding of how bitmasking works to provide logic that permits the determination of "who" was involved in any contact.
The reason I've given each ball size a different bitmask is that I thought this might help determine the bigger ball in any given contact between two balls. I could be wrong about this, though.
UPDATE 2:
Understanding of processes progressing:
As I understand it, these are the parts of the process:
Register SKView subclassed SKScene as conforming to the physics world contact notification delegate. Say it is so, too.
Set bitmask as categories for each type of bodily interaction type desire to be known about and/or controlled in the simulation
Use these bitmasks to articulate the nature of each object desired to be a part of contacts and/or collisions by applying them appropriately (some magic decision making in here).
Override the contacts callback with code that does stuff, in the same SKView subclass registered as the delegate
Create some magic code that determines who/what has contacted whom.
I understand some of these, but not the differentials of setting contact bitmasks versus the reasoning for the naming of category bitmasks, and not how to determine who has contacted whom.
In almost all physics engines, collision layers are represented by bit masks. All objects in the same collision layers will collide with each other. In the bit mask, each layer is represented by a bit. If the bit at position 0 is on, the object will collide with other objects which have the bit at the same position in their bit mask on.
While checking for collisions, the physics engine's broad-phase routine only reports those pairs as potentially colliding which have at least one common bit set to 1 in their collision bit mask. This check is simply done by ANDing (&) the two bit masks. The potentially colliding pair is reported to the narrow-phase routine only if the above check returns a non-zero result.
For example, if you wanted the blue ball to collide with both the red and white balls but wanted the red and white balls to not collide with each other, you'd set the bit masks to somewhat the following:
Blue -> 0b0011
Red -> 0b0001
White -> 0b0010
In your example, since none of the bodies have a common bit set in their collision bit mask, none of them collide with each other. In the above example, since the red and white balls don't have a common bit in their bit mask, they don't collide.
You might want to set all the collision bit masks to -1 (which turns all bits on) and remove bits/categories from the mask by XORing. The above example would then be implemented by the following pseudocode:
blueBody.collisionMask = -1;
whiteBody.collisionMask = -1;
redBody.collisionMask = -1;
redBodyCategory = 0b0001;
whiteBodyCategory = 0b0010;
whiteBody.collisionMask ^= redBodyCategory;
redBody.collisionMask ^= whiteBodyCategory;
I don't use SpriteKit, but from the little information I obtained from this SO answer, the contactTestBitmask sets the categories with which events will be raised on contact, while the collisionBitmask sets the categories with which the body will actually collide. So if you want contact information only from contacts which involve the Blue ball, you'd set the contactTestBitmask to the values as in my example above.
To check which balls are colliding with each other, you'd have to check the bit mask values and discern which one is which. In the above example, the Blue ball can be recognized by checking if body.contactTestBitmask == 0b0011, and so on for each other body.
As a side note, you might want to look into using a proper game engine like Unity that will make all this much easier.
First, you need to define what your sprites are, this is what the categoryBitMask is for. Think of this as a binary name for your sprite, with each digit being a unique name. Now it is possible to give your sprite more than 1 name, but for simplicity purposes, let's keep it to one.
contactBitMask tells the sprites what names it should be looking for.
So during the physics phase, the engine will take a given sprite, and look for all other physics sprites with the search name provided in the contactBitMask.
After this, evaluations are performed against the original sprite and the sprites in the filtered list.
On a contact, didBegin(contact:) is called, and contact contains all the information you need, including the 2 contact bodies. You then check the categoryBitMask to get the name of the sprites in question, and you do your conditioning based on these names.

How to make a sprite have gravity?

xcode 5 iOS7 sprite kit.
My wish is to make a sprite that has its own gravity.
Like a planet. If another sprite comes within a certain range of it, it will slowly pull the other sprite closer.
I have two sprites. One moving and one stationary. When the moving sprite gets in a given distance of the stationary sprite the stationary sprite gravity should slowly pull the other sprite towards it. This way the moving sprite would change its path in a soft curve.
My idea would be to calculate the distance from the stationary object to any other object and if close enough start pulling and if the moving object gets out of range ageing, then stop pulling.
Would probably need to research some vector calculation.
Thats my immediate thoughts.
Is this possible and how? Does it already exist?
A friend of mine did this for his physics dissertation. multibody gravity simulation. So yeah you can but you need to be willing to learn some maths. Apparently there is a clever optimisation to make it run decently nlog(n) rather than n^2). you probably want to ask this on the physics version of stack overflow to get a good answer. I have the code at home ... will post it later but you will want an explanation - i used it in an xna app. Its badass once you get it working - although if you want naturally orbiting objects then you will want to code them using parametric equations for easy and cool orbits. Simply because its hard to solve and with time even using double will result in some errors (the good implementations also work out the error and adjust - again will post later). But the real problem is solving for stable orbits. You then use the algorithm for free moving bodies such and player objects / npcs. Although solving accurate movement for npc in a changing field is v hard.
you want to look at this question: Jon Purdys answer is the one you want
multi body physics - gravity
and this one (which is linked from above) ...
https://gamedev.stackexchange.com/a/19404
There is not a dead-simple way of doing that in any platform as far as I know maybe except for some game engines/platforms that export for different platforms (cocos2d, construct 2 etc).
What you need is a physics engine whether you write one (which is a complicated but fun thing to do) or use an available one.
Luckily I've found a link describing the usage of the famous 2D physics engine "Box2D" on iOS.
This one explains how you can include Box2D in an openGL application (but you can apply this to other environments (sprite kit) I think altough I'm not an iOS guy);
http://www.iforce2d.net/b2dtut/setup-ios
Anyways, you now know what to look for...
For iOS 8.0+ : you have SKFieldNode : radialGravityField()
For iOS 8.0- : one solution could be : 3 to 9
add your sprite ( planet ) with its physics
add an invisible SKNode ( the gravity zone ) with its own physics, as a child of your sprite, but with a radius much more than your sprite's one
you have a little explanation about invisible node here : https://developer.apple.com/documentation/spritekit/skphysicsworld
both, your sprite and the invisible node are centered in a zero gravity world
we look for contact and not collision ( set correctly your bit masks )
when any object get in contact with the invisible node ( gravity zone ), first you remove any moving action or impulse from it and then we add to this object an SKAction to move it toward the center of your sprite ( planet )
at second contact between this object and your sprite ( planet ), you remove all actions again from the object with a velocity = zero

Ignoring Collisions Between Bodies in Box2d (iphone)

I have 3 types of bodies. they are
1) MouseJointBody (It is moving with mouseJoint only)
2) 2 MovingBodys (It is moving continuously in the world)
3) StaticBody (It is fixed in constant position)
I need collision between these bodies:
1) MouseJointBody with MovingBodys and StaticBody and world bounderies
2) StaticBody only with MouseJointBody
3) MovingBodys only with MouseJointBody and world bounderies
4) MovingBodys collide with each other
but don't need collide with StaticBody and MovingBody. I set filter data for these bodies like below code:
StaticBody:
fixDef.filter.categoryBits=0x0004;
fixDef.filter.maskBits= 0x0002;
MovingBodys:
fixDef.filter.categoryBits=0x0004;
fixDef.filter.maskBits= 0x0002;
MouseJointBody:
fixDef.filter.categoryBits=0x0002;
fixDef.filter.maskBits= 0x0004;
Everything working fine but my MovingBodys are not collide with eachother and MouseJointBody and MovingBody not collide with the world box. these two are going out of the world. please tell me the solution for this one.
In Farseer that is a proyect baseb in Box2D exist CollisionCategory but in Box2D to resolve different
please, review the follow discussion
the idea is to assign that body type is each, and that bodies can collide only.
in the discussiontreated a similar case, A hits B, C hits D, but A does not hits A
I think, when you use filters, you need apply filters to walls.
And set maskBits of all.
MovingBodys exemple :
fixDef.filter.categoryBits=0x0004;
fixDef.filter.maskBits= 0x0002 | 0x0006;
(0x0006 is the categoryBits of wall)