Hi, I'm new to this forum and new to orx, I have some level of understanding so I can write code but it is almost always a constant struggle, I know for an example enough to consider that the typecasting in the following code might be concern since I only have a vague understanding of what type they are to begin with and even less however it is OK to typecast them. Well that some sort of presentation i guess.
I would like to use the physic engine to move my SpaceShip (sort of like comets at this stage) and after some goggling I found orxPhysics_ApplyImpulse and orxPhysics_ApplyForce that seemed to be exactly what I want. To clearify what I want to achieve I will compare to the current state of the game, there is no gravity and the player and asteroids are bodies created in the same way as the falling box in the tutorial. When the up key is pressed I use:
orxVector_Set(&speed, 0, -50, 0);
orxObject_SetRelativeSpeed(pstSpaceShipObject, &speed);
this makes the spaceship go -50 something/something, pixels/second? and continue forever with no friction. This is almost what I want but I like to have accelereation like when an impulse is applied to the SpaceShip. I guess it would be fairly easy to implement with an event loop or something but here it would be nice if this code just had worked, can it do that?
orxBODY *pstSpaceShipBody stSpaceShipBody = orxOBJECT_GET_STRUCTURE(pstSpaceShipObject, BODY);
orxVECTOR Impuls;
orxVector_Set(&Impuls, 100, 100, 1);
orxVECTOR Point;
orxVector_Set(&Point, 100, 100, 1);
orxPhysics_ApplyImpulse ( (orxPHYSICS_BODY*) pstSpaceShipBody, &Impuls, &Point );
the problem is that this code takes a orxPHYSICS_BODY as input instead of a object and I don't know how to get the orxPHYSICS_BODY from a object so I have it typecast from orxBODY, will that work? Well this code doesn't work at least a few time a bit at random this code can make the SpaceShip disappear completely together with at couple of asteroid bodies. Very strange. The next thing is rotation, now i use this line:
orxObject_SetRotation(pstSpaceShipObject, orxObject_GetRotation(pstSpaceShipObject) - 0.1f);
The SpaceShip has its center of gravity at its button center and when it hits a asteroid it will start to rotate from that impuls but this code doesn't counteract that since it just warps the SpaceShip 0.1r back. I guess this also easily can be implemented manually but it would be at bit more clean and nice if it was possible to use ApplyImpulse directly.
//AlgoJerViA
Comments
Hi AlgoJerViA and welcome here!
Hopefully the struggling phase will soon be over and things will get more and more familiar to you soon.
The units are using the SI except for distances where the pixel is used. So a speed is expressed in pixels/second.
In the end, the physics module only knows about meters that's where the Physics.DimensionRatio config parameter is useful.
By default its value is 0.01 which means 1 pixel = 0.01 meter.
So when you set your object speed to be 50 pixels/s, for the simulation it ends up being 0.5 m/s.
Also if your object size is 100 pixel, it's actually 1 meter in the physics world.
Box2D works best with object ranging size from 0.1m to 10s of meters, so it's actually good to know that you can change the ratio if need be.
Now for your acceleration, yes, you could either compute it yourself (pretty easy and you can define a callback that would get called from an orxCLOCK) or you can use ApplyImpulse/ApplyForce, but don't use orxPhysics_*, instead either use orxObject_* on your objects or orxBody_* on your bodies.
In that case you should actually call orxBody_ApplyImpulse and not orxPhysics_ApplyImpulse. By doing the casting and calling the wrong method you actually end up corrupting some memory.
You can find the whole API at http://doc.orx-project.org.
That's a result from the memory corruption.
As written above you want to call the proper function on the orxBODY.
All the functions are organized in an Object Oriented way: ie. all functions applied to an orxBODY are defined in the orxBody module, those applied to an orxOBJECT in the orxObject module and etc.
Now in for your particular example, there's even something easier. Let's look at this function: orxObject_ApplyImpulse.
That means you can write:
That will apply the impulse on your object at its center of mass as I assume that's what you wanted to do. Otherwise the impulse would have been applied to the point your specified and if it's not the center of mass it'll result in additional torque that will rotate your object.
First of all, by using the code above, no additional torque will result from your impulse so you won't need to counterbalance it.
Now about collision-induced angular velocities, what result do you want to obtain exactly? If you want collisions to never induce any torques, you can use the config property FixedRotation on your body definition but I'm not sure that's what you wanted.
If you need any more precisions or have any other questions, please let us know!
Cheers and welcome here again!
I don't want to apply the force at the center of mass but at the point where my engine will be so that's not a problem expect that it would be nice to specify that point in the ini file somehow, a simple vector variable, how do I do that?
Is the force Point vector relative to the center of mass or is it like I'm always is applying force from the center of the screen if it is set to 0,0,0?
The main problem now is the direction of force, since I want the thruster at the button of the spaceship to force in an angel of 90 degree against the spaceship but the force i specified as a vector so it is always applied in the same direction relative to the X:Y grid. I guess it is possible to rotate the vector somehow but my memory of trigonometry is a bit dim so instead I tried to first rotate the object to its initial non rotated state then I applied force and then I restored the rotation. This doesn't however rotate the force applied to it so it didn't work. If you have any suggestion how to do this in a easy way it's welcome, in the meantime I guess I should read up on the mathematics.
When I have my project setup up pretty much according to tutorial is it hardware accelerated at that stage? Is the Solider drawn using GL or DirectX or software?
//AlgoJerViA
Maybe I can help you.
You said : it would be nice to specify that point in the ini file somehow, a simple vector variable, how do I do that?
=> Very easy. I suppose that you have a section like [SpaceShip] in your config file ? This section describe your spaceship, for Orx. But you can use the function orxConfig_XXX to access all section/key/value and you can read/write your own.
So, for that, just do something like that in your ini file :
And, in you C code, just read this value like that :
Next, to rotate a vector, you just have to use the orxVector_2DRotate function. You can use the constant orxMATH_KF_DEG_TO_RAD to convert your angle from a degree value to a radian value.
Example :
For the others questions, I'm not sure.
Thanks for the appreciation, AlGoJerViA!
As for the questions faistoiplaisir didn't answer:
All the existing display plugins that you can use with orx are based on (and need) 3D acceleration. There used to be an old SDL non-3D accelerated one, but it has been removed a long time ago.
All the current plugins are using OpenGL on computers and OpenGL ES on iOS/Android.
There's no DirectX plugin available for now and I don't have any plans to write one. However if anyone want to make one, they're more than welcome to do so!
So yes, the soldier is displayed with OpenGL, every sprite is internally converted to an indexed triangle strip.
As for Force/Impulse, you should provide a position in world coordinates for now (Box2D defaults), which is not very handy so I might change it for local object coordinates instead. What do you think?
EDIT: To be clear, (0, 0, 0) wouldn't be the center of the screen but the center of the world. Which would match the center of the screen if your camera is also as the center of the world and your viewport is centered in your display (usually it covers the full display surface, by default).
- *_GetMassCenter() now return the center of mass in object space *even* when the object is scaled (wasn't working correctly with scaled object before)
- The orxBody & orxObject versions of ApplyImpulse()/_ApplyForce() now take an application point in object (ie. local) space and not in world space as before. That should be much more convenient.
- Fixed the Impulse value not being scaled to using the physics DimensionRatio (and thus being 100x too big with default DimensionRatio)
Hope that helps.
Cheers!
//AlgoJerViA