Ok. So the first step is to keep using the same logic. Don’t make it simpler. If that works, only then try to make it simpler.
Regarding beforeSimulation and afterSimulation I don’t think we need that… you are iterating all over the nodes twice. The iteration alone could be expensive when having many nodes. So I would try to avoid if possible.
Yes. Correct. If you use a flat hierarchy, then it should work with relative positioning… at least that is how PhysicsSprite work. But it is buggy. So, it is better to use World coordinates (also because that’s how PhysicsWorld works).
If so, then i have no idea what physics component will do. As you can see, now the component has less codes. And if using the old logic, then i don’t know what i can do with component codes.
We should synchronize nodes to physics before physics simulation and synchronize physics to nodes after simulation. The old codes just want to re-use Node::visit() iteration, that’s why it inserts codes into Node. I can re-use it too after the effect is correct. It is about optimization, but first, i should make the logic correct.
Yep, i just reviewed the codes of PhysicsWorld. It doesn’t think about anchor point and node tree relationship. It only works if the anchor point is center, and Node’s position is the same as world coordinate.
Now the problem is, when i get position, rotation from physics world, how can i set it to Node. Because the return value from physics is world coordinate, how can i translate to relative position and rotation and thinking about anchor point.
What I mean by that, is to use the “physics logic”. Your code is not using the same physics logic. As an example, your are using different math code.
So, the math should be the same, the algorithms should be the same.
But the workflow should be different.
If that works as expected, then feel free to simplify the math/algorithm.
the component, what should do is to use the same physics logic, but with a different workflow.
The component should be in charge doing the physics simulation, and not Node. But the the physics code should be the same.
What you are doing is 2 things at the same time:
change the workflow: from Node to Component (we need this)
Simplifying the physics code (we also need this).
But now you have some bugs… so we don’t know why… so the best thing to do, is to do one step at the time.
I couldn’t run your “physics-component-use-old-logic” branch. Whenever I run the “Node: Physics Component” test, it crashes… actually it enters into a recursive infinite loop. The function MarkSubtree enters into infinite recursion.
For the sake of clarity, what I meant is this:
There are some bugs in your branch.
But for me it is difficult to understand the cause of the bugs when the code has too many changes: a) new math code, and b) code moved from one file to another.
So in order to identify the bug, my proposal is to do the changes one step at the time: First move the physics logic from Node to ComponentPhysics2d.
And only after testing that, you should try to optimize / change/ simplify the physics/math code.
As someone who has used Cocos2d-x exclusively for the past couple of years and just started using Unity for prototyping, I do think the component model Unity uses makes a lot of sense, is simple, and integrates beautifully with their editor.
Of course there are all kinds of restraints, but if you guys manage to get anywhere near their implementation I would be ecstatic.
The way I can compose my own custom game objects by adding built-in components (majority of boilerplate design), then adding specific game behavior by attaching a script component is super easy. Like you guys have said, your equivalent scripting language wouldn’t be C#/JS but LUA/JS/etc.
Unity has black-boxed APIs but in your case that would just be an extendable C++ core? Everything could still be done in C++ programmatically as usual (including creating and setting properties on components and their parent objects), while unifying tons and making the CocosStudio editor much more capable with this new model.
But the codes can not just be put from Node to component just copy&paste. As you know, the old codes will add physics body and remove physics body directly. Now we changed to use physics component, so we should comments the codes related with physics body directly.
As you can see, now the codes is almost the same as before, the work flow is the same, and only just modify Node::updatePhysicsBodyTransform() and Node::updateTransformFromPhysics. Because these codes is something related with physics body directly, so i can not just move the codes into physics component.
Yep, the first case has some problem. I will try to fix it.
Perhaps I’m missing something, but why copying & pasting doesn’t work ?
A component, they way I see is, should be able to transform the Node in any possible way.
So, if Node has some hardcoded physics logic in it, it should be possible to copy & paste it and put it in a component… just copy & paste the logic and all the physics ivars that are needed.
If you post an example with code regarding why you can’t copy & paste the logic, I think I will be able to understand why it is not possible to reuse the same logic.
Thanks.
UPDATE:
So, what I think is needed in order to copy&paste the original code, is to add one more callback to Component… I think you need to broadcast visit. eg:
and in ComponentPhysics2d::visit you need to do something similar to updateTransformFromPhysics(parentTransform, parentFlags); .
At least that is how I would do it in order to be as compatible as possible with the previous code.
And also it gives more flexibility to other components. On the other hand, this could slow down the visit if not done correctly. Perhaps when you register a component, you pass a Hint flag saying which functions are overriden…
@ricardo
Sorry, i forgot to push my codes to remote. I think it works now.
Node::updatePhysicsBodyTransform() depends on some codes done in Node::setPhysicsBody(). Node::setPhysicsBody() and Node::addComponent() are two different ways to connect Node and physics world. And there are many codes depends on Node::setPhysicsBody().
Node has many member variables, such as _physicsBody, _physicsScaleStartX, _physicsScaleStartY and so on. These variables makes Node and physics body tightly coupled together. If we make physics component did the same way, then physics component will be tightly coupled with Node as current.
I worked out why can not drag ball in PhysicsComponentDemoPyramidStack test case. The reason are:
when Node is scaled, corresponding physics body’s mass is not re-calculated again
then grossini’s mass is more bigger than ball(grossini is scaled by 0.13, ball is scaled by 3)
Why are old codes work?
When you scaled a Node, you should scaled its corresponding physics body’s scale by yourself
As you can see
if you scaled Node before setting physics body, you should scaled it when creating the physics body
if you scaled Node after setting physics body, you should create a new physics body with scaled factor and replace old one
physics body doesn’t support scale property. But our physics integration was designed to support it(PhysicsBody::setScale()), and it doesn’t support it well.