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 Kaos » Sun Apr 24, 2016 8:47 pm

newton will destroy alreadyr

That may some reason why i had some freezes when quiting unity!?

Hmm that is a problem since you use ref/ Pointers isnt it?
That is clearly the reason why humans have made managed languages ;D
Then you dont have to care about those things anymore.
Last edited by Kaos on Sun Apr 24, 2016 9:09 pm, edited 1 time in total.
Kaos
 
Posts: 38
Joined: Mon Apr 18, 2016 11:24 pm

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Sun Apr 24, 2016 9:08 pm

Kaos wrote:ok so far it compiles fine but unity doesent like it ..

there is no
/*
#ifdef NEWTONWRAPPER_EXPORTS
#define NEWTONWRAPPER_API extern "C" __declspec(dllexport)
#else
#define NEWTONWRAPPER_API __declspec(dllimport)
#endif
*/


I think this is not necessary, swig make it own export decl

Code: Select all
#ifndef SWIGEXPORT
# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#   if defined(STATIC_LINKED)
#     define SWIGEXPORT
#   else
#     define SWIGEXPORT __declspec(dllexport)
#   endif
# else
#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
#     define SWIGEXPORT __attribute__ ((visibility("default")))
#   else
#     define SWIGEXPORT
#   endif
# endif
#endif


when compiling the woprper SWIGEXPORT resolves to SWIGEXPORT __declspec(dllexport)
when using it resolves to nothing, however the newton_wrap.cs does an explicit look of all the funtions in the dll, so SWIGEXPORT __declspec(dllimport) is not nessesary.
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 » Sun Apr 24, 2016 9:17 pm

Sweenie I am stocked again, I am trying to hook the first set of call backs, I am using the memory allocation driver functions.
This is what I believe is should be

Code: Select all
namespace NewtonPlugin
{
    // This compiles but I do no think is correct, I do not see any function to return the allocated memory
    class NewtonAllocMemory: SWIGTYPE_p_f_int__p_void
    {
        static NewtonAllocMemory()
        {
        }
    }

    class NewtonFreeMemory : SWIGTYPE_p_f_q_const__p_void_int__void
    {
        static NewtonFreeMemory()
        {
        }
    }

    class NewtonWorld
    {
        protected NewtonWorld()
        {
            // create the static memory alloction glue code. (I am no sur eif this is right)
            if (!m_isMemoryEnable)
            {
                m_isMemoryEnable = true;
                cpp.NewtonSetMemorySystem(m_alloc, m_free);
            }

            m_world = cpp.NewtonCreate();
           
            Debug.Log("Newton World created(" + m_world.ToString() + ")");
        }

        ~NewtonWorld()
        {
            Debug.Log("Newton World destroyed(" + m_world.ToString() + ")");
            cpp.NewtonDestroy(m_world);
        }

        protected SWIGTYPE_p_NewtonWorld m_world;
        static private bool m_isMemoryEnable = false;
        static private NewtonAllocMemory m_alloc = new NewtonAllocMemory();
        static private NewtonFreeMemory m_free = new NewtonFreeMemory();
    }
}


but I do not think is right because I do not see any method in class SWIGTYPE_p_f_q_const__p_void_int__void and SWIGTYPE_p_f_q_const__p_void_int__void to return and destroy a chunk of memory.
do you think you have an idea?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Kaos » Mon Apr 25, 2016 3:47 am

Well you didnt ask me but this looks like you made a class inherented from a swig class with a static constructor that is empty. So how should this give back memory it should only use mem for when making the object itself.

And why try to allocate mem in a c# script that looks for me like you wanna use c# like c++.
Ok you newton stuff uses that then but why not do this then on the newton dll side?

i am Just trying to understand.

And the other thing i tried to edit because i got that 8)
Kaos
 
Posts: 38
Joined: Mon Apr 18, 2016 11:24 pm

Re: Newton Plugin for Unity 3D

Postby Sweenie » Mon Apr 25, 2016 4:03 am

In C# you usually handle callbacks through a Delegate.
https://msdn.microsoft.com/en-us/library/ms173171.aspx

It seems Swig doesn't create a Delegate for Malloc and Free since Swig doesn't know they should be Delegates.

Swig see this in Newton.H
Code: Select all
typedef void* (*NewtonAllocMemory) (int sizeInBytes);

And create this c# class based on that

Code: Select all
public class SWIGTYPE_p_f_int__p_void {
  private global::System.Runtime.InteropServices.HandleRef swigCPtr;

  internal SWIGTYPE_p_f_int__p_void(global::System.IntPtr cPtr, bool futureUse) {
    swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
  }

  protected SWIGTYPE_p_f_int__p_void() {
    swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
  }

  internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SWIGTYPE_p_f_int__p_void obj) {
    return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
  }
}


According to this http://stackoverflow.com/questions/6599 ... ig-c-sharp
you have to define typemaps in Swig.

That thread says...
In particular, look for SWIGStringHelper in csharphead.swg. That code maps a delegate to a C callback. The trick is to add a helper callback implementation in the SWIG module.


So, on the c++ side

Code: Select all
typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *);
static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL;


#ifdef __cplusplus
extern "C"
#endif
SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_cpp(SWIG_CSharpStringHelperCallback callback) {
  SWIG_csharp_string_callback = callback;
}


Should be wrapped like this in the C# wrapper
Code: Select all
  protected class SWIGStringHelper {

    public delegate string SWIGStringDelegate(string message);
    static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString);

    [global::System.Runtime.InteropServices.DllImport("cpp", EntryPoint="SWIGRegisterStringCallback_cpp")]
    public static extern void SWIGRegisterStringCallback_cpp(SWIGStringDelegate stringDelegate);

    static string CreateString(string cString) {
      return cString;
    }

    static SWIGStringHelper() {
      SWIGRegisterStringCallback_cpp(stringDelegate);
    }
  }

  static protected SWIGStringHelper swigStringHelper = new SWIGStringHelper();


Or something like that... this way of wrapping is a bit new to me. This is probably the proper way of handling it though. My way is a bit more quick and dirty. :twisted:
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Sweenie » Mon Apr 25, 2016 5:05 am

To simplify this as much as possible, this is how I did it(without using Swig)

Here is how i wrapped the ForceAndTorque-callback in Newton.h
Code: Select all
typedef void (*NewtonApplyForceAndTorque) (const NewtonBody* const body, dFloat timestep, int threadIndex);


In C# I first declare the delegate and import the C-function that will call the Callback/Delegate

Code: Select all
public  delegate void NewtonApplyForceAndTorqueDelegate(IntPtr body, float timestep, int threadIndex);

[DllImportAttribute("Newton", EntryPoint = "NewtonBodySetForceAndTorqueCallback", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern void NewtonBodySetForceAndTorqueCallback(IntPtr body, NewtonApplyForceAndTorqueDelegate callback);



To use the Delegate I then do this...

After creating the NewtonBody

Code: Select all
        NewtonAPI.NewtonBodySetForceAndTorqueCallback(pBody, ApplyForceAndTorque);

        static void ApplyForceAndTorque(IntPtr body, float timestep, int threadIndex)
        {
            float mass = 0, iXX = 0, iYY = 0, iZZ = 0;
            NewtonAPI.NewtonBodyGetMassMatrix(body, ref mass, ref iXX, ref iYY, ref iZZ);

            Vector3 force = new Vector3(0.0f, -9.8f * mass, 0.0f);
            NewtonAPI.NewtonBodyAddForce(body, ref force);
        }



As you see I don't create a new Delegate Instance, I simply pass the function directly, which C# seems to be OK with.

But no example I can find does that. They do like this instead.
Code: Select all
NewtonApplyForceAndTorqueDelegate myForceCallback = new NewtonApplyForceAndTorqueDelegate(ApplyForceAndTorque);

NewtonAPI.NewtonBodySetForceAndTorqueCallback(pBody, myForceCallback);


I suspect it has something to do with the Garbage Collector.
Doing it as above may prevent the Delegate from being collected by the GC.

My method seems to work but maybe it will fail after a couple of garbage collections.

I think my method is safe if you're calling the function which will do the callback directly as the delegate will not be collected while used as a parameter.

But for ApplyForceAndTorque, Newton will hold on to the callbackpointer(delegate) for a long time and that may be a problem with my way of doing it.

[EDIT]
Ok, that seems to be the case after reading a bit about this.
The c# application is responsible for keeping the delegate alive(holding a reference to it) as long as the c++ application will use it.
My method may cause the delegate to be deleted by the Garbage Collector so it isn't safe.
You should store the delegate instance as a instance member or a static member to keep it from being destroyed.

Usually when passing Managed Objects to Unmanaged Applictions you also need to Pin the Managed Object.
Even if you keep the reference to the managed object so that it won't be deleted the GC can still relocate it in memory(due to memory organisation). To prevent this from happening you can tell the GC to Pin the object, thus preventing it from moving.
Fortunately it seems you won't have to do that with Delegates as it seems they are automatically pinned when passed to an Pinvoked unmanaged function.

So Pinning in .NET basically works like this I guess...
C# creates a "Glass" and puts in on the kitchen table.
Then it tells C++, "I've created a "Glass" and it's on the kitchen table, start filling it with water".
C++ starts filling the "Glass".

Suddenly the Garbage Collector swoops in.
"Hey, the kitchen table is too crowded. I'm gonna move this "Glass" over by the kitchen sink instead".

And now the C++ application is pouring water on the kitchen table instead, aka "Memory Access Violation".

So Pinning basically tells the Garbage Collector, "Never move the "Glass" from the kitchen table until I say you can!".



:mrgreen:
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Sweenie » Mon Apr 25, 2016 7:57 am

Regarding Unity GameObjects( MonoBehaviours ).

If you want to allow multiple NewtonWorlds per scene you should probably make the NewtonWorld class likes this...

Code: Select all
    [AddComponentMenu("Newton Physics/Newton World")]
    public class NewtonWorld : MonoBehaviour
    {

        //This function is always called before any Start functions and also just after a prefab is instantiated.
        void Awake()
        {
            m_world = cpp.NewtonCreate();
        }

        //Start is called before the first frame update only if the script instance is enabled.
        void Start()
        {
        }

        //FixedUpdate is often called more frequently than Update. It can be called multiple times per frame if the frame rate is low
        //and it may not be called between frames at all if the frame rate is high.
        void OnFixedUpdate()
        {
            cpp.NewtonUpdate(m_world, Time.deltaTime);
        }

        //Update is called once per frame. It is the main workhorse function for frame updates.
        void OnUpdate()
        {

        }

        // LateUpdate is called once per frame, after Update has finished
        void LateUpdate()
        {

        }

//This function is called after all frame updates for the last frame of the object’s existence
//(the object might be destroyed in response to Object.Destroy or at the closure of a scene).        void OnDestroy()
        {
            cpp.NewtonDestroy(m_world);
        }

        internal SWIGTYPE_p_NewtonWorld m_world; //internal makes this reference available only to classes inside this assembly(dll).
    }


It's not recommended to initializing anything in the constructor nor destroy it in the destructor.
The class may be created and destroyed several times by the Editor, due to serialisation and deserialisation etc.

One should use the events Awake(), Start(), OnApplicationQuit() & OnDestroy() for this instead.

Now, the problem as you mention is that if a NewtonBody is initiated( awake or start), the NewtonWorld must already be created.
By default it may not be so. The NewtonBody script may be called before the NewtonWorld script.

You can controll this by setting the Script Execution Order.
Giving the NewtonWorld script a start order of -500, we can guarantee that the NewtonWorld script will always be called before any NewtonBody script.

This is only a problem when loading a scene. During runtime we will know the world already exist.

So far it's good.

Now what happens when we quit the scene?

The same rules apply, Unity will normally call Destroy() in any given order, meaning NewtonWorld.Destroy() may be called before NewtonBody.Destroy().
In our case we specifically told the NewtonWorld to be called first so it will call NewtonWorld.Destroy before calling NewtonBody.Destroy.

Unity could have made this trivial by letting users define Script Execution Order on the methods as well. That way we could have defined NewtonWorld.Awake() to run first of all and NewtonWorld.Destroy() to run last.
But we can't, we can only define this on the whole Script Object, NewtonWorld. So the script execution order applies to all the methods inside the script.

So we have to work around this problem.
I used the Singleton "trick", that is, the NewtonWorld is kept alive all the time.
But that trick didn't really work. It only works when loading a new scene by keeping the NewtonWorld alive by using a function called "DontDestroyOnLoad". This makes the GameObject stay alive and move over to the next loaded scene.

But it still gets destroyed in random order when quitting the application.
That trick also prevents you from creating multiple worlds in the same scene.

I remember there was another "trick" to handle this... Can't remember it now though.
I will update this post when I find it again.

[EDIT]
Ah, found it.
But it still involves the Singleton approach.
Basically you do what I did in the first Plugin, but destroy the unmanaged object in the OnApplicationQuit event instead of in the OnDestroy event.

The OnApplicationQuit will trigger before destroy, so , if the unmanaged object in NewtonWorld is only destroyed in the OnDestroy() event, and all other objects in OnApplicationQuit, the NewtonWorld will always be the last object to be destroyed.

However, if you load a new scene, OnDestroy will be called for all objects but not OnApplicationQuit(since it's not quitting the applicaton). So therefor you also will need to check from within OnDestroy if it was called because the applicaton is quitting or loading a new scene.

But this means loading a new scene will call OnDestroy for the NewtonWorld.
Therefor you set DontDestroyOnLoad for the NewtonWorld, meaning it only will be Destroyed when you quit the game.

Sadly, this means you can only have one single NewtonWorld, not several.

FYI, PhysX only allow on world(scene) as well, maybe because of the same reason, or simply just to make it easier to use physics.

Multiple worlds would mean you would have to force the Unity User to choose which world each NewtonBody should belong to.
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Mon Apr 25, 2016 10:07 am

Oh I see, so MonoBehaviour is what connect an c# class to Mono or to Unitity?

Sweenie, I now added the rest of the dMath, and dContaners support library
I also added CustomJoint and Ball and CustomBallAndSocket so we now have a limited but complete wrapper to Newton SDK

in fact this is can be a template for wrapping to any other languages supported by swig.
Lua, Java, Python, Pascal, and so on. even C

anyway Sweenie, since you are a lot more knowledge of C# than I am, it will take my some time to complete my learning curve for both c# and Unity.

maybe you can give a head start and complete the class NewtonWorld
the goal is to complete the equivalent of this basics functions. I put the comment with !!! in the code.
Plase sync, you need to sync newton and build it, I has to add an export to a member variable in the CustomJoint base class.

I am no sure way github take so long to sync after commiting, wait some time a sync.
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 » Mon Apr 25, 2016 10:24 am

on the internal house keeping and synchronization between work and bodies, joints etc.
I am not too worry about that,

It does no matter what order object are created. The goal here is the wrapper should support creation of any of then in the order that Unity want to create or destroy them and the engine should support the functionality.

I do no know much of C# and much lest if Unity, but I know a lithe about Graph theory. and C# is memory system and garbage collection is nothing by a simple bidirectional graph

we can campilalize on that to guarantee always a order I proper.
basically simething as simple as the NewtonWorld having a container of references to NewtonBody, and the body having a reference to the NewtonWorlk will always guarantee a proper order.

I am not worry on the lest about that at all, I am worry more on how to interface to the swig wrapper.
we should strike for seamless integration supporting Multiple works and no trick like playing around with order of creation. In my experience that those tricks only work until some one do something difference, and hopefully there will be few people using it so, is bound to break.

My hope is that the interface is so transparent that people with not knowledge of the SDK, can use it with little couching as possible.

Anyway let us see how is goes, there must be something wrong with github, my last commit does not sync for hours.
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 » Mon Apr 25, 2016 10:28 am

Ok Github finish mergine, Please sync and look at NetwonWorld.cs
please see if you can do the memory call back, the userdata and the call to initialized the CustomJointLibrary.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Newton Plugin for Unity 3D

Postby Kaos » Mon Apr 25, 2016 12:44 pm

so MonoBehaviour is what connect an c# class to Mono or to Unitity?

maybe i can bring light to this.

Most Important EVERY SCRIPT component for a "gameobject" has to be inherented from monobehaviour otherwise you cant add it as a component.

Monobehaviour is a unity class that derives from behaviours .. behaviours brings components basics as enable disable ..
monobehaviour are somewhat special because if a class ergo script derives from monobehaviour its update() start() and awake() and fixedUpdate() function will be called if it haves them if not no problem.
It also brings coroutines which is threading.
You can then call scripts classes which are not derived that are in the asset folder.

And i dont see any special connection to the ide .. it may only be mono vs multi. :D



i also wanted to add that i think its good if the plugin would not use script execution settings because that is than something a user could forget to do and then complain. so its good that thats not necessary.


My hope is that the interface is so transparent that people with not knowledge of the SDK, can use it with little couching as possible.
I think so too. Otherwise it will not find followers on a wide base.
Kaos
 
Posts: 38
Joined: Mon Apr 18, 2016 11:24 pm

Re: Newton Plugin for Unity 3D

Postby Sweenie » Mon Apr 25, 2016 2:35 pm

Hmm, I'm getting some link errors...

The Linker includes these folders
newton\packages\projects\visualStudio_2015_dll\x64\dMath\Release
newton\packages\projects\visualStudio_2015_dll\x64\dContainers\Release
newton\packages\projects\visualStudio_2015_dll\x64\dJointLibrary\Release
newton\coreLibrary_300\projects\windows\project_vs2015_dll\x64\newton\Release

Put the Preprocessor has these added...
_NEWTON_STATIC_LIB
_CUSTOM_JOINTS_STATIC_LIB

Either I have to rebuild Newton as static libs or remove the Preprocessors.
Using static libs we don't need to handle extra dlls, but wouldn't it be more difficult for you to debug
if we use static libs?
Sweenie
 
Posts: 498
Joined: Mon Jan 24, 2005 7:59 am
Location: Sweden

Re: Newton Plugin for Unity 3D

Postby Julio Jerez » Mon Apr 25, 2016 3:13 pm

oh I has not compile in release yet, there may be some link error yes.
I will check tonight.

on the static linking yes you are right doing that way we do not need so many dlls.
yes is harder to debug but not impossible, the wrapper itself is a DLL, there is not reason why we can no debug it that, we only need to set the path to where the newton source is.
Let us make it static, this will only required two DLL, the wrapper and the c sharp plugin.
Is that right?

if this is correct then tonight I will go and change the path to point to the projects
visualStudio_2015_static_mt
The simple the better.

mean time try using the debug configuration, I believe that one compiles fine.
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 » Mon Apr 25, 2016 4:54 pm

Usually when passing Managed Objects to Unmanaged Applications you also need to Pin the Managed Object.
Even if you keep the reference to the managed object so that it won't be deleted the GC can still relocate it in memory(due to memory organization). To prevent this from happening you can tell the GC to Pin the object, thus preventing it from moving.


what? are you serious? C# still reallocate memory pointers, I thought garbage collector evolved well pad that point.
That was a win 3.1 thing 20 year ago, and some low performance scripting languages like java script or Perl still do that, but I do not believe C# and Java will do that kind of shenanigan.

you mean you can have a pointer to an object and the unbeknown to you, the pointer can turns invalid?
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 » Mon Apr 25, 2016 6:18 pm

haha, Well it still seems to be the case. :lol:
https://msdn.microsoft.com/en-us/librar ... e(v=vs.100).aspx
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