How to share collision layer to every objects? - xna

Currently, each level has 3 layers :
background
collisions(walls, invisible walls, ground, etc)
foreground
My character sprite has 1 pixel to detect the collision.
In this character class, there is a Color[] contains every pixels of the collision layer.
I calculate the position of the Character's pixel detection, and obtain an int that i can use with the Color[] ("CharactersPixel")
if ( Color[CharactersPixel].A != 0 )
Then collision.
It works perfectly.
But the collision layer has to be used by every others objects like particles, monsters etc.
The collision layer has about 3.800.000 pixels. so the Color[] has the same.
If I add this Color[] to every objects, this will use too much RAM, right ?

You'd only add a reference to your collision layer to the objects. You are not copying the entire thing to each object. Adding a reference will not add much memory to your objects.
However, I would suggest making the collision available in some more general fashion by exposing some level data in a place accessible to any object. Perhaps you could add the data to your Game class as a property CurrentLevel with CollisionData as an accessible property.
Normally you keep the collision data separate from the actual rendering colours, and perform a more simplistic collision with boxes and the like instead that approximately match the shape of the collision data. This would in the end make it easier to calculate things like the angle which you impact the environment and calculation of appropriate physics. Pixel to pixel collisions are rare, and might also be problematic from a performance perspective.

Related

Texture baking with 3Dsmax

I'm struggling with a texture-baking process with 3DSmax software. I have a white 3D mesh with 2 image textures. I'm trying to get a diffusemap (see target_diffuse_map.jpg). To do this, I exectue the following steps:
1) Affect image-texture1 and image-texture2 to face1 and face2 of the objet.
2) Clone the object to get the white colors when baking texture.
3) unwrap UVM.
4) Rendering Texture to obtain the diffuse map.
5) Projection of the texture + white colors on the cloned object.
Please, find these steps on this small video I made: https://drive.google.com/file/d/1h4v2CrL8OCLwdeVtLmpQwD250cawgJpi/view
I obtain a bad sampled and weird diffuse map (please see obtained_diffuse_map.jpg). What I want is target_diffuse_map.jpg.
I'm I forgetting some steps?
Thank you for your help.
You need to either:
Add a small amount of "Push" in the Projection Modifier
Uncheck "Use Cage" in the Projection Options dialog, while setting a very small value for the offset
Projection Mapping works by casting rays from points on the cage towards corresponding model points on your mesh. You did not push the cage out at all, therefore rays are not well defined; rays are cast from a point toward a direction which is the exact same point. This causes numerical errors and z-fighting. The there needs to be some time amount of push so the "from" and "to" points of each ray are different giving them a well-defined direction to travel.
The second option, instead of using the cage defined in the projection modifier, is to use the offset method (you probably still need to apply projection modifier though). This method defines each rays as starting from a point defined by taking the model point of the mesh and moving outward by a fixed offset amount in the direction of the normal. The advantage is that for curved objects with large polygons, it produces less distortion because the system uses the smoothed shading normal at each point. The disadvantage you can't have different cage distances at different points of the model, for better control. Use this method for round wooden barrels and other simplistic objects with large, smooth curves.
Also, your situation is made difficult by having different parts of the model very close to each other (touching) and embedded within each other - namely how the mouth of the bottle is inside the cap and the cap it touching the base. For this case, it might make sense to break the objects apart after you have the overall UV mapping, run projection mapping separately on each one separately, and then combine the maps back together in an image editor.

ARKit only detect floor to place objects

In ARKit i can use hitTest:tapPoint types:ARHitTestResultTypeExistingPlaneUsingExtent
This works if you want to place objects on e.g. tables as types:ARHitTestResultTypeExistingPlaneUsingExtent will only detect hits within the extent of the detected plane.
It is less usefull if you want to place objects on the floor, because you need to have to walk around until ARKit has placed (or extended) a lot of planes across your floor.
ARHitTestResultTypeExistingPlane solves that issue, because you just need to have detected a small patch of your floor and can place objects everywhere. The problem is however as soon as ARKit has detected another plane that doesn't correspond to the floor (e.g. a table), every object will be placed on that higher surface.
Is it possible to control which planes are used for the hittest?
The hit testing methods return multiple results, sorted by distance from the camera. If you're hit testing against existing planes with infinite extent, you should see at least two results in the situation you describe: first the table/desk/etc, then the floor.
If you specifically want the floor, there are a couple of ways to find it:
If you already know which ARPlaneAnchor is the floor from earlier in your session, search the array of hit test results for one whose anchor matches.
Assume the floor is always the plane farthest from the camera (the last in the array). Probably a safe assumption in most cases, but watch out for balconies, genkan, etc.

is there a simple way to draw coordinates for SKnodes obstacles from images?

I am creating a game and I need to draw some obstacles on in (SKNodes), depending on the level (background image).
Let's say I have a tree, i would like to draw borders around it as in the picture below:
I will need the coordinates to create a physicsBody.
Is there a simple way to do it? (maybe a software?)
I will need to adapt the same coordinates for different devices, therefore I believe it's too complicated to manually do it.
Any ideas?
Thanks!
There is a SKPhysicsBody class method that could be of help:
+ bodyWithTexture:size:
From the description:
Use this method when your sprite has a shape that you want replicated
in its physics body. The texture is scaled to the new size and then
analyzed. A new physics body is created that includes all of the
texels in the texture that have a nonzero alpha value. The shape of
this body attempts to strike a good balance between performance and
accuracy. For example, fine details may be ignored if keeping them
would cause a significant performance penalty.
Check out this SKPhysicsBody Path Generator.
You can easily create a path as you desire with this tool (but make sure you read the rules at the top right)

XNA 3D Collision Detection for Terrain

I've been working on a basic 3D XNA game. So far I've managed to load various character models onto a larger level/world model. I've put in some basic controls which allows the user/player to move one of the characters around the world - and even implemented some collision detection using BoundingSphere/BoundingBox with other character models.
However, the character models (at the moment) are stuck in a fixed place on the Y-axis, and so my world is really just a flat plane for them to glide across.
What I want to do now is implement a gravity like force, which will allow characters to rise and fall with the flow of the terrain. I've spent a couple of hours on google searching (in vain) for some way of checking for a detailed collision between the bounding sphere of my character and the actual mesh of the world. The articles I have found all seem to explain how to use the sphere and box methods, or to implement some external physics engine (all of which seem really quite elaborate for what I want to achieve).
So my question is twofold -
Firstly, Am I approaching this in the best way? With a single large-ish model for my world?
Secondly, Is there a relatively simple way to check for the type of collision I need, using the XNA library itself, or some other library that doesn't require me to introduce an entirely new layer of physics.
NB. The models that I want to check for collisions are: Microsoft.Xna.Framework.Graphics.Model
EDIT:
I should also mention that I am not creating a single level, but a game engine which will work with various levels loaded from a Database. For this reason, I don't want to have to separately/manually define the constraints of the level. I would ideally like to load my single mesh from the database and be able to detect collisions with it as is, or alternatively automatically work out the constraints/bounding areas from the mesh data.
3d collision detection is more complex than it may seem at a glance, so using one of the prescribed methods (I.e. the BoundingSphere Object can help). Check http://msdn.microsoft.com/en-us/library/bb203906(v=xnagamestudio.10).aspx
Specifically this code block gives an idea:
static void CheckForCollisions( ref WorldObject c1, ref WorldObject c2 )
{
for (int i = 0; i < c1.model.Meshes.Count; i++)
{
// Check whether the bounding boxes of the two cubes intersect.
BoundingSphere c1BoundingSphere = c1.model.Meshes[i].BoundingSphere;
c1BoundingSphere.Center += c1.position;
for (int j = 0; j < c2.model.Meshes.Count; j++)
{
BoundingSphere c2BoundingSphere = c2.model.Meshes[j].BoundingSphere;
c2BoundingSphere.Center += c2.position;
if (c1BoundingSphere.Intersects( c2BoundingSphere ))
{
c2.ReverseVelocity();
c1.Backup();
c1.ReverseVelocity();
return;
}
}
}
}
The first answer gave you a first-pass test for detailed collision detection. You could refine that first-pass and use an AABB test. The second pass would then require a ray-triangle intersection test. Be careful since some of these will fail when the ray hits a triangle edge or vertex - so make sure that the tester code/algorithm you chose considers these. There are further modifications using quad-trees or other space-partitioning schemes to increase the speed of collision detection.
Here is a detailed description of a sphere/triangle technique I once adapted for 2D collision detection:
http://www.peroxide.dk/papers/collision/collision.pdf
I cannot say for certain that it will help you, but it may be useful for collisions with a terrain mesh and gravity. Combining that with collisions with other "characters" may be challenging, depending on exactly what it is you want to do. However, it does specifically describe how to implement gravity, and overall it is one of the simpler approaches you might take to collision detection and character physics in 3D.
As for the question of whether colliding with the entire terrain mesh is the "correct" way to go... if it is a simple mesh and you aren't resource-constrained, then sure. However, collision detection is computationally expensive, and applying it to all the triangles in your mesh may quickly become impossible. Generally, you may want to store your triangles in some efficiently searchable structure, like an octree or a k-d tree, and then do a rough search for triangles near your character which can then be tested more precisely for collisions in much less time than it would take to test every triangle in the mesh.
You could fake it. In other words, I'm assuming, at every update call you could just set the height of your player to the height of the terrain wherever the player happens to be. I imagine not the most professional way to handle things, but might work.

Surface Detection in 2d Game?

I'm working on a 2D Platform game, and I was wondering what's the best (performance-wise) way to implement Surface (Collision) Detection.
So far I'm thinking of constructing a list of level objects constructed of a list of lines, and I draw tiles along the lines.
alt text http://img375.imageshack.us/img375/1704/lines.png
I'm thinking every object holds the ID of the surface that he walks on, in order to easily manipulate his y position while walking up/downhill.
Something like this:
//Player/MovableObject class
MoveLeft()
{
this.Position.Y = Helper.GetSurfaceById(this.SurfaceId).GetYWhenXIs(this.Position.X)
}
So the logic I use to detect "droping/walking on surface" is a simple point (player's lower legs)-touches-line (surface) check
(with some safety approximation
- let`s say 1-2 pixels over the line).
Is this approach OK?
I`ve been having difficulty trying to find reading material for this problem, so feel free to drop links/advice.
Having worked with polygon-based 2D platformers for a long time, let me give you some advice:
Make a tile-based platformer.
Now, to directly answer your question about collision-detection:
You need to make your world geometry "solid" (you can get away with making your player object a point, but making it solid is better). By "solid" I mean - you need to detect if the player object is intersecting your world geometry.
I've tried "does the player cross the edge of this world geometry" and in practice is doesn't work (even though it might seem to work on paper - floating point precision issues will not be your only problem).
There are lots of instructions online on how to do intersection tests between various shapes. If you're just starting out I recommend using Axis-Aligned Bounding Boxes (AABBs).
It is much, much, much, much, much easier to make a tile-based platformer than one with arbitrary geometry. So start with tiles, detect intersections with AABBs, and then once you get that working you can add other shapes (such as slopes).
Once you detect an intersection, you have to perform collision response. Again a tile-based platformer is easiest - just move the player just outside the tile that was collided with (do you move above it, or to the side? - it will depend on the collision - I will leave how to do this is an exercise).
(PS: you can get terrific results with just square tiles - look at Knytt Stories, for example.)
Check out how it is done in the XNA's Platformer Starter Kit Project. Basically, the tiles have enum for determining if the tile is passable, impassable etc, then on your level you GetBounds of the tiles and then check for intersections with the player and determine what to do.
I've had wonderful fun times dealing with 2D collision detection. What seems like a simple problem can easily become a nightmare if you do not plan it out in advance.
The best way to do this in a OO-sense would be to make a generic object, e.g. classMapObject. This has a position coordinate and slope. From this, you can extend it to include other shapes, etc.
From that, let's work with collisions with a Solid object. Assuming just a block, say 32x32, you can hit it from the left, right, top and bottom. Or, depending on how you code, hit it from the top and from the left at the same time. So how do you determine which way the character should go? For instance, if the character hits the block from the top, to stand on, coded incorrectly you might inadvertently push the character off to the side instead.
So, what should you do? What I did for my 2D game, I looked at the person's prior positioning before deciding how to react to the collision. If the character's Y position + Height is above the block and moving west, then I would check for the top collision first and then the left collision. However, if the Character's Y position + height is below the top of the block, I would check the left collision.
Now let's say you have a block that has incline. The block is 32 pixels wide, 32 pixels tall at x=32, 0 pixels tall at x=0. With this, you MUST assume that the character can only hit and collide with this block from the top to stand on. With this block, you can return a FALSE collision if it is a left/right/bottom collision, but if it is a collision from the top, you can state that if the character is at X=0, return collision point Y=0. If X=16, Y=16 etc.
Of course, this is all relative. You'll be checking against multiple blocks, so what you should do is store all of the possible changes into the character's direction into a temporary variable. So, if the character overlaps a block by 5 in the X direction, subtract 5 from that variable. Accumulate all of the possible changes in the X and Y direction, apply them to the character's current position, and reset them to 0 for the next frame.
Good luck. I could provide more samples later, but I'm on my Mac (my code is on a WinPC) This is the same type of collision detection used in classic Mega Man games IIRC. Here's a video of this in action too : http://www.youtube.com/watch?v=uKQM8vCNUTM
You can try to use one of physics engines, like Box2D or Chipmunk. They have own advanced collision detection systems and a lot of different bonuses. Of course they don't accelerate your game, but they are suitable for most of games on any modern devices
It is not that easy to create your own collision detection algorithm. One easy example of a difficulty is: what if your character is moving at a high enough velocity that between two frames it will travel from one side of a line to the other? Then your algorithm won't have had time to run in between, and a collision will never be detected.
I would agree with Tiendil: use a library!
I'd recommend Farseer Physics. It's a great and powerful physics engine that should be able to take care of anything you need!
I would do it this way:
Strictly no lines for collision. Only solid shapes (boxes and triangles, maybe spheres)
2D BSP, 2D partitioning to store all level shapes, OR "sweep and prune" algorithm. Each of those will be very powerfull. Sweep and prune, combined with insertion sort, can easily thousands of potentially colliding objects (if not hundreds of thousands), and 2D space partitioning will allow to quickly get all nearby potentially colliding shapes on demand.
The easiest way to make objects walk on surfaces is to make then fall down few pixels every frame, then get the list of surfaces object collides with, and move object into direction of surface normal. In 2d it is a perpendicular. Such approach will cause objects to slide down on non-horizontal surfaces, but you can fix this by altering the normal slightly.
Also, you'll have to run collision detection and "push objects away" routine several times per frame, not just once. This is to handle situations if objects are in a heap, or if they contact multiple surfaces.
I have used a limited collision detection approach that worked on very different basis so I'll throw it out here in case it helps:
A secondary image that's black and white. Impassible pixels are white. Construct a mask of the character that's simply any pixels currently set. To evaluate a prospective move read the pixels of that mask from the secondary image and see if a white one comes back.
To detect collisions with other objects use the same sort of approach but instead of booleans use enough depth to cover all possible objects. Draw each object to the secondary entirely in the "color" of it's object number. When you read through the mask and get a non-zero pixel the "color" is the object number you hit.
This resolves all possible collisions in O(n) time rather than the O(n^2) of calculating interactions.

Resources