Syflex Development Kit
Introduction
Example
Files
Code
Introduction


The SDK allows you to add entirely new features by letting you create your own forces and constraints.
This is an advanced functionality: you need to know how to program in C++, and how to write a plugin for XSI.

A simple example is provided as a base for the implementation of your own forces.
Example


A simple example is provided in the directory sdk/syForce.
It shows a simple collision force on the horizontal plane y=-10.


To compile the plugin:
  • Windows
    open the workspace in VisualC++:
    sdk/syForce/win/win.dsw
    press F7
    it requires the library syLib.lib located in the lib/ directory.
  • Linux
    cd sdk/syForce/src
    make
    It requires the library syLib.a located in the lib/ directory

The compiled plugin (syForce.dll or syForce.so) can be loaded in XSI through:
File > Add-on > Plugins
To test it: load the scene Syflex_simple.scn
or copy/paste the following commands:
  CreatePrim "Grid", "MeshSurface"
  SetValue "grid.grid.ulength", 20
  SetValue "grid.grid.vlength", 20
  SetValue "grid.polymsh.geom.subdivu", 20
  SetValue "grid.polymsh.geom.subdivv", 20
  SelectObj "grid", , True
  SyCreateCloth
  SetValue "grid.polymsh.syCloth.syProperties.StretchStiffness", 1
  SetValue "grid.polymsh.syCloth.syProperties.ShearStiffness", 1
  SetValue "grid.polymsh.syCloth.syProperties.BendStiffness", 0.2
  SetValue "grid.polymsh.syCloth.syProperties.StretchDamping", 0.01
  SetValue "grid.polymsh.syCloth.syProperties.ShearDamping", 0.01
  SetValue "grid.polymsh.syCloth.syProperties.BendDamping", 0.002
  SyCreateGravity
  SetValue "grid.polymsh.syCloth.syGravity.Gy", -0.1
  SyCreateDamp
  SetValue "grid.polymsh.syCloth.syDamp.Damp", 0.002
  SetSelFilter "Vertex"
  SelectGeometryComponents "grid.pnt[LAST]"
  AddToSelection "grid.pnt[420]", , True
  SyCreateNail
To add your new force to this cloth, apply the force on it:
  applyOperator "syForce", "grid.polymsh.syCloth"
You can check in the explorer window that the force has indeed been added to the cloth:


Run the simulation: the cloth now bounces on the plane y=-10.

You can create a command that applies the syForce operator to the selected cloth. Then add a new item to the Syflex menu.
The scripts in the directory syflex/sdk/scripts will help you do that.

Files


The plugin is divided in two layers:
The UI layer
This layer contains all the interface with XSI. No computation is done here.
Files:
• syForceX.c
Creation of the user interface of the force in XSI.
Transfer the parameters of the force from XSI to the computational layer.
• syForce.spdl
Definition of the connections, parameters and UI for XSI.
.
• syXforce.def
Exported functions.

The computational layer
This is where all the computation is done. It is completely independent from XSI.
The class contains a compute method called by the simulation. The compute method computes the force applied on each vertex of the cloth.
Files:
• syForceS.c
syInc.h
This include file contains the base classes used by the SDK.
You should not modify anything in this file.
syForce.h
Contains the definition of our force.
This is the file you need to modify to create your own force.
It contains 2 classes:

syForceS
This is the class where the force is computed.
It is completely indpendent from XSI.

syForceX
This class contains the user interface with XSI.
syForce.spdl
This file contains the definition of the UI in XSI.
In this example there are only 2 parameters for the force:
Mute
K

It's a good thing to always have a Mute parameter.
The 'PortSet' section in this file should not be modified.
syForce.def
This file is only used in Windows to define the 3 interface functions called by XSI: syForce_Init, syForce_Term and syForce_Update.

syForceS.h
This is where all the computation is done, through the compute method of the class. There is nothing related to XSI in this file.
syForceX.h
This is where the force is created in XSI. The Update function just transfers the parameters from the XSI user interface to the computational layer syForceS.
Code


A cloth in the simulator is represented by particles associated to each vertex, linked together by springs. The particle class contains informations for each particle, such as its position and velocity.
// particle class
class sySparticle {
  public:
    sySparticle();
    ~sySparticle();

    int nbParticle;    number of particles
    float3* position;  position of each particle
    float3* normal;    normal of each particle
    float3* velocity;  velocity of each particle
    float3* force;     force at each particle
    float* mass;       mass of each particle
};
Position is initialized from the XSI shape.
Velocity is computed at each frame.
Force is the sum of all forces applied on each vertex.
Your force class needs to compute a force for each particle, and add it to this 'force' array. This computation is based on the position, speed and mass of the particles. This is done through the compute method of the syForceS class.
// force class
class syForceS : public class sySforce{
public:
  sySforce();
  virtual ~syforceS();
  
  int type() { return 32; }  
  void compute( sySparticle &p, sySsolver &s );

  float k;
};
You can add additional parameters used by the force in this class.
In this example, there is only one parameter: 'k'.
The base class contains only one useful variable:
'active' is used to mute or activate the force.
syForceS::syForceS() {
  active = 1;
  plan = 0;
  
  k = 0.01f;
}
syForceS::~syForceS() {}
void syForceS::compute( sySparticle &p, sySsolver &s ) {
  int i,n;
  float3 *F, *P;

  n = p.nbParticle;
  F = p.force;
  P = p.position;

  for(i=0;i<n;i++) {
    if( P[i][1]<-10 )
      F[i][1] += k;
  }
}
The compute method calculates the force for each vertex.
If the position along the Y axis of a particle becomes smaller than -10 (P[i][1]<-10), then this particle is added a constant force along the +Y axis, pulling the vertex above the plane Y=-10.

The syForce_Update is called by XSI at each frame. It transfers the parameters from the UI to the computational layer:
CStatus syForce_Update(...) {
  ...
  bool mute = op.GetParameterValue(L"mute");
  float k = op.GetParameterValue(L"K");
  force->active = !mute;
  force->k = k;
  ...
}
Syflex LLC - www.syflex.biz