Announcement

Collapse
No announcement yet.

3D Object Collisions Help

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 3D Object Collisions Help

    Not sure if this is the correct site to ask about this kind of thing, but the ps2dev forums account registration email script is broken. So this is the only place I am able to ask.

    I have modded the ps2sdk sample called "cube" so that I could rotate and move around objects. I want to be able to have objects collide instead of meshing into one another. I wrote a function that works partially. It reads 3 X,Y,Z coordinate points from the mesh_data.c and compares them with all the triangles from the same VECTOR array. Then grabs the next 3 X,Y,Z's and does the same until it reaches, in this case, 24 or greater.

    From there is compares the first X,Y,Z point with the other 3 points in the following way to determine if the X value is within or touching any of those X values. I will call the first X,Y,Z values X1, Y1, Z1 and the following 3 points (XX1,YY1,ZZ1), (XX2,YY2,ZZ2), (XX3,YY3,Z33).
    So if (XX1 <= X1 <= XX2) or (XX2 <= X1 <= XX3) or (XX3 <= X1 <= XX1) then X1 is within or touching another points X axis. Then do the same for Y and Z. If they all return true then there is a collision. I did that for X1 - X3 and XX1 - XX3 (like so: X1 <= XX1 <= X2).

    This works well if the rotation is 0. But if it isn't I fall into a problem. What I ended up doing is making 2 new matrices and assigning 4 values identical to the position of both objects (mat1 and mat2). Then used the function matrix_rotate() with the values of object_rotation (Both cubes use the same rotation so I can have parallel lines).

    This fixed half the problem. Now my problem is when I rotate horizontally; the cube can pass through the other cube. If I keep the Z axis equal for both objects then I can spin vertically and the cube will not pass through the other cube. But when I move it up or down does it pass through the other cube.

    I have an attachment to this post with the source code. If anyone wants to look/help, you can download it and do so.

    The controls are like so:
    DPAD UP = Rotate both cubes up
    DPAD DOWN = Rotate both cubes down
    DPAD LEFT = Spin both cubes left
    DPAD RIGHT = Spin both cubes right
    R-Stick UP = Move cube on the right (initially) up
    R-Stick DOWN = Move cube on the right (initially) down
    R-Stick LEFT = Move cube on the right (initially) left
    R-Stick RIGHT = Move cube on the right (initially) right

    P.S. the pad.c is a collection of pad functions taken directly from cYs Driver's Cora Dumper. Credit is his. I threw my loadmodules function in there as well.

    Thanks.

    EDIT1: Fixed the problem by making it check each triangle instead of the first 3 X,Y,Z's and then the next 3. Now it reads the first 3 (0, 1, 2), then the second 3 (1, 2, 3) and so on until 24.
    Now I want to ask if there is an alternative to this? I find this to be fine for something like a cube. But the teapot (from the ps2sdk sample) has 1,598 vertices. I haven't tryed yet but I get the feeling that would take a while longer.

    EDIT2: Another thing to know, if you change the matrix_rotate(mat1, mat1, object_rotation); to matrix_rotate(mat1, mat1, object_rotation2); (cube2's rotation values). Then change the PadReadMoveRotate function to rotate the objects individually. Then if you rotate the cubes so that one cube touches the other cubes corner; it continues into the cube for a bit. Now sure why that is. Here is an example of how I set the PadReadMoveRotate function for that. L1 + dpad rotates the left cube and R1 + dpad rotates the right cube. Start + Select to reset the cubes.

    Code:
     void PadReadMoveRotate(void) {
     
    	int CollideChecker = 0;
    	float old1, old2, old3, old4, old5;
    	old1 = object_rotation[0];
    	old2 = object_rotation2[0];
    	old3 = object_position2[0];
    	old4 = object_position2[1];
    	old5 = object_position2[2];
     
    	if (padRead(0, 0, &buttons));
    	{
    		paddata = 0xffff ^ buttons.btns;
    		new_pad = paddata & ~old_pad;
    		old_pad = paddata;
    		
    		if (paddata & PAD_UP && paddata & PAD_L1) //Rotate left cube (1st cube)
    		{	
    			object_rotation[0] += -0.010f; while (object_rotation[0] > 3.14f) { object_rotation[0] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_UP && paddata & PAD_R1) //Rotate right cube (2nd cube)
    		{	
    			object_rotation2[0] += -0.010f; while (object_rotation[0] > 3.14f) { object_rotation[0] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_DOWN && paddata & PAD_L1) //Rotate left cube (1st cube)
    		{
    			object_rotation[0] += 0.010f; while (object_rotation[0] > 3.14f) { object_rotation[0] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_DOWN && paddata & PAD_R1) //Rotate right cube (2nd cube)
    		{
    			object_rotation2[0] += 0.010f; while (object_rotation2[0] > 3.14f) { object_rotation2[0] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_LEFT && paddata & PAD_L1) //Rotate left cube (1st cube)
    		{
    			object_rotation[1] += -0.010f; while (object_rotation[1] > 3.14f) { object_rotation[1] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_LEFT && paddata & PAD_R1) //Rotate right cube (2nd cube)
    		{
    			object_rotation2[1] += -0.010f; while (object_rotation2[1] > 3.14f) { object_rotation2[1] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_RIGHT && paddata & PAD_L1) //Rotate left cube (1st cube)
    		{
    			object_rotation[1] += 0.010f; while (object_rotation[1] > 3.14f) { object_rotation[1] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    		
    		if (paddata & PAD_RIGHT && paddata & PAD_R1) //Rotate right cube (2nd cube)
    		{
    			object_rotation2[1] += 0.010f; while (object_rotation2[1] > 3.14f) { object_rotation2[1] -= 6.28f; }
    			
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_rotation[0] = old1;
    			object_rotation2[0] = old2;
    			}
    		}
    	
    		x = 0;
    	
    		//Reset both objects
    		if (new_pad & PAD_START && new_pad & PAD_SELECT)
    		{
    			ResetObjects();
    		}
    	
    		if(buttons.rjoy_h > 0xf0) 
    		{
    			object_position2[0] += 0.10f;
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_position2[0] = old3;
    			}
    		}
    		
    		if(buttons.rjoy_h < 0x10) 
    		{
    			object_position2[0] -= 0.10f;
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_position2[0] = old3;
    			}
    		}
    		
    		if(buttons.rjoy_v > 0xf0) 
    		{
    			object_position2[1] -= 0.10f;
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_position2[1] = old4;
    			}
    		}
    		
    		if(buttons.rjoy_v < 0x10) 
    		{
    			object_position2[1] += 0.10f;
    			CollideChecker = CheckForCollision();
    			if (CollideChecker != 0) {
    			object_position2[1] = old4;
    			}
    		}
    	
    	}
    		
     }
    Last edited by dnawrkshp; 11-24-2012, 03:51:10 PM. Reason: Fixed problem

  • #2
    I also want to have a struct called Object in which I can store/load specific parameters for certain 3D objects. That will allow me to shorten the DrawObject function to just the objects position, rotation, and the object. I tried this and I get the error "cube.c:58: parse error before '->' token".

    Code:
     typedef struct {
    	VECTOR vertices;    //Object's vertices
    	int vertcount;      //# of vertices
    	int point;          //Object's points
    	int pointcount;     //# of points
    	VECTOR colour;      //Object's colours
    	VECTOR normal;      //Object's normals
    	VECTOR hitbox;      //Object's outline - used to check for collision (can be the same as the vertices)
     } Object;
     
     Object Cube1;
     Cube1->vertices = vertices;
    What am I doing wrong? Thanks.
    Last edited by dnawrkshp; 11-24-2012, 06:39:46 PM.

    Comment


    • #3
      The -> operator is for dereferencing a pointer to a struct/class. All you did was declare the instance Cube1, so you'd have to use the . operator.

      Comment


      • #4
        Okay that works thanks.
        Last edited by dnawrkshp; 11-25-2012, 07:16:08 PM.

        Comment

        Working...
        X