void EditorScalePointModule::fillPropertyGrid (wxPropertyGrid *pg)
{
	pg->Append( wxPropertyCategory(wxT("Source modules")) );
	appendSourceModuleProperty (pg, wxT("Source module"), mSourceModules[0]);
	pg->Append( wxPropertyCategory(wxT("Parameters")) );
	pg->Append( wxFloatProperty(wxT("Scale X"), wxPG_LABEL, mModule.getScaleX()) );
	pg->Append( wxFloatProperty(wxT("Scale Y"), wxPG_LABEL, mModule.getScaleY()) );
	pg->Append( wxFloatProperty(wxT("Scale Z"), wxPG_LABEL, mModule.getScaleZ()) );
}
void EditorSelectModule::fillPropertyGrid (wxPropertyGrid *pg)
{
	pg->Append( wxPropertyCategory(wxT("Source modules")) );
	appendSourceModuleProperty (pg, wxT("Source module 1"), mSourceModules[0]);
	appendSourceModuleProperty (pg, wxT("Source module 2"), mSourceModules[1]);
	appendSourceModuleProperty (pg, wxT("Control module"), mSourceModules[2]);
	pg->Append( wxPropertyCategory(wxT("Parameters")) );
	pg->Append( wxFloatProperty(wxT("Lower bound"), wxPG_LABEL, mModule.getLowerBound()) );
	pg->Append( wxFloatProperty(wxT("Upper bound"), wxPG_LABEL, mModule.getUpperBound()) );
	pg->Append( wxFloatProperty(wxT("Edge falloff"), wxPG_LABEL, mModule.getEdgeFalloff()) );
}
void EditorTurbulenceModule::fillPropertyGrid (wxPropertyGrid *pg)
{
	pg->Append( wxPropertyCategory(wxT("Source modules")) );
	appendSourceModuleProperty (pg, wxT("Source module"), mSourceModules[0]);
	pg->Append( wxPropertyCategory(wxT("Parameters")) );
	pg->Append( wxFloatProperty(wxT("Power"), wxPG_LABEL, mModule.getPower()) );
	pg->Append( wxFloatProperty(wxT("Frequency"), wxPG_LABEL, mModule.getFrequency()) );
	pg->Append( wxIntProperty(wxT("Roughness"), wxPG_LABEL, mModule.getRoughness()) );
	pg->Append( wxIntProperty(wxT("Seed"), wxPG_LABEL, mModule.getSeed()) );
	appendQualityProperty (pg, mModule.getQuality());
}
void EditorExponentModule::fillPropertyGrid (wxPropertyGrid *pg)
{
	pg->Append( wxPropertyCategory(wxT("Source modules")) );
	appendSourceModuleProperty (pg, wxT("Source module"), mSourceModules[0]);
	pg->Append( wxPropertyCategory(wxT("Parameters")) );
	pg->Append( wxFloatProperty(wxT("Exponent"), wxPG_LABEL, mModule.getExponent()) );
}
//-----------------------------------------------------------------------
void VortexExternPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	// TODO
	PRNL_ROTATION_SPEED = _("Rotation speed");
	PRNL_ROTATION_AXIS = _("Rotation axis");
	PRNL_X = _(".x");
	PRNL_Y = _(".y");
	PRNL_Z = _(".z");
	PRNL_EXTERN_THRESHOLD = _("Distance threshold");

	mHelpHtml = wxT("ExternVortex.html");

	// Distance Threshold: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_EXTERN_THRESHOLD, PRNL_EXTERN_THRESHOLD, std::numeric_limits<float>::max()));
	SetPropertyEditor(PRNL_EXTERN_THRESHOLD, wxPG_EDITOR(SpinCtrl));

	// Rotation Vector: Ogre::Vector3
	appendVector3(PRNL_ROTATION_AXIS, PRNL_ROTATION_AXIS, ParticleUniverse::VortexAffector::DEFAULT_ROTATION_VECTOR);

	// Rotation Speed: Dynamic Attribute
	ParticleUniverse::DynamicAttributeFixed dynAttr;
	dynAttr.setValue(ParticleUniverse::VortexAffector::DEFAULT_ROTATION_SPEED);
	appendDynamicAttribute(PRNL_ROTATION_SPEED, PRNL_ROTATION_SPEED, dynAttr);
}
//-----------------------------------------------------------------------
void OnTimeObserverPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_ON_TIME_COMPARE = _("On time compare");
	PRNL_ON_TIME_THRESHOLD = _("On time threshold");
	PRNL_SINCE_START_SYSTEM = _("Since start system");
	PRNL_COMPARE_LESS_THAN = _("Less than");
	PRNL_COMPARE_GREATER_THAN = _("Greater than");
	PRNL_COMPARE_EQUALS = _("Equals");

	mHelpHtml = wxT("ObserverOnTime.html");

	// Time Threshold - Compare: List
	mCompare.Add(PRNL_COMPARE_LESS_THAN);
	mCompare.Add(PRNL_COMPARE_GREATER_THAN);
	mCompare.Add(PRNL_COMPARE_EQUALS);
	Append(wxEnumProperty(PRNL_ON_TIME_COMPARE, PRNL_ON_TIME_COMPARE, mCompare));

	// Time Threshold - Value: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_ON_TIME_THRESHOLD, PRNL_ON_TIME_THRESHOLD, ParticleUniverse::OnTimeObserver::DEFAULT_THRESHOLD));
	SetPropertyEditor(PRNL_ON_TIME_THRESHOLD, wxPG_EDITOR(SpinCtrl));

	// Since Start System: bool
	Append(wxBoolProperty(PRNL_SINCE_START_SYSTEM, PRNL_SINCE_START_SYSTEM, ParticleUniverse::OnTimeObserver::DEFAULT_SINCE_START_SYSTEM));
}
//-----------------------------------------------------------------------
void TextureAnimatorPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_ANIMATION_TYPE = _("Animation type");
	TAT_LOOP = _("Loop");
	TAT_UP_DOWN = _("Up - Down");
	TAT_RANDOM = _("Random");
	PRNL_TEXCOORDS_START = _("Texture coordinate start");
	PRNL_TEXCOORDS_END = _("Texture coordinate end");
	PRNL_START_RANDOM = _("Start random");
	PRNL_TIME_STEP = _("Time step");

	mHelpHtml = wxT("AffectorTextureAnimator.html");

	// Time Step Animation: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_TIME_STEP, PRNL_TIME_STEP, ParticleUniverse::TextureAnimator::DEFAULT_TIME_STEP));
	SetPropertyEditor(PRNL_TIME_STEP, wxPG_EDITOR(SpinCtrl));

	// Animation Type: List
	mAnimationTypes.Add(TAT_LOOP);
	mAnimationTypes.Add(TAT_UP_DOWN);
	mAnimationTypes.Add(TAT_RANDOM);
	wxPGId pid = Append(wxEnumProperty(PRNL_ANIMATION_TYPE, PRNL_ANIMATION_TYPE, mAnimationTypes));

	// Start Texture Coordinates: ParticleUniverse::uint16
	Append(wxUIntProperty(PRNL_TEXCOORDS_START, PRNL_TEXCOORDS_START, ParticleUniverse::TextureAnimator::DEFAULT_TEXCOORDS_START));
	SetPropertyEditor(PRNL_TEXCOORDS_START, wxPG_EDITOR(SpinCtrl));

	// End Texture Coordinates: ParticleUniverse::uint16
	Append(wxUIntProperty(PRNL_TEXCOORDS_END, PRNL_TEXCOORDS_END, ParticleUniverse::TextureAnimator::DEFAULT_TEXCOORDS_END));
	SetPropertyEditor(PRNL_TEXCOORDS_END, wxPG_EDITOR(SpinCtrl));

	// Random Start: bool
	Append(wxBoolProperty(PRNL_START_RANDOM, PRNL_START_RANDOM, ParticleUniverse::TextureAnimator::DEFAULT_START_RANDOM));
}
void EditorTerraceModule::changeNumberOfControlPoints (wxPropertyGrid *pg)
{
	if (mControlPointIDs.size() > mPointCount)
	{
		while (mControlPointIDs.size() > MIN_POINTS && mControlPointIDs.size() > mPointCount)
		{
			pg->Delete (mControlPointIDs.back());
			mControlPointIDs.pop_back ();
		}
	}
	else if (mControlPointIDs.size() < mPointCount)
	{
		noisepp::TerraceControlPointVector &points = mModule.getControlPoints ();
		while (mControlPointIDs.size() < MAX_POINTS && mControlPointIDs.size() < mPointCount)
		{
			wxString name = wxT("Point ");
			name << mControlPointIDs.size() + 1;
			double val = 0.0;
			if (mControlPointIDs.size() < points.size())
			{
				val = points[mControlPointIDs.size()];
			}
			wxPGId id = pg->AppendIn( mPointCategoryID, wxFloatProperty(name,wxPG_LABEL,val) );
			mControlPointIDs.push_back (id);
		}
	}
}
//-----------------------------------------------------------------------
void DoPlacementParticleEventHandlerPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_NUMBER_OF_PARTICLES = _("Number of particles");
	PRNL_INHERIT_POSITION  = _("Inherit position");
	PRNL_INHERIT_DIRECTION  = _("Inherit direction");
	PRNL_INHERIT_ORIENTATION  = _("Inherit orientation");
	PRNL_INHERIT_TIME_TO_LIVE  = _("Inherit time to live");
	PRNL_INHERIT_MASS  = _("Inherit mass");
	PRNL_INHERIT_TEXTURE_COORDINATE  = _("Inherit texture coord");
	PRNL_INHERIT_COLOUR  = _("Inherit colour");
	PRNL_INHERIT_PARTICLE_WIDTH  = _("Inherit particle width");
	PRNL_INHERIT_PARTICLE_HEIGHT  = _("Inherit particle height");
	PRNL_INHERIT_PARTICLE_DEPTH  = _("Inherit particle depth");

	mHelpHtml = wxT("EventHandlerDoPlacementParticle.html");

	// Force Emitter: Is established by means of a connection

	// Number of Particles: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_NUMBER_OF_PARTICLES, 
		PRNL_NUMBER_OF_PARTICLES, 
		ParticleUniverse::DoPlacementParticleEventHandler::DEFAULT_NUMBER_OF_PARTICLES));
	SetPropertyEditor(PRNL_NUMBER_OF_PARTICLES, wxPG_EDITOR(SpinCtrl));

	// Inherit Position: bool
	Append(wxBoolProperty(PRNL_INHERIT_POSITION, PRNL_INHERIT_POSITION, true));

	// Inherit Direction: bool
	Append(wxBoolProperty(PRNL_INHERIT_DIRECTION, PRNL_INHERIT_DIRECTION, false));
	
	// Inherit Orientation: bool
	Append(wxBoolProperty(PRNL_INHERIT_ORIENTATION, PRNL_INHERIT_ORIENTATION, false));
	
	// Inherit Time to live: bool
	Append(wxBoolProperty(PRNL_INHERIT_TIME_TO_LIVE, PRNL_INHERIT_TIME_TO_LIVE, false));
	
	// Inherit Mass: bool
	Append(wxBoolProperty(PRNL_INHERIT_MASS, PRNL_INHERIT_MASS, false));
	
	// Inherit Texture Coord: bool
	Append(wxBoolProperty(PRNL_INHERIT_TEXTURE_COORDINATE, PRNL_INHERIT_TEXTURE_COORDINATE, false));
	
	// Inherit Colour: bool
	Append(wxBoolProperty(PRNL_INHERIT_COLOUR, PRNL_INHERIT_COLOUR, false));
	
	// Inherit Particle width: bool
	Append(wxBoolProperty(PRNL_INHERIT_PARTICLE_WIDTH, PRNL_INHERIT_PARTICLE_WIDTH, false));
	
	// Inherit Particle height: bool
	Append(wxBoolProperty(PRNL_INHERIT_PARTICLE_HEIGHT, PRNL_INHERIT_PARTICLE_HEIGHT, false));
	
	// Inherit Particle Depth: bool
	Append(wxBoolProperty(PRNL_INHERIT_PARTICLE_DEPTH, PRNL_INHERIT_PARTICLE_DEPTH, false));
}
//-----------------------------------------------------------------------
void PlaneColliderPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_PLANE_COLLIDER_NORMAL = _("Plane normal");
	PRNL_COLLIDER_FRICTION = _("Friction");
	PRNL_COLLIDER_BOUNCYNESS = _("Bouncyness");
	PRNL_INTERSECTION_TYPE = _("Intersection type");
	PRNL_COLLISION_TYPE = _("Collision type");
	IST_POINT = _("Point");
	IST_BOX = _("Box");
	COLLT_NONE = _("None");
	COLLT_BOUNCE = _("Bounce");
	COLLT_FLOW = _("Flow");

	PRNL_X = _(".x");
	PRNL_Y = _(".y");
	PRNL_Z = _(".z");

	mHelpHtml = wxT("ColliderPlane.html");

	// Normal: Ogre::Vector3
	appendVector3(PRNL_PLANE_COLLIDER_NORMAL, PRNL_PLANE_COLLIDER_NORMAL, ParticleUniverse::PlaneCollider::DEFAULT_NORMAL);

	// Friction: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_COLLIDER_FRICTION, PRNL_COLLIDER_FRICTION, ParticleUniverse::PlaneCollider::DEFAULT_FRICTION));
	SetPropertyEditor(PRNL_COLLIDER_FRICTION, wxPG_EDITOR(SpinCtrl));

	// Bouncyness: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_COLLIDER_BOUNCYNESS, PRNL_COLLIDER_BOUNCYNESS, ParticleUniverse::PlaneCollider::DEFAULT_BOUNCYNESS));
	SetPropertyEditor(PRNL_COLLIDER_BOUNCYNESS, wxPG_EDITOR(SpinCtrl));

	// Intersection type: List
	mIntersectionTypes.Add(IST_POINT);
	mIntersectionTypes.Add(IST_BOX);
	Append(wxEnumProperty(PRNL_INTERSECTION_TYPE, PRNL_INTERSECTION_TYPE, mIntersectionTypes));

	// Collision type: List
	mCollisionTypes.Add(COLLT_NONE);
	mCollisionTypes.Add(COLLT_BOUNCE);
	mCollisionTypes.Add(COLLT_FLOW);
	Append(wxEnumProperty(PRNL_COLLISION_TYPE, PRNL_COLLISION_TYPE, mCollisionTypes));
}
Beispiel #11
0
wxPGProperty*
WXEffectEditDialog::CreateProperty(const Ogre::ParameterDef& propertyDef, Ogre::StringInterface *basic)
{
	wxPGProperty* property = NULL;
	wxString name = propertyDef.name.c_str();
	Ogre::String value = basic->getParameter(name.c_str());
	Ogre::ParameterType paraType = propertyDef.paramType;

	switch ( paraType )
	{
	case Ogre::PT_COLOURVALUE:
		property = wxFairyColourProperty(name, name, colorConverter(value));
		break;

	case Ogre::PT_STRING:
		{
			wxPGConstants* constants = PopulateConstants(propertyDef.name);
			if (constants)
			{
				// 创建出combobox
				property = wxEnumProperty(name, name, *constants);
				// 设置成当前这个参数的值
				property->SetValueFromString(value.c_str(),0);
			}
			
			break;
		}

	case Ogre::PT_REAL:
		{
			property = wxFloatProperty(name, name, Ogre::StringConverter::parseReal(value));

			break;
		}

	default:
		property = wxStringProperty(name, name, value.c_str());
		break;
	}

	assert (property);
	
	return property;
}
//-----------------------------------------------------------------------
void OnVelocityObserverPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_ON_VELOCITY_COMPARE = _("Velocity compare");
	PRNL_ON_VELOCITY_THRESHOLD = _("Velocity threshold");
	PRNL_COMPARE_LESS_THAN = _("Less than");
	PRNL_COMPARE_GREATER_THAN = _("Greater than");
	PRNL_COMPARE_EQUALS = _("Equals");

	mHelpHtml = wxT("ObserverOnVelocity.html");

	// Velocity threshold - compare: List
	mCompare.Add(PRNL_COMPARE_LESS_THAN);
	mCompare.Add(PRNL_COMPARE_GREATER_THAN);
	mCompare.Add(PRNL_COMPARE_EQUALS);
	Append(wxEnumProperty(PRNL_ON_VELOCITY_COMPARE, PRNL_ON_VELOCITY_COMPARE, mCompare));

	// Velocity threshold - value: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_ON_VELOCITY_THRESHOLD, PRNL_ON_VELOCITY_THRESHOLD, ParticleUniverse::OnVelocityObserver::DEFAULT_VELOCITY_THRESHOLD));
	SetPropertyEditor(PRNL_ON_VELOCITY_THRESHOLD, wxPG_EDITOR(SpinCtrl));
}
//-----------------------------------------------------------------------
void DoScaleEventHandlerPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_SCALE_FRACTION = _("Scale fraction");
	PRNL_SCALE_TYPE = _("Scale type");
	SC_TIME_TO_LIVE = _("Time to live");
	SC_VELOCITY = _("Velocity");

	mHelpHtml = wxT("EventHandlerDoScale.html");

	// Scale Fraction: Ogre:: Real
	Append(wxFloatProperty(PRNL_SCALE_FRACTION, 
		PRNL_SCALE_FRACTION, 
		ParticleUniverse::DoScaleEventHandler::DEFAULT_SCALE_FRACTION));
	SetPropertyEditor(PRNL_SCALE_FRACTION, wxPG_EDITOR(SpinCtrl));

	// Scale Type: List
	mScaleTypes.Add(SC_TIME_TO_LIVE);
	mScaleTypes.Add(SC_VELOCITY);
	wxPGId pid = Append(wxEnumProperty(PRNL_SCALE_TYPE, PRNL_SCALE_TYPE, mScaleTypes));
}
wxPGProperty*
FairySkillEditDialog::CreateProperty(const Ogre::ParameterDef& propertyDef, Ogre::String &value)
{
	wxPGProperty* property = NULL;
	wxString name = propertyDef.name.c_str();
	Ogre::ParameterType paraType = propertyDef.paramType;

	switch ( paraType )
	{
	case Ogre::PT_COLOURVALUE:
		property = wxFairyColourProperty(name, name, colorConverter(value));
		break;

	case Ogre::PT_STRING:
		{
			if (name == "HitTime")
			{
				Ogre::String newValue("");

				for (unsigned short i=0; i<mSkill->getNumHitTimes(); ++i)
				{
					float time = mSkill->getHitTime(i);

					newValue += Ogre::StringConverter::toString( (time * mDObject->getCurrentAnimationLength() * mFramePerSecond) );
					newValue += " ";
				}
				property = wxStringProperty(name, name, newValue.c_str());
			}
			else if (name == "BreakTime")
			{
				Ogre::String newValue("");

				for (unsigned short i=0; i<mSkill->getNumBreakTimes(); ++i)
				{
					float time = mSkill->getBreakTime(i);

					newValue += Ogre::StringConverter::toString( (time * mDObject->getCurrentAnimationLength() * mFramePerSecond) );
					newValue += " ";
				}
				property = wxStringProperty(name, name, newValue.c_str());
			}
            else if (name == "ShakeTime")
            {
                Ogre::String newValue("");

                for (unsigned short i=0; i<mSkill->getNumShakeTimes(); ++i)
                {
                    float time = mSkill->getShakeTime(i);

                    newValue += Ogre::StringConverter::toString( (time * mDObject->getCurrentAnimationLength() * mFramePerSecond) );
                    newValue += " ";
                }
                property = wxStringProperty(name, name, newValue.c_str());
            }
			else
			{
				wxPGConstants* constants = PopulateConstants(propertyDef.name);
				if (constants)
				{
					// 创建出combobox
					property = wxEnumProperty(name, name, *constants);
					// 设置成当前这个参数的值
					property->SetValueFromString(value.c_str());
				}
				else
				{				
					property = wxStringProperty(name, name, value.c_str());
				}
			}			

			break;
		}

	case Ogre::PT_REAL:
		{
			if (name == "AttachTime")
			{
				float inputValue = Ogre::StringConverter::parseReal(value);

				if (inputValue >= 0.0f && inputValue <= 1.0f)
					value = Ogre::StringConverter::toString( (inputValue * mDObject->getCurrentAnimationLength() * mFramePerSecond) );
			}

			property = wxFloatProperty(name, name, Ogre::StringConverter::parseReal(value));

			break;
		}

	case Ogre::PT_BOOL:
		{
			size_t id = reinterpret_cast<size_t>(&name);
			wxPGConstants* constants = wxPropertyGrid::GetConstantsArray(id);

			if (!constants)
			{
				constants = wxPropertyGrid::CreateConstantsArray(id);		

				constants->Add("true");
				constants->Add("false");

				registerConstants(constants);
			}

			if (constants)
			{
				// 创建出combobox
				property = wxEnumProperty(name, name, *constants);
				// 设置成当前这个参数的值
				property->SetValueFromString(value.c_str());
			}
			break;
		}

	default:
		property = wxStringProperty(name, name, value.c_str());
		break;
	}

	assert (property);

	return property;
}
void wxsFloatProperty::PGCreate(wxsPropertyContainer* Object,wxPropertyGridManager* Grid,wxPGId Parent)
{
    PGRegister(Object,Grid,Grid->AppendIn(Parent,NEW_IN_WXPG14X wxFloatProperty(GetPGName(),wxPG_LABEL,VALUE)));
}
void CPropertiesCanvas::AddProperty(Property* p, wxPGProperty* parent_prop)
{
	switch(p->get_property_type()){
	case StringPropertyType:
		{
			wxPGProperty *new_prop = wxStringProperty(p->GetShortString(),wxPG_LABEL, ((PropertyString*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	case DoublePropertyType:
	case LengthPropertyType:
		{
		    wxString initial_value;
		    initial_value << ((PropertyDouble*)p)->m_initial_value;
			// wxPGProperty *new_prop = wxFloatProperty(p->GetShortString(),wxPG_LABEL, ((PropertyDouble*)p)->m_initial_value);
			wxPGProperty *new_prop = wxStringProperty(p->GetShortString(),wxPG_LABEL, initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case IntPropertyType:
		{
			wxPGProperty *new_prop = wxIntProperty(p->GetShortString(),wxPG_LABEL, ((PropertyInt*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case ColorPropertyType:
		{
			HeeksColor& col = ((PropertyColor*)p)->m_initial_value;
			wxColour wcol(col.red, col.green, col.blue);
			wxPGProperty *new_prop = wxColourProperty(p->GetShortString(),wxPG_LABEL, wcol);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case ChoicePropertyType:
		{
			wxArrayString array_string;
			std::list< wxString >::iterator It;
			for(It = ((PropertyChoice*)p)->m_choices.begin(); It != ((PropertyChoice*)p)->m_choices.end(); It++){
				array_string.Add(wxString(It->c_str()));
			}
			wxPGProperty *new_prop = wxEnumProperty(p->GetShortString(),wxPG_LABEL,array_string, ((PropertyChoice*)p)->m_initial_index);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
		}
		break;
	case VertexPropertyType:
		{
			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			Append( parent_prop, new_prop, p );
			double x[3];
			unsigned int number_of_axes = 3;
			if(((PropertyVertex*)p)->xyOnly())number_of_axes = 2;
			memcpy(x, ((PropertyVertex*)p)->m_x, number_of_axes*sizeof(double));
			if(((PropertyVertex*)p)->m_affected_by_view_units)
			{
				for(unsigned int i = 0; i<number_of_axes; i++)x[i] /= wxGetApp().m_view_units;
			}
            wxPGProperty* x_prop = wxFloatProperty(_("x"),wxPG_LABEL, x[0]);
            if(!p->property_editable())x_prop->SetFlag(wxPG_PROP_READONLY);
            Append( new_prop, x_prop, p );
			wxPGProperty* y_prop = wxFloatProperty(_("y"),wxPG_LABEL, x[1]);
			if(!p->property_editable())y_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, y_prop, p );
			if(!((PropertyVertex*)p)->xyOnly())
			{
				wxPGProperty* z_prop = wxFloatProperty(_("z"),wxPG_LABEL, x[2]);
				if(!p->property_editable())z_prop->SetFlag(wxPG_PROP_READONLY);
				new_prop->SetFlag(wxPG_PROP_READONLY);
				Append( new_prop, z_prop, p );
			}
		}
		break;
	case TrsfPropertyType:
		{
			double x[3];
			extract(((PropertyTrsf*)p)->m_trsf.TranslationPart(), x);

			gp_Dir xaxis(1, 0, 0);
			xaxis.Transform(((PropertyTrsf*)p)->m_trsf);
			gp_Dir yaxis(0, 1, 0);
			yaxis.Transform(((PropertyTrsf*)p)->m_trsf);

			double vertical_angle = 0;
			double horizontal_angle = 0;
			double twist_angle = 0;
			CoordinateSystem::AxesToAngles(xaxis, yaxis, vertical_angle, horizontal_angle, twist_angle);

			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			Append( parent_prop, new_prop, p );
			wxPGProperty* x_prop = wxFloatProperty(_("x"),wxPG_LABEL,x[0]);
			if(!p->property_editable())x_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, x_prop, p );
			wxPGProperty* y_prop = wxFloatProperty(_("y"),wxPG_LABEL,x[1]);
			if(!p->property_editable())y_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, y_prop, p );
			wxPGProperty* z_prop = wxFloatProperty(_("z"),wxPG_LABEL,x[2]);
			if(!p->property_editable())z_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, z_prop, p );
			wxPGProperty* v_prop = wxFloatProperty(_("vertical angle"),wxPG_LABEL,vertical_angle);
			if(!p->property_editable())v_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, v_prop, p );
			wxPGProperty* h_prop = wxFloatProperty(_("horizontal angle"),wxPG_LABEL,horizontal_angle);
			if(!p->property_editable())h_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, h_prop, p );
			wxPGProperty* t_prop = wxFloatProperty(_("twist angle"),wxPG_LABEL,twist_angle);
			if(!p->property_editable())t_prop->SetFlag(wxPG_PROP_READONLY);
			new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, t_prop, p );
		}
		break;
	case CheckPropertyType:
		{
			wxPGProperty* new_prop = wxBoolProperty(p->GetShortString(),wxPG_LABEL, ((PropertyCheck*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
			m_pg->SetPropertyAttribute(new_prop, wxPG_BOOL_USE_CHECKBOX, true);
		}
		break;
	case ListOfPropertyType:
		{
			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
			std::list< Property* >::iterator It;
			for(It = ((PropertyList*)p)->m_list.begin(); It != ((PropertyList*)p)->m_list.end(); It++){
				Property* p2 = *It;
				AddProperty(p2, new_prop);
			}
		}
		break;
	case FilePropertyType:
		{
			wxPGProperty *new_prop = wxFileProperty(p->GetShortString(),wxPG_LABEL, ((PropertyFile*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	case DirectoryPropertyType:
		{
			wxPGProperty *new_prop = wxDirProperty(p->GetShortString(),wxPG_LABEL, ((PropertyDir*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	}
}
//-----------------------------------------------------------------------
void BillboardRendererPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_RENDERER_TYPE = _("Renderer type");
	PRNL_BILLBOARD_TYPE = _("Billboard type");
	BBT_POINT = _("Point");
	BBT_ORIENTED_COMMON = _("Oriented Common");
	BBT_ORIENTED_SELF = _("Oriented Self");
	BBT_PERPENDICULAR_COMMON = _("Perpendicular Common");
	BBT_PERPENDICULAR_SELF = _("Perpendicular Self");
	BBT_ORIENTED_SHAPE = _("Oriented Shape");
	PRNL_ORIGIN = _("Origin");
	ORG_TOP_LEFT = _("Top-left");
	ORG_TOP_CENTER = _("Top-center");
	ORG_TOP_RIGHT = _("Top-right");
	ORG_CENTER_LEFT = _("Center-left");
	ORG_CENTER_RIGHT = _("Center-right");
	ORG_CENTER = _("Center");
	ORG_BOTTOM_LEFT = _("Bottom-left");
	ORG_BOTTOM_RIGHT = _("Bottom-right");
	ORG_BOTTOM_CENTER = _("Bottom-center");
	PRNL_ROTATION_TYPE = _("Rotation type");
	RT_VERTEX = _("Vertex");
	RT_TEXTURE_COORDINATES = _("Texture coordinates");
	PRNL_COMMON_DIRECTION = _("Common direction");
	PRNL_UP_VECTOR = _("Up Vector");
	PRNL_POINT_RENDERING = _("Point Rendering");
	PRNL_ACCURATE_FACING = _("Accurate Facing");
	ACF_ON = _("On");
	ACF_OFF = _("Off");
	PRNL_RENDERER_USE_SOFT_PARTICLES = _("Use soft particles");
	PRNL_RENDERER_SOFT_PARTICLES_CONTRAST_POWER = _("Soft particles contrast power");
	PRNL_RENDERER_SOFT_PARTICLES_SCALE = _("Soft particles scale");
	PRNL_RENDERER_SOFT_PARTICLES_DELTA = _("Soft particles delta");
	PRNL_X = _(".x");
	PRNL_Y = _(".y");
	PRNL_Z = _(".z");

	mHelpHtml = wxT("RendererBillboard.html");

	// Billboard Type: List
	mBillboardTypes.Add(BBT_POINT);
	mBillboardTypes.Add(BBT_ORIENTED_COMMON);
	mBillboardTypes.Add(BBT_ORIENTED_SELF);
	mBillboardTypes.Add(BBT_PERPENDICULAR_COMMON);
	mBillboardTypes.Add(BBT_PERPENDICULAR_SELF);
	mBillboardTypes.Add(BBT_ORIENTED_SHAPE);
	wxPGId pid = Append(wxEnumProperty(PRNL_BILLBOARD_TYPE, PRNL_BILLBOARD_TYPE, mBillboardTypes));

	// Origin: List
	mOrigin.Add(ORG_TOP_LEFT);
	mOrigin.Add(ORG_TOP_CENTER);
	mOrigin.Add(ORG_TOP_RIGHT);
	mOrigin.Add(ORG_CENTER_LEFT);
	mOrigin.Add(ORG_CENTER_RIGHT);
	mOrigin.Add(ORG_CENTER);
	mOrigin.Add(ORG_BOTTOM_LEFT);
	mOrigin.Add(ORG_BOTTOM_RIGHT);
	mOrigin.Add(ORG_BOTTOM_CENTER);
	pid = Append(wxEnumProperty(PRNL_ORIGIN, PRNL_ORIGIN, mOrigin));

	// Rotation Type: List
	mRotationTypes.Add(RT_VERTEX);
	mRotationTypes.Add(RT_TEXTURE_COORDINATES);
	pid = Append(wxEnumProperty(PRNL_ROTATION_TYPE, PRNL_ROTATION_TYPE, mRotationTypes));

	// Common Direction: Ogre::Vector3
	appendVector3(PRNL_COMMON_DIRECTION, PRNL_COMMON_DIRECTION, ParticleUniverse::BillboardRenderer::DEFAULT_COMMON_DIRECTION);

	// Common Up Vector: Ogre::Vector3
	appendVector3(PRNL_UP_VECTOR, PRNL_UP_VECTOR, ParticleUniverse::BillboardRenderer::DEFAULT_COMMON_UP_VECTOR);

	// Point Rendering: bool
	Append(wxBoolProperty(PRNL_POINT_RENDERING, PRNL_POINT_RENDERING, ParticleUniverse::BillboardRenderer::DEFAULT_POINT_RENDERING));

	// Accurate Facing: List
	mAccurateFacing.Add(ACF_ON);
	mAccurateFacing.Add(ACF_OFF);
	wxPGProperty* prop = wxEnumProperty(PRNL_ACCURATE_FACING, PRNL_ACCURATE_FACING, mAccurateFacing);
	Append(prop);
	prop->SetValueFromString(ACF_OFF);

	// Note: Although soft particles are generic renderer properties, they currently only work in combination with a billboard renderer.

	// Use soft particles: Bool
	Append(wxBoolProperty(PRNL_RENDERER_USE_SOFT_PARTICLES, 
		PRNL_RENDERER_USE_SOFT_PARTICLES, 
		ParticleUniverse::ParticleRenderer::DEFAULT_USE_SOFT_PARTICLES));

	// Soft particles contrast power: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_RENDERER_SOFT_PARTICLES_CONTRAST_POWER, 
		PRNL_RENDERER_SOFT_PARTICLES_CONTRAST_POWER, 
		ParticleUniverse::ParticleRenderer::DEFAULT_SOFT_PARTICLES_CONTRAST_POWER));
	SetPropertyEditor(PRNL_RENDERER_SOFT_PARTICLES_CONTRAST_POWER, wxPG_EDITOR(SpinCtrl));

	// Soft particles scale: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_RENDERER_SOFT_PARTICLES_SCALE, 
		PRNL_RENDERER_SOFT_PARTICLES_SCALE, 
		ParticleUniverse::ParticleRenderer::DEFAULT_SOFT_PARTICLES_SCALE));
	SetPropertyEditor(PRNL_RENDERER_SOFT_PARTICLES_SCALE, wxPG_EDITOR(SpinCtrl));

	// Soft particles delta: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_RENDERER_SOFT_PARTICLES_DELTA, 
		PRNL_RENDERER_SOFT_PARTICLES_DELTA, 
		ParticleUniverse::ParticleRenderer::DEFAULT_SOFT_PARTICLES_DELTA));
	SetPropertyEditor(PRNL_RENDERER_SOFT_PARTICLES_DELTA, wxPG_EDITOR(SpinCtrl));
}
void EditorConstantModule::fillPropertyGrid (wxPropertyGrid *pg)
{
	pg->Append( wxPropertyCategory(wxT("Parameters")) );
	pg->Append( wxFloatProperty(wxT("Value"), wxPG_LABEL, mModule.getValue()) );
}
bool ConfigOptionsDialog::AddPropGridSelectValue(ConfigSelectValue & selectValue, wxPGId parentHeaderID, const string & parentNamePath)
{
  wxPGId addID = 0;

  // Calculate the child path
  string selectNamePath = parentNamePath + string(".") + selectValue.typeName;

  // Add a selection based on the type
  switch(selectValue.configType)
  {
    case(CT_String):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a string property
        addID = propGrid->AppendIn(parentHeaderID, wxStringProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_KeyCombination):
    case(CT_StringList):
      {
        // Get the default values
        wxArrayString defaultValues;
        for(uint i=0; i<selectValue.defaultValue.size(); i++)
        {
          defaultValues.Add(selectValue.defaultValue[i].c_str());
        }

        // Add a string-list property
        addID = propGrid->AppendIn(parentHeaderID, wxArrayStringProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValues));
      }
      break;

    case(CT_Boolean):
      {
        // Get the default value
        bool defaultValue = false;
        if(selectValue.defaultValue.size() > 0)
        {
          // If the default value is true
          if(selectValue.defaultValue[0] == CONFIG_PLUGIN_TOKEN_TRUE)
          {
            defaultValue = true;
          }
          else if(selectValue.defaultValue[0] == CONFIG_PLUGIN_TOKEN_FALSE)
          {
            defaultValue = false;
          }
          else
          {
            wxLogError("AddPropGridSelectValue - Unknown boolean value \"%s\"", selectValue.defaultValue[0].c_str());
            return false;
          }
        }

        // Add a boolean selection
        addID = propGrid->AppendIn(parentHeaderID, wxBoolProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Int):
      {
        // Get the default value
        int defaultValue = 0;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = atoi(selectValue.defaultValue[0].c_str());
        }

        // Add a int property
        addID = propGrid->AppendIn(parentHeaderID, wxIntProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_UInt):
      {
        // Get the default value
        unsigned int defaultValue = 0;
        if(selectValue.defaultValue.size() > 0)
        {
          int testValue = atoi(selectValue.defaultValue[0].c_str());
          if(testValue >= 0)
          {
            defaultValue = testValue;
          }
        }

        // Add a uint property
        addID = propGrid->AppendIn(parentHeaderID, wxUIntProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Float):
      {
        // Get the default value
        float defaultValue = 0.0f;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = atof(selectValue.defaultValue[0].c_str());
        }

        // Add a float property
        addID = propGrid->AppendIn(parentHeaderID, wxFloatProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Enum):
      {
        // Get the default value
        wxArrayString enumValues;
        int defaultValue = 0;
        for(uint i=0; i<selectValue.enumValueTypes.size(); i++)
        {
          enumValues.Add(selectValue.enumValueTypes[i].c_str());

          // Check if the value is the default value
          if(selectValue.defaultValue.size() > 0 &&
             selectValue.defaultValue[0] == selectValue.enumValueTypes[i])
          {
            defaultValue = i;
          }
        }

        // Add a enum property
        addID = propGrid->AppendIn(parentHeaderID, wxEnumProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), enumValues, defaultValue));
      }
      break;


    case(CT_EnumMulti):
      {
        // Get the default value
        wxArrayString enumValues;
        wxArrayInt defaultValues;
        for(uint i=0; i<selectValue.enumValueTypes.size(); i++)
        {
          enumValues.Add(selectValue.enumValueTypes[i].c_str());

          // Check if the value is the default value
          for(uint i2=0; i2<selectValue.defaultValue.size(); i2++)
          {
            // Compare the default value to the enum value
            if(selectValue.defaultValue[i2] == selectValue.enumValueTypes[i])
            {
              defaultValues.Add(i);
              break;
            }
          }
        }

        // Add a multiselect enum property
        addID = propGrid->AppendIn(parentHeaderID, wxMultiChoiceProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), enumValues, defaultValues));
      }
      break;

    case(CT_DirSelect):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a directory select property
        addID = propGrid->AppendIn(parentHeaderID, wxDirProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_FileSelect):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a file select property
        addID = propGrid->AppendIn(parentHeaderID, wxFileProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    default:
      wxLogError("AddPropGridSelectValue - Unknown type");
      return false;
  }

  // Assign the comment string
  wxString commentStr = selectValue.commentString.c_str();
  commentStr.Replace("\\n", "\n");
  propGrid->SetPropertyHelpString(addID, commentStr);

  return true;
}
//-----------------------------------------------------------------------
void PhysXFluidExternPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_PHYSX_REST_PARTICLE_PER_METER = _("Rest particle per meter");
	PRNL_PHYSX_REST_DENSITY = _("Rest density");
	PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER = _("Kernel radius multiplier");
	PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER = _("Motion limit multiplier");
	PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER = _("Collision dist. multiplier");
	PRNL_PHYSX_PACKET_SIZE_MULTIPLIER = _("Packet size multiplier");
	PRNL_PHYSX_STIFFNESS = _("Stiffness");
	PRNL_PHYSX_VISCOSITY = _("Viscosity");
	PRNL_PHYSX_SURFACE_TENSION = _("Surface tension");
	PRNL_PHYSX_DAMPING = _("Damping");
	PRNL_PHYSX_EXTERNAL_ACCELERATION = _("External acceleration");
	PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES = _("Restitution static shapes");
	PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES = _("Dyn. friction static shapes");
	PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES = _("Static friction static shapes");
	PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES = _("Attraction static shapes");
	PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES = _("Restitution dynamic shapes");
	PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Dyn. friction dyn. shapes");
	PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Static friction dyn. shapes");
	PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES = _("Attraction dynamic shapes");
	PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT = _("Collision response coeff.");
	PRNL_PHYSX_SIMULATION_METHOD = _("Simulation method");
	PRNL_PHYSX_COLLISION_METHOD = _("Collision method");
	PRNL_PHYSX_FLAG_VISUALIZATION = _("Visualisation");
	PRNL_PHYSX_FLAG_DISABLE_GRAVITY = _("Disable gravity");
	PRNL_PHYSX_FLAG_COLLISION_TWOWAY = _("Collision twoway");
	PRNL_PHYSX_FLAG_FLUID_ENABLED = _("Fluid enabled");
	PRNL_PHYSX_FLAG_HARDWARE = _("Hardware");
	PRNL_PHYSX_FLAG_PRIORITY_MODE = _("Priority mode");
	PRNL_PHYSX_FLAG_PROJECT_TO_PLANE = _("Project to plane");
	PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT = _("Strict cooking format");
	PHYSX_INTERCOLLISION = _("Intercollision");
	PHYSX_NOINTERCOLLISION = _("Non-intercollision");
	PHYSX_MIX_INTERCOLLISION = _("Mixed intercollision");
	PHYSX_STATIC = _("Static");
	PHYSX_DYNAMIC = _("Dynamic");

	mHelpHtml = wxT("ExternPhysXFluid.html");

	NxFluidDesc fluidDesc;
	fluidDesc.setToDefault();

	// Rest particle per meter: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_REST_PARTICLE_PER_METER, PRNL_PHYSX_REST_PARTICLE_PER_METER, fluidDesc.restParticlesPerMeter));
	SetPropertyEditor(PRNL_PHYSX_REST_PARTICLE_PER_METER, wxPG_EDITOR(SpinCtrl));

	// Rest density: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_REST_DENSITY, PRNL_PHYSX_REST_DENSITY, fluidDesc.restDensity));
	SetPropertyEditor(PRNL_PHYSX_REST_DENSITY, wxPG_EDITOR(SpinCtrl));

	// Kernel radius multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, fluidDesc.kernelRadiusMultiplier));
	SetPropertyEditor(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Motion limit multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, fluidDesc.motionLimitMultiplier));
	SetPropertyEditor(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Collision distance multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, fluidDesc.collisionDistanceMultiplier));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Packet size multiplier: NxU32
	Append(wxUIntProperty(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, fluidDesc.packetSizeMultiplier));
	SetPropertyEditor(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Stiffness: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STIFFNESS, PRNL_PHYSX_STIFFNESS, fluidDesc.stiffness));
	SetPropertyEditor(PRNL_PHYSX_STIFFNESS, wxPG_EDITOR(SpinCtrl));

	// Viscosity: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_VISCOSITY, PRNL_PHYSX_VISCOSITY, fluidDesc.viscosity));
	SetPropertyEditor(PRNL_PHYSX_VISCOSITY, wxPG_EDITOR(SpinCtrl));

	// Surface tension: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_SURFACE_TENSION, PRNL_PHYSX_SURFACE_TENSION, fluidDesc.surfaceTension));
	SetPropertyEditor(PRNL_PHYSX_SURFACE_TENSION, wxPG_EDITOR(SpinCtrl));

	// Damping: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DAMPING, PRNL_PHYSX_DAMPING, fluidDesc.damping));
	SetPropertyEditor(PRNL_PHYSX_DAMPING, wxPG_EDITOR(SpinCtrl));

	// External acceleration: NxVec3
	appendVector3(PRNL_PHYSX_EXTERNAL_ACCELERATION, PRNL_PHYSX_EXTERNAL_ACCELERATION, 
		ParticleUniverse::PhysXMath::convert(fluidDesc.externalAcceleration));

	// Restitution for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, fluidDesc.restitutionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Dynamic friction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.dynamicFrictionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Static friction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.staticFrictionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Attraction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, fluidDesc.attractionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Restitution for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, fluidDesc.restitutionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Dynamic friction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.dynamicFrictionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Static friction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.staticFrictionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Attraction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, fluidDesc.attractionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Collision response coefficient: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, fluidDesc.collisionResponseCoefficient));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, wxPG_EDITOR(SpinCtrl));

	// Collision group: NxCollisionGroup
	Append(wxUIntProperty(PRNL_PHYSX_COLLISION_GROUP, PRNL_PHYSX_COLLISION_GROUP, fluidDesc.collisionGroup));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_GROUP, wxPG_EDITOR(SpinCtrl));

	// Simulation method: List
	wxArrayString simulationMethod;
	simulationMethod.Add(PHYSX_INTERCOLLISION);
	simulationMethod.Add(PHYSX_NOINTERCOLLISION);
	simulationMethod.Add(PHYSX_MIX_INTERCOLLISION);
	wxPGId pid = Append(wxEnumProperty(PRNL_PHYSX_SIMULATION_METHOD, PRNL_PHYSX_SIMULATION_METHOD, simulationMethod));

	// Collision method: List
	wxArrayString collisionMethod;
	collisionMethod.Add(PHYSX_STATIC);
	collisionMethod.Add(PHYSX_DYNAMIC);
	wxPGId pid2 = Append(wxEnumProperty(PRNL_PHYSX_COLLISION_METHOD, PRNL_PHYSX_COLLISION_METHOD, collisionMethod));

	// Visualisation: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_VISUALIZATION, PRNL_PHYSX_FLAG_VISUALIZATION, fluidDesc.flags & NX_FF_VISUALIZATION));

	// Disable gravity: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_DISABLE_GRAVITY, PRNL_PHYSX_FLAG_DISABLE_GRAVITY, fluidDesc.flags & NX_FF_DISABLE_GRAVITY));

	// Collision twoway: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_COLLISION_TWOWAY, PRNL_PHYSX_FLAG_COLLISION_TWOWAY, fluidDesc.flags & NX_FF_COLLISION_TWOWAY));

	// Fluid enabled: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_FLUID_ENABLED, PRNL_PHYSX_FLAG_FLUID_ENABLED, fluidDesc.flags & NX_FF_ENABLED));

	// Hardware: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_HARDWARE, PRNL_PHYSX_FLAG_HARDWARE, fluidDesc.flags & NX_FF_HARDWARE));

	// Priority mode: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_PRIORITY_MODE, PRNL_PHYSX_FLAG_PRIORITY_MODE, fluidDesc.flags & NX_FF_PRIORITY_MODE));

	// Project to plane: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, fluidDesc.flags & NX_FF_PROJECT_TO_PLANE));

	// Strict cooking format: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, fluidDesc.flags & NX_FF_FORCE_STRICT_COOKING_FORMAT));
}