Newton Plugin for Unity 3D

Share with us how are you using the powerrrr of the force

Moderator: Alain

Re: Newton Plugin for Unity 3D

Postby Sweenie » Wed Apr 27, 2016 1:46 pm

Sounds good.

Let's start very easy this time with just the objects needed to create a world, a simple collider and the body.
Then we can verify that swig wraps the parameters right so that C# can pass and retrieve data in a effective way.
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Thu Apr 28, 2016 6:55 am

Ok Sweenie, this is what I think should be.

I commented out every thing from Newton.i

The I made a NetwonSDK.cpp class that wraper newton.
here we add all the glue to the Netwon.h, and deal with memory allocation.

then I added this to Newyon.i and swig make a nice eassy to use c chaps class.
now for here we can use that class to make out cSharp plugin.

I has no added the body, yet let us see if this works first, the I will add tow more classes
NetwonCollision.cpp and NewtonBody.cpp

do not write them yet, there is a cpp trick that I use to make it work nice with order of creation.
I use it is the custom joints.

one this this foundation is robust, the we can move on to the Joint and Managers stuff, that is much easier since they are C++ already.

Please tell me if this is a good way to go about.

if this is ok them the process is that we add to the cpp classes what we need, and we compile that script to get the c sharp equivalent.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Sweenie » Thu Apr 28, 2016 2:49 pm

This looks very promising so far.

The wrapped classes looks clean and tidy.

new NewtonSDK() create the world.
NewtonSDK.Dispose() deletes it.
The IDisposible interface will also make the GC call the Dispose() method if you forgot to call Dispose() yourself.

Since NewtonSDK inherits from MemoryAlloc the two methods __MemoryAlloc_Alloc__ and __MemoryAlloc_Free__ are exposed.
Is that intended?
To be honest I'm not really sure what they will be used for in C#.

As you can see I create an instance of NewtonSDK inside a MonoBehaviour component(I called it NewtonWorld).

Thats the only way to create an instance of NewtonSDK.

There is one other way though.

If the C++ NewtonWrapper implement these two functions...

Code: Select all
// If exported by a plugin, this function will be called when the plugin is loaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces);

// If exported by a plugin, this function will be called when the plugin is about to be unloaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload();


we get two callbacks from Unity.

That way we can have an instance of NewtonSDK ready when the plugin loads and it destroys itself when the plugin unloads.

Then we wouldn't need to have a NewtonManager or NewtonWorld gameobject in the scene to create the NewtonSDK instance.

We would instead need a function in the wrapper to acces that instance from C#.
Maybe something like GetNewtonSDK() or maybe GetNewtonWorld().

I haven't tested that setup, but in theory it should work.

That would mean both NewtonPlugin.dll and NewtonWrapper.dll are plugins.
That is, NewtonWrapper.dll would be a Native Plugin and a wrapper for NewtonPlugin.dll at the same time.
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Thu Apr 28, 2016 3:31 pm

Sweenie wrote:Since NewtonSDK inherits from MemoryAlloc the two methods __MemoryAlloc_Alloc__ and __MemoryAlloc_Free__ are exposed.
Is that intended?To be honest I'm not really sure what they will be used for in C#.


No, I just added Memoory alloc in the swig script to avoid a warning that say it does no know what MemoryAlloc. since willl never call any method on MemoryAlloc we can remove the include from swig and instead add command to supreme that warning.

on the rest of your comment, Yes if there is a way no to make NewtonWord a Unity object that will be better,
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Thu Apr 28, 2016 3:35 pm

tonight I see if I can add the rigibody. question.


do we want to expose, collision as independent objects, or does unity relates bodies to a collision tipe.

for example a Body will have a property that is a Box, or something else. but the Box is no an object is just a unknown member is the body that can be set, like for example the Mass.

some time having a collision shape as an object is useful for some algorithm by we can decide that later.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Sweenie » Thu Apr 28, 2016 4:32 pm

If you check my old colliders in the Colliders folder you can see how I made them just as types.

Like this...
Code: Select all
 [AddComponentMenu("Newton Physics/Colliders/Box Collider")]
    public class NewtonBoxCollider : NewtonCollider
    {
        //public members will be editable in the Unity Editor
        public Vector3 Size = Vector3.one;

        public override IntPtr CreateCollider(bool applyOffset)
        {
            Matrix4x4 offsetMatrix = Matrix4x4.identity;
            if (applyOffset)
                offsetMatrix.SetTRS(transform.localPosition, transform.localRotation, Vector3.one);
            IntPtr collider = NewtonAPI.NewtonCreateBox(NewtonWorld.Instance.pWorld, Size.x, Size.y, Size.z, 0, ref offsetMatrix);
            NewtonAPI.NewtonCollisionSetScale(collider, Scale.x, Scale.y, Scale.z);
            return collider;
        }
       
    }


Unity(physx) does it a bit different.

The documentation says this...
Colliders can be added to an object without a Rigidbody component to create floors, walls and other motionless elements of a scene. These are referred to as static colliders.

In general, you should not reposition static colliders by changing the Transform position since this will impact heavily on the performance of the physics engine.

Colliders on an object that does have a Rigidbody are known as dynamic colliders.

Static colliders can interact with dynamic colliders but since they don’t have a Rigidbody, they will not move in response to collisions.


I think without a Rigid Body they might actually be the same as a NewtonSceneCollision

http://docs.unity3d.com/Manual/CollidersOverview.html
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Sweenie » Thu Apr 28, 2016 5:12 pm

Regarding making NewtonWrapper.dll a Native Unity Plugin...

I was thinking something like this...

Code: Select all
#include "IUnityInterface.h"

extern NewtonSDK* sdk;

void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
   sdk = new NewtonSDK();
}

void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
   delete sdk;
}


But I suspect my code above is bad...

First I hear people say global variables is no no.

Second, class NewtonSDK is defined inside newton_wrap.cxx so I don't know how to create an instance of it from another source file.

But hopefully you understand my idea?
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Thu Apr 28, 2016 5:35 pm

Ha I see, so we make collisions type for now.


This is actually very cool,
Sweenie wrote:There is one other way though.
If the C++ NewtonWrapper implement these two functions...

Code: Select all
// If exported by a plugin, this function will be called when the plugin is loaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces);

// If exported by a plugin, this function will be called when the plugin is about to be unloaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload();


we get two callbacks from Unity.

That way we can have an instance of NewtonSDK ready when the plugin loads and it destroys itself when the plugin unloads...


but wouldn't that make the newton world in effect a singleton?

I still believe that's no necessity.
I think this scheme should work with out problems.

In the NewtonWorld.cs we add a dictionary of NewonRigidBody.cs
and each RigidBody.cs and a reference to the world it belongs too.

This make a strong connection between two to objects, that even we you destroy one the one one can no go away.

if Unity destroy the world, unit will relinquish it reference to the world, by since each body has a reference to it I will still be around.
so the function destroy iterate over each body and can relinquish reference to each body, and set the reference to 0.

if Unity destroy a body first. That body has a reference to the world, he will relinquish it reference to the world, but the world will still be around for when Unity call destroy world, so what Unity call destroy world later, the bodies that wee previously destroyed will not be on the list.

This allowed for world and bodies to be created at will,
the body will have a field that is expose to the editor, where the use can asigns the world the want.

They can even do a group select on a buck of rigid bodies and dropped in the NewtonWorld and the dictionary will be populated and as it populate each entry is Create the Body internal NewtonBody and the set the reference to the world.

To me this should be vey organic and an robust. Let me just try that tonight and see how that goes.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Sweenie » Fri Apr 29, 2016 1:23 am

Since NewtonSDK is now a disposible class, would we really need to keep track of the references ourselves? The Garbage Collector should do that for us.

Code: Select all
    [DisallowMultipleComponent]
    [AddComponentMenu("Newton Physics/Newton World")]
    public class NewtonWorld : MonoBehaviour
    {
        //Exposed to Editor
        public int SolverMode = 1;

        private NewtonSDK m_sdk = null;

        internal NewtonSDK GetNewtonSDK()
        {
            if (m_sdk == null)
            {
                m_sdk = new NewtonSDK();  // Creates a new NewtonSDK object an keeps a reference to it.
                m_sdk.SetSolverMode(SolverMode);
            }

            return m_sdk;
        }

        void FixedUpdate()
        {
            if (m_sdk != null)
                m_sdk.Update(Time.deltaTime);
        }

        void OnDestroy()
        {
            m_sdk = null; // Release reference to the NewtonSDK object;

            // Don't call m_sdk.Dispose() , bodies may still hold a reference to it.
            // m_sdk will be collected and disposed by the Garbage Collector when all Bodies released their reference to it.
        }

    }

    [DisallowMultipleComponent]
    [AddComponentMenu("Newton Physics/Newton Body")]
    public class NewtonBody : MonoBehaviour
    {
        //Exposed to Editor

        // User connects to a GameObject with a NewtonWorld in the Editor
        public NewtonWorld World = null;

        public float Mass = 1.0f;

        private NewtonSDK m_sdk = null;
        private BodySDK m_body = null;

        void Start()
        {
            if (World == null)
            {
                Debug.LogError("You must connect this body to a world.");
                return;
            }

            // If this is the first call to World.GetNewtonSDK, the NewtonWorld will create a NewtonSDK object, if not NewtonWorld will just return the already created NewtonSDK object
            m_sdk = World.GetNewtonSDK();

            m_body = m_sdk.CreateBody();
        }

        void OnDestroy()
        {
            m_body = null;
            m_body.Dispose(); // Dispose will immediately release the unmanaged resource.

            m_sdk = null; // Release reference to NewtonSDK object. If this was the last reference to the NewtonSDK object it will be disposed by the Garbage Collector.
        }

    }


This should work like you described.
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Kaos » Fri Apr 29, 2016 9:26 am

Sweenie
I dont want to take much of your time but i thought this could be helpful for you if you really want to use script execution order since it is still mentioned on the github page that youre looking for a solution.

I have more than one for you:

This one is what youre asking for thats why i put this first even if i hope you dont have to use something like this.
http://gamedevrant.blogspot.de/2013/07/ ... order.html





Awake and other are called before so you dont know when a gameobject itself makes its call or when it is exactly created but all of them should be created and initialized when used awake before unity calls start().

And the newton body can be created and should be created then in the awake() call
http://docs.unity3d.com/ScriptReference ... Awake.html

it is stated there that Initialization of objects should be done in the awake function not in start()
So actually the joint should be initialized in there too but i see the problem with ... i just pointed to let that in start if that would fail.

Awake may be called even if a script is disabled. But i dont think that this would be a problem since even if you then created the body and or joints it doesen updates or calles start when disabled so it doesen cause harm if the itself object is initialized.


And then i have another great solution on doing it with a coroutine in start().
Since awake doesent have a coroutine ;D

Edit: I made that in notepad but it should make clear what it does :D

Code: Select all
using UnityEngine;
using System;

namespace NewtonPlugin
{

    [AddComponentMenu("Newton Physics/Joints/Hinge Joint")]
    public class NewtonHinge : MonoBehaviour
    {

        IntPtr joint = IntPtr.Zero;

        private NewtonBody childBody = null;
        public NewtonBody ConnectedBody = null;

   private bool JointCreated = false;

        public float Friction;
        public bool EnableLimits;
        public float MinAngle;
        public float MaxAngle;


        void Awake()
        {
 
      if(CreateJoint())
         JointCreated = true;
        }

   
        void Start()
        {
          // for the case that joint creation didnt happen in the awake()
      if(!JointCreated ){
      
         while( !(childBody = GetComponentInParent<NewtonBody>()) )
          {   

            // you can make a coroutine in the start function so wee wait  half a second and try again
             yield WaitForSeconds( 0.5 );
          }
 
            
            CreateJoint();
         }
      }
        }
   
   void Update(){
   

   }

        void OnDestroy()
        {
            Debug.Log("Destroying hinge");
            //NewtonPlugin.DestroyJoint(joint);
        }

   bool CreateJoint(){

           Debug.Log("Creating hinge");

            childBody = GetComponentInParent<NewtonBody>();
      if(childBody == null)
         return false;


            Matrix4x4 matrix = Matrix4x4.identity;
            matrix.SetTRS(transform.position, transform.rotation, Vector3.one);

            IntPtr parentBodyPtr = IntPtr.Zero;
            if (ConnectedBody == null)   
            return false;
               
      
       parentBodyPtr = ConnectedBody.pBody;

            joint = NewtonAPI.NewtonCreateHinge(ref matrix, childBody.pBody, parentBodyPtr);
            NewtonAPI.NewtonHingeEnableLimits(joint, EnableLimits);

            NewtonAPI.NewtonHingeSetLimits(joint, MinAngle * Mathf.Deg2Rad, MaxAngle * Mathf.Deg2Rad);
            NewtonAPI.NewtonHingeSetFriction(joint, Friction);
   }

    }
}


So thats what i would try out.

Edit: the last way ..
There's also the way of making a controller object with 2 list inside where all newton objects will be registered and then the controller calls on Start() first all newton body creations and then all joints and whatever should come next.

So the compont dosent make the connection when they start the just have a function that will be called.
Kaos
 
Posts: 38
Joined: Mon Apr 18, 2016 11:24 pm

Re: Newton Plugin for Unity 3D

Postby Sweenie » Fri Apr 29, 2016 11:19 am

Based on Julios suggestion I think we will do something like this.

Image

Explanation comes later, I have to go buy some food now. :)
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Kaos » Fri Apr 29, 2016 11:55 am

No explanation needed.

Have a nice Evening.
Kaos
 
Posts: 38
Joined: Mon Apr 18, 2016 11:24 pm

Re: Newton Plugin for Unity 3D

Postby Sweenie » Fri Apr 29, 2016 1:51 pm

I like to draw schematics because it's helps me get an abstract view of the situation.

In the image I've placed the NewtonWorld as a component(MonoBehaviour) in a Game Object.
Pros: The Component can expose Editor parameters for setting SolverMode, Update timings etc. World stuff.
Cons: The user world have to add the world(or worlds) to the scene and assign it to every NewtonBody.
Some automations could be made. For example if the scene only has one world, the NewtonBody component could automatically find the WorldComponent and attach to it(by using the OnValidate() method).

Another method could be to create a Static class(not a Game Object or a MonoBehavior) that manage the Worlds. That static class create the worlds. Similar to what I described earlier.

Pros: The user wouldn't have to create any World components in the scene.
For handling multiple worlds, some kind of World ID would probably be needed.

Cons: It would be trickier to expose individual world settings for each world.

In the image I also modelled the joint as a component placed individually inside a Game Object.
Looking at how Unity/Physx does it, they actually don't allow you to do that.
The joint component can only be placed in the same Game Object as a Rigid Body.
There actually is an attribute for that [RequireComponent].

If you add the attribute [RequireComponent(NewtonBody)] to the JointComponent and the User add the jointcomponent to an Empty GameObject, the Editor will automatically add an NewtonBody as well.
If you try to remove the NewtonBody from the GameObject it won't let you until you remove the JointComponent.

It actually makes sense. You can't create a NewtonJoint without at child RigidBody.
It's only the parent body that is optional.

So in my image, the JointComponent should actually move in together with the NewtonBody component.

And the rules are.
If the joint is destroyed, only the joint goes.
If the body is destroyed, both the body and joint goes.
Last edited by Sweenie on Fri Apr 29, 2016 1:52 pm, edited 1 time in total.
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Fri Apr 29, 2016 1:52 pm

Sweenie wrote:Based on Julios suggestion I think we will do something like this.

Image

Explanation comes later, I have to go buy some food now. :)


yes precisely. 8)
I di not had time to look at the code you committed, but looking at the class.
Code: Select all
 public class NewtonBody : MonoBehaviour
    {
        //Exposed to Editor

        // User connects to a GameObject with a NewtonWorld in the Editor
        public NewtonWorld World = null;

        public float Mass = 1.0f;

        private NewtonSDK m_sdk = null;
        private BodySDK m_body = null;

this would work, and is probably the easiest way, but from the user of the plug in may not be the most user friendly interface.
I think that implemented forces the user to keep browsing the unity explorer to connect word for bodies.

if you instead put the references to the NewtonWorkd and in the NewtonWorkd we place a dictionary of NewtonBody references, functional is the same, but the user has more friendly we to inspect a scene.
Cons: The user world have to add the world(or worlds) to the scene and assign it to every
NewtonBody.
IT does no solve the that probe 100% but it goes a long way to make friendly, and we get the benefit of the component solutions.
This also allow for easy way to have more than one world without conflicts.

he can for example group select to add or remove objects from the world, or he can do one at a time.
I assume Unity expose thing like Vector and dictionaries to the editor.
The way you set is good for Joint, because joint only link tow objects, but I also has an idea for that which I explain later when we are ready for joints.

And I am getting wrong?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Sweenie » Fri Apr 29, 2016 3:06 pm

Hmm, do you mean like this?

User selects a group of bodies
Image

and drag them onto the Bodies array in the Newton World component.
Image

That would work for a couple of bodies but what if you need to handle 100 bodies?
The list would be very very long.
Also, you can add the same reference several times, so we would need to filter out duplicates in the OnValidate method.

My method would work like this.

Select the Bodies
Image

and click on the reference button.
Pick the world you want and all the selected bodies will reference that world.(Multi assign)
Image
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

PreviousNext

Return to User Gallery

Who is online

Users browsing this forum: No registered users and 11 guests

cron