Horde3D
http://horde3d.org/forums/

HordeControls
http://horde3d.org/forums/viewtopic.php?f=4&t=178
Page 1 of 1

Author:  confused [ 18.10.2007, 19:30 ]
Post subject:  HordeControls

We created for our project a set of wrapper classes in C# for Horde3D objects (using the .NET wrapper for Horde3D from Martin Burkhart). We also had a look at the samples and we thought about a UserControl "HordePanel" which encapsulates the wohle rendering logic. The wrapper classes (we called them "HordeControls") can be added to the panel.

We think that these classes can help developers to create small to medium sized applications with Horde3D and C#.

After adding the library to a project, you can easily add the "HordePanel" onto your form in the VS Form-Editor. One "Init(...)" call and the panel starts the render loop with the given options.

We "ported" the Chicago sample to our controls and we noticed that we only needed the real "application" code and there was no Horde-specific code inside. This was quite cool.

Here are some code snippets of the "code smell":

Code:
Camera camera = new Camera(); // create the main camera object
camera.Position = new Point3D(0, 120, 0); // set the position
camera.Rotation = new Point3D(-90, 0, 0); // and rotation
hordePanel1.Add(camera); // add the camera to the panel


Code:
Emitter emitter = new Emitter("MovingEmitter", new Material("particle.material.xml"), new Effect("particle.effect.xml"), 500, -1); // create an emitter
emitter.Position = new Point3D(50, 70, 50); // current position of the emitter
emitter.EmissionRate = 10.0f;
emitter.SpreadAngle = 90.0f;           

MovingRotatingScaling movControl = new MovingRotatingScaling(emitter); // MovingRotatingScaling is a control that has another control inside and that can be moved, rotated or scaled in a given speed to a desired value
movControl.DesiredPosition = new Point3D(100, 70, 100); // we want the emitter to move to this position
movControl.MovingSpeed = 3.0f; // the moving speed
movControl.PositionListener = new ReachedListener(PositionReached); // register a listener when the position is reached

hordePanel1.Add(movControl); // we don't need to add the emitter, because it is already part of the MovingRotatingScaling control


After starting the application, we provide a context menu when someone right clicks on the panel. In this menu you can switch to FullScreen mode or display some settings. These settings contain the logfile of Horde (displayed in a WebBrowser) and the current HordeOptions. As a further feature you can browse through the HordeControls that are currently "in" the panel and you can simply modify their properties like the position or the rotation in a property grid.

Here is a screenshot of the HordePanel and the settings view. In this example, Horde3D is "switched off". This means that there are no Horde calls but tje controls change their values as you would expect. This is for developers who have to develop some behaviour logic in an application and who do not have strong hardware.

Image

Puh, I did not mean to write such a long text, I'm sorry...if you are interested, just have a look at our project website. There you will find the source code for the "HordeControls".

I'm planning to add the "ported" Chicago sample to this post so that you can see how less code we need.

Author:  confused [ 19.10.2007, 09:32 ]
Post subject:  Ported Chicago sample

Ok, now I want to provide some code snippets from the ported Chicago sample.

After starting the application, the HordePanel has to be initialized. This should be done in the Load method of the form where the panel lies in. We also add all the controls we need like the two lights, the skybox and, of course, the crowd:

Code:
private void MainForm_Load(object sender, EventArgs e)
{
    // configure horde options
    HordeOptions options = new HordeOptions();
    options.Pipeline = "pipeline_Chicago.xml";
    options.FastAnimation = true;
   
    // init the panel
    hordePanel1.Init(options);

    // create controls
    SceneGraphObject env = new SceneGraphObject(new SceneGraphResource("scene.scene.xml"));
    SceneGraphObject skybox = new SceneGraphObject(new SceneGraphResource("skybox.scene.xml"));           
    Light light1 = new Light("Light1", new Material("light.material.xml"));
    Light light2 = new Light("Light2", new Material("light.material.xml"));
    Camera camera = new Camera();
    CrowdControl crowd = new CrowdControl();
 
    // configure controls
    skybox.Scale = new Point3D(500, 500, 500);

    camera.Position = new Point3D(0, 10, 0);
    camera.Rotation = new Point3D(-90, 0, 0);
          
    light1.Position = new Point3D(0,25,-25);
    light1.Rotation = new Point3D(-120,0,0);
    light1.Radius = 100;
    light1.FOV = 90;
    light1.Col_B = 0.5f;
    light1.Col_R = 0.98f;
    light1.Col_G = 0.6f;
   
    light2.Position = new Point3D(0, 25, 30);
    light2.Rotation = new Point3D(-60, 0, 0);
    light2.Radius = 50;
    light2.FOV = 90;
    light2.Col_B = 0.98f;
    light2.Col_R = 0.5f;
    light2.Col_G = 0.6f;

    // add controls to panel
    hordePanel1.Add(light1);
    hordePanel1.Add(light2);
    hordePanel1.Add(skybox);
    hordePanel1.Add(env);
    hordePanel1.Add(camera);
    hordePanel1.Add(crowd);
}


That's all we have to do in the form. You may have noticed the "CrowdControl" class. This is a class we implemented in this sample. This class inherits from the HordeControl "Container" and it has the possibility to hold arbitrary other HordeControls in a list.

Here comes the class:

Code:
public class CrowdControl : Container
{
   public CrowdControl()           
   {
       for (int i = 0; i < 100; i++)
      Add(new ManControl(i));
   }
   
   public override void Render(float fps)
   {
       base.Render(fps);
       update(fps);
   }
   
   [...]


The CrowdControl has 100 "ManControl" in it's list. The "Render" method is called from the HordePanel in each Rendering loop for every control that has been added to the panel. So if we override it, we can do our application logic in every rendering loop. The Chicago sample calculates the new position and direction of each man in every loop, so we do the same in the update(...) method. We only had to change that the update method accesses the list of the CrowdControl and not the "old" "particle" list. We did not touch the calculation.

The only remaining thing is the ManControl class. A "man" consists of a SceneGraph node and an animation and he has the fields from the Chicago sample (fx, fy...). So we use an AnimationControl combined with a SceneGraphControl and we are done:

Code:
AnimatedObject _anim;
SceneGraphObject _man;
private int _index;

public float fx;
public float fz;
public float ox;
public float oz;
public float dx;
public float dz;
public float px;
public float pz;

public ManControl(int index)       
{
    _index = index;
    _man = new SceneGraphObject(new SceneGraphResource("man.scene.xml"));
    _anim = new AnimatedObject(_man,new Animation("man.anim"));
    _anim.AnimationSpeed = 20.0f;
}

public override void Render(float fps)
{
    _anim.Render(fps);
}


Because Horde3D renders the scene graph nodes one it's own, we only have to worry about that the animation is continued in the Render method.

You see that there is only the "application" logic that we had to implement. We do not care about Horde3D specific things. That is of course not suitable for all applications, because some may want to have the full possibilities the engine offers. But as mentioned, for small to medium sized applications and for programmers who start programming with a 3D engine, these HordeControls may be a good alternative.

Author:  marciano [ 22.10.2007, 18:25 ]
Post subject: 

This is a really nice project for rapid development of smaller Horde applications using .NET. Especially the integrated editor is great! :D
The classes have already proven to be useful for the xenakis table project where they made testing and debugging much more convenient.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/