[CLOSED] - Farseer Phsyics Integration - Any pointers?
by Ron Barbosa · in Torque X 2D · 07/29/2010 (12:51 pm) · 234 replies
Hey all...I've just recently started looking at some demos and videos for Farseer Physics.
I was curious if anyone here had done or is considering a Farseer integration with TorqueX. If so, how's it going for you?
I am admittedly ignorant in the use of the physics engine, so I have no idea where to begin...but I'm just curious if folks are even trying this and whether or not it integrates fairly simply or if it will detract too much attention from my game build.
I don't want to take a 2-month detour from my game project just to integrate the physics. My game project is going to be a value proposition. I want to sell it cheap and see if I can push volume...so if it doesn't have a proper physics implementation, or uses only the TX physics...that's ok. But if I can spend a couple of weeks or a month on the Farseer integration...that might help push sales volume.
Thanks!
--RB
I was curious if anyone here had done or is considering a Farseer integration with TorqueX. If so, how's it going for you?
I am admittedly ignorant in the use of the physics engine, so I have no idea where to begin...but I'm just curious if folks are even trying this and whether or not it integrates fairly simply or if it will detract too much attention from my game build.
I don't want to take a 2-month detour from my game project just to integrate the physics. My game project is going to be a value proposition. I want to sell it cheap and see if I can push volume...so if it doesn't have a proper physics implementation, or uses only the TX physics...that's ok. But if I can spend a couple of weeks or a month on the Farseer integration...that might help push sales volume.
Thanks!
--RB
#82
I think I'm going to have to add a positioning type data member, and then a Vector2 to reflect the value. PositionType might be defined like so:
If you choose one of the predefined types, the component can calculate the anchor based on the dimensions and position of the SceneObject. The predefined types would basically represent the cardinal directions relative to the SceneObject.
If you choose, SceneObject, the anchor will be positioned at the SceneObject's position.
Choosing Offset will require you to put a value into the vector parameter, and will calculate the position relative to the SceneObject.
Choosing Absolute will require you to put a value into the vector parameter, and it will position the anchor at the position you plug in there.
These are just my brain droppings, but maybe you guys can offer some feedback as to whether or not you think this is sound reasoning.
Thanks
--RB
08/20/2010 (11:55 am)
Just some thinking out loud. I have to expose a bunch of anchor and positioning vectors for the joints and springs. But many of them you might want to be set either AT the SceneObject position or relative to the SceneObject position. Problem with this is that TXB doesn't have a way to reflect the SceneObject's position in the component configuration.I think I'm going to have to add a positioning type data member, and then a Vector2 to reflect the value. PositionType might be defined like so:
public enum PositionType
{
SceneObject,
Offset,
Absolute
// Predefined points that will be calculated by the component
Top,
Right,
Bottom,
Left,
TopRight,
TopLeft,
BottomRight,
BottomLeft
}If you choose one of the predefined types, the component can calculate the anchor based on the dimensions and position of the SceneObject. The predefined types would basically represent the cardinal directions relative to the SceneObject.
If you choose, SceneObject, the anchor will be positioned at the SceneObject's position.
Choosing Offset will require you to put a value into the vector parameter, and will calculate the position relative to the SceneObject.
Choosing Absolute will require you to put a value into the vector parameter, and it will position the anchor at the position you plug in there.
These are just my brain droppings, but maybe you guys can offer some feedback as to whether or not you think this is sound reasoning.
Thanks
--RB
#83
08/20/2010 (1:17 pm)
Would it be possible to add Linkpoint to the PositionType list?
#84
I'll check it out and if it gets too involved, I may leave it for a subsequent pass.
I'm trying to do things in sprints...so the first sprint was getting you guys the components. The second sprint was to tighten the integration between T2D native classes and Farseer components.
This current sprint is the exposure of more of the configurable native Farseer options to TXB (some of that stuff went out in my last submission).
I don't know if link points qualifies as part of this pass...but if it's easily done then I will certainly roll it in. If not...I'll add it to my to-do list.
Good call, for sure!
--RB
08/20/2010 (1:25 pm)
@Charles Marshall...Good call...it would be a little bit more involved to derive the value, but it could certainly be done and would be very valuable.I'll check it out and if it gets too involved, I may leave it for a subsequent pass.
I'm trying to do things in sprints...so the first sprint was getting you guys the components. The second sprint was to tighten the integration between T2D native classes and Farseer components.
This current sprint is the exposure of more of the configurable native Farseer options to TXB (some of that stuff went out in my last submission).
I don't know if link points qualifies as part of this pass...but if it's easily done then I will certainly roll it in. If not...I'll add it to my to-do list.
Good call, for sure!
--RB
#85
I was going to look around in there but don't want to necessarily duplicate your efforts.
08/20/2010 (9:29 pm)
Ron aren't there collision material properties like kinetic and static friction? So that when my box hits the "floor" it doesn't keep sliding as if on ice?I was going to look around in there but don't want to necessarily duplicate your efforts.
#86
FrictionCoefficient & RestitutionCoefficient were exposed to TXB in the latest submission.
If you sync up, you should find those.
There are tons more properties to expose, and I'm trying to prioritize them based on what I see in samples and from working through the code.
If anyone knows of a property that they've seen in Farseer that's not yet exposed and is really important, post it here and I'll push it up on the priority list.
I'm very much learning what Farseer has to offer as I thumb through the code.
@Henry...let me know if these help. For anything that has a default value in Farseer, I'm trying to use the same default value for TXB.
Thanks,
--RB
08/20/2010 (10:04 pm)
@Henry...in the most recent submission, I included some collision properties (most collision-related items are in the FSGeomComponent) that will help you out with that problem.FrictionCoefficient & RestitutionCoefficient were exposed to TXB in the latest submission.
If you sync up, you should find those.
There are tons more properties to expose, and I'm trying to prioritize them based on what I see in samples and from working through the code.
If anyone knows of a property that they've seen in Farseer that's not yet exposed and is really important, post it here and I'll push it up on the priority list.
I'm very much learning what Farseer has to offer as I thumb through the code.
@Henry...let me know if these help. For anything that has a default value in Farseer, I'm trying to use the same default value for TXB.
Thanks,
--RB
#87
Download the latest version for the fix.
--RB
08/20/2010 (11:03 pm)
Oops...I added a bug into the FSPhsyicsManagerComponent.Download the latest version for the fix.
--RB
#88
The anchoring can get very complex when you're trying to communicate the values through TorqueX builder.
You might want to refer back to my message #82 in this thread. In that message I discussed PositionType enumerator. Once I got into the implementation, it got a little more complicated.
Basically, there are cases where you want the values to be relative to the SceneObject that holds the component (this is almost always the case when using Fixed joints and springs). But when using the dynamic joints and springs, you might want the positions to be relative to the body you're anchoring TO. So in addition to the above items indicated in the enumerated type (comment #82), I've also added:
That way you can decide to set position relative to the component holder, or the object to which it is anchored.
Clear as mud?
;)
--RB
08/21/2010 (2:21 am)
Hey all...just to give an update. I'm working on exposing some of the joint and spring properties, and one of the key components to making those things go is to have proper anchoring of your joints and springs.The anchoring can get very complex when you're trying to communicate the values through TorqueX builder.
You might want to refer back to my message #82 in this thread. In that message I discussed PositionType enumerator. Once I got into the implementation, it got a little more complicated.
Basically, there are cases where you want the values to be relative to the SceneObject that holds the component (this is almost always the case when using Fixed joints and springs). But when using the dynamic joints and springs, you might want the positions to be relative to the body you're anchoring TO. So in addition to the above items indicated in the enumerated type (comment #82), I've also added:
TheirObject, TheirOffset, TheirTop, TheirRight, TheirBottom, TheirLeft, TheirTopRight, TheirTopLeft, TheirBottomRight, TheirBottomLeft
That way you can decide to set position relative to the component holder, or the object to which it is anchored.
Clear as mud?
;)
--RB
#89
Those 2 changes in and of themselves are not really valuable, so I modified the FSRevoluteJointComponent to give you an idea of the reason behind the update.
Now, in the FSRevJointComp, you'll notice there's an AnchorType and Anchor vector. The AnchorType is an FSPositionType variable. The default value is "OurObject" which anchors the joint to the SceneObject's position. There are several different values for AnchorType, and they could all influence the anchor position of the joint. If you set it to Absolute, then the value in Anchor becomes the pivot point of the revolute joint. OurOffset will add the SceneObject's position to the value in Anchor and THAT will be the pivot point. There are presets for top, bottom, left, etc. That satisfies most conditions for fixed joint types.
For the dynamic types, those same AnchorTypes apply, but you also have "TheirObject" which will position the pivot point of the joint at the position of the SceneObject set in the "Body" property. TheirOffset will add the value of Anchor to the position of the SceneObject in the "Body" property. Then you also have TheirTop, TheirBottom, TheirLeft, etc.
Refer back to comments #82 and #88 for more background. It's late, and I'm sleepy.
Hope some of this makes sense...
--RB
08/21/2010 (3:51 am)
@All...I've made some updates to the Farseer integration. I've added a new enumerated type FSPositionType and a utility for interpreting the FSPositionTypes in a meaningful way.Those 2 changes in and of themselves are not really valuable, so I modified the FSRevoluteJointComponent to give you an idea of the reason behind the update.
Now, in the FSRevJointComp, you'll notice there's an AnchorType and Anchor vector. The AnchorType is an FSPositionType variable. The default value is "OurObject" which anchors the joint to the SceneObject's position. There are several different values for AnchorType, and they could all influence the anchor position of the joint. If you set it to Absolute, then the value in Anchor becomes the pivot point of the revolute joint. OurOffset will add the SceneObject's position to the value in Anchor and THAT will be the pivot point. There are presets for top, bottom, left, etc. That satisfies most conditions for fixed joint types.
For the dynamic types, those same AnchorTypes apply, but you also have "TheirObject" which will position the pivot point of the joint at the position of the SceneObject set in the "Body" property. TheirOffset will add the value of Anchor to the position of the SceneObject in the "Body" property. Then you also have TheirTop, TheirBottom, TheirLeft, etc.
Refer back to comments #82 and #88 for more background. It's late, and I'm sleepy.
Hope some of this makes sense...
--RB
#90
It does not require 2 bodies at all. Here's what you can do to get started.
The problem with the default values is that they vary wildly between fixed and dynamic angle springs. The dynamic angle springs defaults to 400 in the code form SpringConstant. Kinda sucks. So I chose a value that worked well for the dynamic springs while I was experimenting. It wasn't until I went through all of the Farseer demo code that I found these rather large values in there.
Hope that helps...
--RB
08/21/2010 (3:56 am)
@Aaron...With the new updates in the latest submission, I managed to get the fixed angle spring component to work.It does not require 2 bodies at all. Here's what you can do to get started.
- Set up your sandbox...we've been through this piece before.
- Add a horizontally oriented rectangular body with a geom.
- Add an FSRevoluteJointComponent. Set IsFixed to true, and set the AnchorType to "OurLeft" or "OurRight" (your choice).
- Add an FSAngleSpringComponent. Set IsFixed to true, and here's where I think we went awry. The SpringConstant value needs to be huge. Set it to 1,000,000. The DampingConstant also needs to be much higher. Use 5,000.
- Add another body with a geom above it, so it will fall and land on the spring.
The problem with the default values is that they vary wildly between fixed and dynamic angle springs. The dynamic angle springs defaults to 400 in the code form SpringConstant. Kinda sucks. So I chose a value that worked well for the dynamic springs while I was experimenting. It wasn't until I went through all of the Farseer demo code that I found these rather large values in there.
Hope that helps...
--RB
#91
--RB
08/22/2010 (4:08 pm)
[OOPS - DISREGARD THIS POST...I HAD A STUPIDITY LEAK...THE LEAK HAS BEEN PLUGGED]--RB
#92
08/22/2010 (4:27 pm)
I like the new updates Ron! Would have never guessed to use values so large with the spring and damping constant. :-) Thanks so much!
#93
I'm exposing most of the common properties that are shared by all joints and springs, and adjusting the class hierarchy so that all FS*JointComponents and all FS*SpringComponents inherit from common abstract components.
Stay tuned...
--RB
08/22/2010 (4:56 pm)
@Aaron...glad you're finding the updates useful. I've got a few more going in today that will improve the flexibility and tunability of the joints and springs.I'm exposing most of the common properties that are shared by all joints and springs, and adjusting the class hierarchy so that all FS*JointComponents and all FS*SpringComponents inherit from common abstract components.
Stay tuned...
--RB
#94
Softness is a floating point value that provides some flexibility in the joints soft or stiffness. This value is usually pretty small. All the sample code I saw has values between 0.01 and 0.05. I has originally chosen a default value of 0.03 to split the difference...but WOW...this totally broke my sandbox level. So I decided on a default value of 0.01 and things seem to work as they did before I made these changes.
[UPDATE] It turns out the default Softness for all joint types is 0.0. So this is the default value that I will use when I actually submit these changes.
I'll be cleaning up the code and packaging this stuff and sending it out for Pino to give it the once over. Another set of eyes never hurt a code a submission. ;)
Springs will get the same treatment...during the course of the week. I'll be back at work come Monday so it might be slow going. Hopefully by Thursday, the springs will have all the base properties exposed.
Once that's done, I'll be moving on to either abnormal bodies and geoms (polygonal geometry) or collision categorization. Not sure which I'll be tackling first.
I'll post when the new updates are submitted.
In general, when I make updates to the code, I'll try to provide details here, but there's no substitute for the authoritative manual. So if you see a parameter, and you don't know what it means, be sure to read the manual for an explanation.
--RB
08/22/2010 (6:16 pm)
Okay...I've been working on exposing as many of the base Farseer Joint properties to TXB as I could find in the code and docs. I'm about ready to send my stuff off to Pino for a code review. The changes are small, but noticeable. Specifically when it comes to joint softness.Softness is a floating point value that provides some flexibility in the joints soft or stiffness. This value is usually pretty small. All the sample code I saw has values between 0.01 and 0.05. I has originally chosen a default value of 0.03 to split the difference...but WOW...this totally broke my sandbox level. So I decided on a default value of 0.01 and things seem to work as they did before I made these changes.
[UPDATE] It turns out the default Softness for all joint types is 0.0. So this is the default value that I will use when I actually submit these changes.
I'll be cleaning up the code and packaging this stuff and sending it out for Pino to give it the once over. Another set of eyes never hurt a code a submission. ;)
Springs will get the same treatment...during the course of the week. I'll be back at work come Monday so it might be slow going. Hopefully by Thursday, the springs will have all the base properties exposed.
Once that's done, I'll be moving on to either abnormal bodies and geoms (polygonal geometry) or collision categorization. Not sure which I'll be tackling first.
I'll post when the new updates are submitted.
In general, when I make updates to the code, I'll try to provide details here, but there's no substitute for the authoritative manual. So if you see a parameter, and you don't know what it means, be sure to read the manual for an explanation.
--RB
#95
Exposing those values to TXB is trying to enforce a universal default which might not be "valid" in that it may be a different value than the one that is implicitly being set in all of our collective sandboxes.
In other words...exposing these under a single default value might break some aspects of your current levels.
I'm going to try to either find happy mediums or tune these things as close to what the code provides for defaults as possible.
On the good side...most of the Spring work is done, so it won't have to wait until next week.
More to come...
--RB
[UPDATE] Upon further investigation, it looks like there's only one odd man out. It's the FixedRevoluteJoint...its default BiasFactor is 0.8 where all other joints are 0.2. Kinda sucks, because I can't trigger off of the check box in TXB and set the appropriate default.
[UPDATE PART DEUCE] Okay...I don't love this solution, but without source code for TXB, I couldn't think of anything more elegant. Since the only affected joint type that uses a different default bias factor is the FixedRevoluteJoint, and since both the RevoluteJoint and FixedRevoluteJoint are combined into FSRevoluteJointComponent (didn't I say early on that some of these design decisions might prove to be bad?), here's what's going to happen.
In the FSRevoluteJointComponent, there is a new property, FSRevoluteJointComponent.UseDefaultBias. It's exposed to TXB and defaults to true. When this check box is checked, it ignores the value in BiasFactor (not currently exposed in the build you guys are running) and uses the default of 0.2 (for RevoluteJoint) and 0.8 (for FixedRevoluteJoint).
It's not elegant, but it solves the problem and maintains the current default behavior so our collective sandboxes shouldn't break when we update to the latest code.
08/22/2010 (7:53 pm)
Hmmmm...an addendum to my last note. It turns out, there's no single reliable default value for many of these properties. All of the values are tuned in the Joint and Spring factories to give decent defaults to the individual spring types.Exposing those values to TXB is trying to enforce a universal default which might not be "valid" in that it may be a different value than the one that is implicitly being set in all of our collective sandboxes.
In other words...exposing these under a single default value might break some aspects of your current levels.
I'm going to try to either find happy mediums or tune these things as close to what the code provides for defaults as possible.
On the good side...most of the Spring work is done, so it won't have to wait until next week.
More to come...
--RB
[UPDATE] Upon further investigation, it looks like there's only one odd man out. It's the FixedRevoluteJoint...its default BiasFactor is 0.8 where all other joints are 0.2. Kinda sucks, because I can't trigger off of the check box in TXB and set the appropriate default.
[UPDATE PART DEUCE] Okay...I don't love this solution, but without source code for TXB, I couldn't think of anything more elegant. Since the only affected joint type that uses a different default bias factor is the FixedRevoluteJoint, and since both the RevoluteJoint and FixedRevoluteJoint are combined into FSRevoluteJointComponent (didn't I say early on that some of these design decisions might prove to be bad?), here's what's going to happen.
In the FSRevoluteJointComponent, there is a new property, FSRevoluteJointComponent.UseDefaultBias. It's exposed to TXB and defaults to true. When this check box is checked, it ignores the value in BiasFactor (not currently exposed in the build you guys are running) and uses the default of 0.2 (for RevoluteJoint) and 0.8 (for FixedRevoluteJoint).
It's not elegant, but it solves the problem and maintains the current default behavior so our collective sandboxes shouldn't break when we update to the latest code.
#96
The fact this exists should be brought up in the XNA forums, bring some more converts to TX.
08/22/2010 (8:26 pm)
Pino, do you think this would beter served as it's own project as opposed to being part of TX2D? That would make it more portable and allow it to be distributed without TX source no?The fact this exists should be brought up in the XNA forums, bring some more converts to TX.
#97
There's very little overlap that touches anything outside the "FarseerEngine" folder under the TX2D project.
The binary users would also need to have a reference to the Farseer DLLs, but those are pretty readily available.
I'm going to remain focused on the current flow, which is part of the Torque X community repo, but if anyone has some spare cycles, I can provide guidance as far as how to extract this stuff into its own project and get it working.
If anyone's interested, send me an email. My email address is public visible in my profile.
--RB
08/22/2010 (8:44 pm)
@Henry...it shouldn't be too hard for anyone with the source access to extract these components and make a DLL out of them.There's very little overlap that touches anything outside the "FarseerEngine" folder under the TX2D project.
The binary users would also need to have a reference to the Farseer DLLs, but those are pretty readily available.
I'm going to remain focused on the current flow, which is part of the Torque X community repo, but if anyone has some spare cycles, I can provide guidance as far as how to extract this stuff into its own project and get it working.
If anyone's interested, send me an email. My email address is public visible in my profile.
--RB
#99
08/22/2010 (9:01 pm)
@Henry I agree. If TX has Farseer in it more people would buy it.
#100
In the current implementation all joints and springs are unbreakable. With this update, you'll have an "Unbreakable" flag (defaults to true which is what you all have now implicitly) and a "Breakpoint" value.
If the Unbreakable flag is set, then Breakpoint is ignored...kinda...it's actually set to the maximum floating point value which makes the joint/spring unbreakable.
If Unbreakable is false, then you plug a value into Breakpoint. When JointError or SpringError (calculated by the physics engine) is greater than Breakpoint, the joint or spring will break and the connection that the joint represents will be severed.
Hopefully I didn't introduce any bugs...when Pino's done reviewing...I'll submit ASAP.
Enjoy...
--RB
08/22/2010 (9:08 pm)
I've just sent the joint and spring updates off for code review. One note I forgot to mention...this update includes joint and spring breakability.In the current implementation all joints and springs are unbreakable. With this update, you'll have an "Unbreakable" flag (defaults to true which is what you all have now implicitly) and a "Breakpoint" value.
If the Unbreakable flag is set, then Breakpoint is ignored...kinda...it's actually set to the maximum floating point value which makes the joint/spring unbreakable.
If Unbreakable is false, then you plug a value into Breakpoint. When JointError or SpringError (calculated by the physics engine) is greater than Breakpoint, the joint or spring will break and the connection that the joint represents will be severed.
Hopefully I didn't introduce any bugs...when Pino's done reviewing...I'll submit ASAP.
Enjoy...
--RB
Torque Owner Ron Barbosa
Disposable Fun
When I first built the component, I was surprised myself to find that it didn't seem to be fixed at its world position. I think this spring type needs an offset from the SceneObject position in order to be properly anchored.
As I just made a pass over the FSPhysicsManager, FSBodyComponent, and FSGeomComponent to expose more public properties, I will be doing the same with the joints and springs this weekend. I will start with the springs since there are fewer variations. Hopefully once I've exposed the properties to let you tune it just right, things will fall into place.
I'll keep this thread updated with my progress.
--RB