PUDotNet        

PUDotNet is a simple C++/CLI wrapper class to use Particle Universe in Mogre.

help For questions is this forum topic.

Look to the Particle page for basic particle information and further links.

Contributer of this code snippet: mstoyke
Published in February 2011.
Updated in March 2011 by user tafkag for Mogre 1.7 with Particle Universe 1.5.

The source codes for PU 1.2 and 1.4/1.5 are attached to this wiki page. (see bottom)


Note by the contributor:
This code is a quick-and-dirty solution:
Grab the code and have some fun. It's very simplistic, not a real wrapper of the API, more a kind of binding to the plug-in. I will not have time to support this in any way, but I think I should at least share it with you in case somebody find it useful.

How to use


First you need to buy Particle Universe (for about 10 Euro/Dollars) and compile the wrapper code.
For compilation of the wrapper it's needed to link against the Mogre version of the Ogre libraries when building PU, otherwise it will not work. (means: The Ogre sources, which are modified specific for Mogre)

Additionally you need to add PUDotNet to the file plugins.cfg:

  • release version:
Plugin=ParticleUniverse
  • debug version:
Plugin=ParticleUniverse_d






PUDotNet.h

Source code for Mogre 1.7 with Particle Universe 1.4

#pragma once
 
#include <Ogre.h>
#include <ParticleUniverseSystem.h>
#include <ParticleUniverseSystemManager.h>
 
using namespace System;

namespace PUDotNet 
{
	public ref class PUManager
	{
		private:
		  Mogre::SceneManager^ mScene;
		  ParticleUniverse::ParticleSystemManager* mPUMgr;
		  Collections::Generic::Dictionary<System::String^, IntPtr>^ mSystems;
	 
		public:
		  PUManager( Mogre::SceneManager^ _scene );
		  !PUManager();
		  ~PUManager();
	 
		  property bool IsDisposed { bool get(); }
	 
		  array<System::String^>^ GetTemplateNames();
		  bool CreateParticleSystem( System::String^ _name, System::String^ _templateName );
		  void DestroyParticleSystem( System::String^ _name );
		  void AddToSceneNode( Mogre::SceneNode^ _node, System::String^ _name );
		  void RemoveFromSceneNode( Mogre::SceneNode^ _node, System::String^ _name );
		  void Start( System::String^ _name );
		  void Stop( System::String^ _name );
		  void Pause( System::String^ _name );
		  void Resume( System::String^ _name );		  

                  void SetScale( System::String^ _name, float _x, float _y, float _z );
		  void SetScaleVelocity( System::String^ _name, float _scaleVelocity );
		  void SetScaleTime( System::String^ _name, float _scaleTime );

		private:
		  ParticleUniverse::ParticleSystem* GetByName( System::String^ _name );

		  void MarshalString ( System::String^ s, std::string& os );
	};	 

	inline void PUManager::MarshalString ( System::String^ s, std::string& os ) 
	{
	   using namespace Runtime::InteropServices;
	   const char* chars = 
		  (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
	   os = chars;
	   Ogre::String test(os);
	   Marshal::FreeHGlobal(IntPtr((void*)chars));
	}
}





PUDotNet.cpp

Source code for Mogre 1.7 with Particle Universe 1.4

#include "stdafx.h" 
#include "PUDotNet.h"
 
namespace PUDotNet {
 
  PUManager::PUManager( Mogre::SceneManager^ _scene )
  {
    if( _scene == nullptr )
      throw gcnew System::ArgumentNullException( "_scene" );
 
    mScene = _scene;
    mPUMgr = ParticleUniverse::ParticleSystemManager::getSingletonPtr();
    mSystems = gcnew Collections::Generic::Dictionary<System::String^, IntPtr>();
  }
 
  PUManager::!PUManager()
  {
    if( mSystems != nullptr )
    {
      Collections::Generic::Dictionary<System::String^, IntPtr>::Enumerator it;
      it = mSystems->GetEnumerator();
 
      array<System::String^>^ names = gcnew array<System::String^>( mSystems->Keys->Count );
      int pos = 0;
      while( it.MoveNext() )
        names[ pos++ ] = it.Current.Key;
 
      for( int i = 0; i < names->Length; ++i )
        DestroyParticleSystem( names[i] );
 
      mSystems->Clear();
    }
 
    mSystems = nullptr;
    mPUMgr = NULL;
    mScene = nullptr;
  }
 
  PUManager::~PUManager()
  {
    this->!PUManager();
  }
 
  bool PUManager::IsDisposed::get()
  {
    return ( mPUMgr == NULL );
  }
 
  array<System::String^>^ PUManager::GetTemplateNames()
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
 
    ParticleUniverse::vector<ParticleUniverse::String> tNames;

    mPUMgr->particleSystemTemplateNames( tNames );
 
    array<System::String^>^ names = gcnew array<System::String^>( tNames.size() );
 
	ParticleUniverse::vector<Ogre::String>::iterator it;
    int i = 0;
    for ( it = tNames.begin(); it != tNames.end(); ++it, ++i )
    {
      Ogre::String name = *it;
      //names[ i ] = TO_CLR_STRING( name );
      names[ i ] = gcnew ::System::String( name.c_str() );
    }
 
    return names;
  }
 
  bool PUManager::CreateParticleSystem( System::String^ _name, System::String^ _templateName )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if( _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
    if( _templateName == nullptr )
      throw gcnew System::ArgumentNullException( "_templateName" );
 
    ParticleUniverse::ParticleSystem* psys;	
        
	//DECLARE_OGRE_STRING( name, _name )
	std::string nameTemp;
	MarshalString(_name, nameTemp);
	Ogre::String name(nameTemp);

    //DECLARE_OGRE_STRING( templateName, _templateName )
	std::string templateTemp;
	MarshalString(_templateName, templateTemp);
	Ogre::String templateName(templateTemp);
     
    psys = mPUMgr->createParticleSystem( name, templateName, mScene );
    if( psys == NULL )
      return false;
 
    IntPtr psysPtr = IntPtr( psys );
    mSystems->Add( _name, psysPtr );
 
    return true;
  }
 
  void PUManager::DestroyParticleSystem( System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if( _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
    mSystems->Remove( _name );
 
    Ogre::SceneNode* node = psys->getParentSceneNode();
    if( node != NULL )
      node->detachObject( psys );
 
    mPUMgr->destroyParticleSystem( psys, mScene );
  }
 
  void PUManager::AddToSceneNode( Mogre::SceneNode^ _node, System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if( _node == nullptr )
      throw gcnew System::ArgumentNullException( "_node" );
    if( _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    Ogre::SceneNode* node = (Ogre::SceneNode*) _node->NativePtr;
    if( node == NULL )
      return;
 
    node->attachObject( psys );
  }
 
  void PUManager::RemoveFromSceneNode( Mogre::SceneNode^ _node, System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if( _node == nullptr )
      throw gcnew System::ArgumentNullException( "_node" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    Ogre::SceneNode* node = (Ogre::SceneNode*) _node->NativePtr;
    if( node == NULL )
      return;
 
    node->detachObject( psys );
  }
 
  void PUManager::Start( System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    psys->start();
  }
 
  void PUManager::Stop( System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    psys->stop();
  }
 
  void PUManager::Pause( System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    psys->pause();
  }
 
  void PUManager::Resume( System::String^ _name )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );
 
    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    if( psys == NULL )
      return;
 
    psys->resume();
  }
 
  void PUManager::SetScale(System::String^ _name, float _x, float _y, float _z)
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );

    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    psys->setScale(Mogre::Vector3(_x, _y, _z));		
  }

  void PUManager::SetScaleVelocity( System::String^ _name, float _scaleVelocity )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );

    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    psys->setScaleVelocity( _scaleVelocity );	
  }

  void PUManager::SetScaleTime( System::String^ _name, float _scaleTime )
  {
    if( IsDisposed )
      throw gcnew System::ObjectDisposedException( "PUManager" );
    if(  _name == nullptr )
      throw gcnew System::ArgumentNullException( "_name" );

    ParticleUniverse::ParticleSystem* psys;
    psys = GetByName( _name );
    psys->setScaleTime( _scaleTime );	
  }

  ParticleUniverse::ParticleSystem* PUManager::GetByName( System::String^ _name )
  {
    IntPtr sys;
    if( !mSystems->TryGetValue( _name, sys ) )
      return NULL;
 
    ParticleUniverse::ParticleSystem* psys = (ParticleUniverse::ParticleSystem*) sys.ToPointer();
    return psys;
  }
 
}