Typecasting Help

I am trying to get rid of this annoying error that keeps coming up when I pass a class object by reference in a parameter.

The body of the code is this:
1
2
3
4
5
6
7
8
9
Contact Collide( PoolTable& pt, Ball& b) {
	

	//this holds details of collision that occurred; empty if no collision occurred
	Contact collision;

	collision.object[0] = PhysicsObject(pt);

	return collision;


For reference the Contact class is defined like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Contact
{
public:
	// define variables here
	Vector3D point; //point of contact
	Vector3D normal; //contact normal
	PhysicsObject* object[2]; //represents potential of two objects colliding
	Scalar COR; //coefficient of Restitution
	Scalar penetration; //Penetration in the collision
	bool collided; //used to check if objects collided

	Contact() ;
	void Compute_Response() ;
} ;


For further clarification, I use the object pointer array in this function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Contact::Compute_Response()
{
	//calculates relative velocity of 2 objects and finds magnitude (i.e. speed) of that velocity
	Vector3D v1 = object[0]->velocity;
	Vector3D v2 = object[1]->velocity;
	Scalar m1_inverse = object[0]->inverse_mass;
	Scalar m2_inverse = object[1]->inverse_mass;
	Vector3D relative_velocity = v1 - v2;
	Scalar relative_velocity_N = relative_velocity * normal;

	//calculates impulse vector
	Scalar e = -(1 + COR);
	Scalar dV = e * relative_velocity_N;
	Scalar i = dV / (m1_inverse + m2_inverse);
	Vector3D impulse = i * normal;

	//updates momentum and velocity of objects
	object[0]->momentum += impulse;
	object[1]->momentum += impulse;
	object[0]->velocity = object[0]->momentum / object[0]->mass;
	object[1]->velocity = object[1]->momentum / object[1]->mass;
}


For a tad extra clarification, this is how each class is declared (i left out the unnecessary info that has nothing to do with problem):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Ball : public PhysicsObject
{
private:

public:
	friend Contact Collide( PoolTable&, Ball& ) ;
} ;

class PoolTable : public PhysicsObject
{
private:

public:
	friend Contact Collide( PoolTable&, Ball& ) ;
} ;

Contact Collide( PoolTable&, Ball& ) ;


In this code I get errors here:

 
  collision.object[0] = PhysicsObject(pt); //says "no suitable conversion from PhysicsObject to PhysicsObject* exists" 


What am I doing wrong?

Sidenote: I tried doing this earlier
 
collision.object[0] = pt;

That give me a pretty similar error: "no suitable conversion from PoolTable to PhysicsObject* exists"
Last edited on
If collision.object is an array of pointers, then collision.object[0] is a pointer, meaning you need the address of pt.

However, just from this small portion of code I think you have several design flaws already - but I won't explain them unless you want me to.
Try PhysicsObject(&pt);


That give me a pretty similar error: "no suitable conversion from PoolTable to PhysicsObject* exists"
Because they're not of the same type.

EDIT: Dang it, I was ninja'd.
Last edited on
Presumably collision.object is of type PhysicsObject* and you're casting to a type of PhysicsObject (no pointer).

Inheritance and polymorphism could help a bit here. If you have a class, say CollidableObject, that all objects that can collide inherit from then you could have a list of CollidableObjects, which could eliminate the need to cast at all.
@Avilius
I tried doing PhysicsObject(&pt), but it gives a new error: "no instance of constructor PhysicsObject::PhysicsObject matches the argument list".

@L B
I changed the original post to give more detail. The collision.object is an array of PhysicsObject*, which is the parent class of both the Ball and PoolTable class.

@iHutch
I am not sure I follow. I thought the Contact class was serving the purpose of a class CollidableObject by allowing for collision between the Ball and PoolTable?
I'll show you what I mean, keeping it as basic as possible. Note, I'm not using separate bounding boxes or vectors or anything. Nor am I being clever with access levels, hence the struct.

The assumptions here are that a collision box builds up and right of the position. This isn't great because it's more likely to expand from the centre of the object position but it keeps the math a little simpler. You could easily change it.

Anyway, here goes for simplicity. Hopefully it'll make some sense:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <vector>

struct CollidableObject
{
    int x, y;
    int width, height;
    virtual ~CollidableObject(){};

    void setPosition( int x, int y )
    {
        this->x = x;
        this->y = y;
    }

    void setBoxSize( int w, int h )
    {
        width  = w;
        height = h;
    }
};

class Player : public CollidableObject {};
class Enemy : public CollidableObject {};

bool checkForCollision( const CollidableObject *a, const CollidableObject *b )
{
    if( a->x + a->width < b->x || a->x > b->x + b->width ||
        a->y + a->height < b->y || a->y > b->y + b->height )
    {
        return false;
    }

    return true;
}

int main( int argc, const char* argv[] )
{
    Player* player = new Player();
    player->setPosition( 10, 10 );
    player->setBoxSize( 5, 5 );

    Enemy *enemy = new Enemy();
    enemy->setPosition( 11, 11 );
    enemy->setBoxSize( 5, 5 );

    std::cout << ( checkForCollision( player, enemy ) ? "Objects are colliding" : "Objects aren't colliding" );

    delete player;
    delete enemy;

    return 0;
}


Since we've used inheritance here, we can pass the player and enemy into the collision function easily. No casting needed.

You could store all of your collidable objects using this method in a vector and loop through to check for collisions. Ideally, you'd want something more efficient, like a kd-tree, though. That's a different story. :-)

If you did want to keep a vector of collidable objects then that's possible:
1
2
3
std::vector<CollidableObject*> collidables;
collidables.push_back( new Player() );
collidables.push_back( new Enemy() );
Last edited on
I get what you are saying mostly, but to do that I would have to create a new class for defining the collision check and derive the Ball and PoolTable classes from that object. The only problem is that these objects are already derived from the PhysicsObject class, and I do not want to go down the road of multiple inheritances as researching how to do that melted my brain. :(

I believe I am misunderstanding something basic about what I am trying to do when assigning object[0] to an object. What I understand:

-I know object[0] is a PhysicsObject*. A PhysicsObject* is a reference of a PhysicsObject
-I know PoolTable& references an object to be used in the function. We declare that object in the parameters as pt.
-pt is the instance of the PoolTable object passed in the parameters. PoolTable is a child class of PhysicsObject.
-Therefore, we should be able to set object[0] = PhysicsObject(pt) because object[0] needs to be assigned a reference of a PhysicsObject and pt is a PhysicsObject.


What important concept am I missing here?

EDIT: I think my question is, how do I change the function parameters of:
 
Contact Collide( PoolTable& pt, Ball& b) { }

so that pt is a PhysicsObject*, and not a type PhysicsObject?
Last edited on
A PhysicsObject* is a reference of a PhysicsObject

No. A PhysicsObject* is a pointer to a PhysicsObject.

PhysicsObject& is a reference to a PhysicsObject.
Mikey, you sir are AWESOME. :D

Ok, so I was able to correct the flaw in syntax by adding in PhysicsObject* pt as a private member to the PoolTable class, then declaring it in the PoolTable constructor as pt = this. Finally, I created a new pointer to store this information in the Collide function like so:
1
2
	PoolTable* TheTable = new PoolTable;
	TheTable -> pt;

Then, I changed the syntax I was originally using to collision.object[0] = TheTable;. Now, it compiles without any errors! That solves the initial problem I had before, but I only hope the logic is right for being used with the Contact function Compute_Response().
Topic archived. No new replies allowed.