Strange error using BillboardSet

instbldrjems

01-08-2008 15:53:13

I have a strange problem when instancing a class I've created that uses Billboards to display a rotating icon (e.g. a letter). The billboard uses a texture atlas image that's 512x512 with 16 separate images of the letter rotating 360 degrees. These "Indicators" float above objects in my scene to indicate that there is a playable behavior attached to the object.

Even though I use a unique string for the billboardset when the class is instanced, based on the log Mogre thinks that a billboardset of that name already exists and crashes -- but this does not happen 100% of the time. So for example out of 5 calls to the constructor, 4 will be successful but one will trigger the "Already exists" message (see the code below)

Now if I uncomment the line:

MessageBox.Show("Made BIndicator named: " + bbset.Name);

then everything works OK -- every call to the constructor completes without error. It seems that simply showing and clearing the MessageBox solves the problem

I'm somewhat new to C#, so maybe this class should be written differently -- I just have no idea what the "right" way might be.

Thanks in advance for any help you can provide!!!!

Here's the code of the class itself:


using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using Mogre;
using FSLOgreCS;
using MogreNewt;


namespace BSys
{
public class BIndicator
{
private System.Windows.Forms.Timer RotationTimer;
private SceneNode bnode = null;
private ushort cycle_counter = 0;
private Billboard bb;
private BillboardSet bbset;
private SceneManager mScM;


public BIndicator(string img_name, Entity ent, SceneManager mSceneMgr)
{

string nam = ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME;
mScM = mSceneMgr;
System.Random RandNum = new System.Random();
int MyRandomNumber = RandNum.Next(8, 14);

string mat_name = RandomString(MyRandomNumber, true);
string bb_name = RandomString(MyRandomNumber, true);

if (mSceneMgr.HasBillboardSet(bb_name))
{
MessageBox.Show("Already exists");
}
else
{
bbset = mSceneMgr.CreateBillboardSet(RandomString(MyRandomNumber, true), 16);

//MessageBox.Show("Made BIndicator named: " + bbset.Name);

bbset.SetTextureStacksAndSlices(4, 4);
TexturePtr QMark_comp = TextureManager.Singleton.GetByName(img_name);
MaterialPtr material = MaterialManager.Singleton.Create(mat_name, nam);
Pass pass = material.GetTechnique(0).GetPass(0);
TextureUnitState tstate = pass.CreateTextureUnitState();
tstate.SetTextureName(img_name);
pass.SetSceneBlending(SceneBlendType.SBT_TRANSPARENT_ALPHA);
//pass.DepthCheckEnabled = false;
pass.DepthCheckEnabled = true;

bbset.MaterialName = mat_name;
bbset.BillboardOrigin = BillboardOrigin.BBO_BOTTOM_CENTER;
bb = bbset.CreateBillboard(0, 0, 0);
bb.SetDimensions(10, 10);

/* Attach billboard set to the scene */
SceneNode node = ent.ParentSceneNode;
float hgt = Mogre.Math.Abs(ent.BoundingBox.Maximum.y - ent.BoundingBox.Minimum.y);


bnode = mSceneMgr.RootSceneNode.CreateChildSceneNode();
//bnode = node.CreateChildSceneNode();
//Position just above the top of the object's bounding-box
bnode.Position = new Vector3(node.Position.x, (node.Position.y + (hgt * 0.5f)), node.Position.z);
//MessageBox.Show("Min Y = " + ent.BoundingBox.Minimum.z + ", Max Y = " + ent.BoundingBox.Maximum.z + ", Loc = " + bnode.Position.y);
bnode.Orientation = node.Orientation;
bnode.AttachObject(bbset);

RotationTimer = new System.Windows.Forms.Timer();
RotationTimer.Tick += new System.EventHandler(RotationTimer_Tick);
RotationTimer.Enabled = false;
//2 seconds divided by 16 (for number of indexes in texture array). This could be a GUI parameter later....
RotationTimer.Interval = 125;

hide();
}
}



private void RotationTimer_Tick(object sender, EventArgs e)
{
if (cycle_counter <= 15)
{
this.bb.TexcoordIndex = cycle_counter;
cycle_counter++;
}
else
cycle_counter = 0;
}


public void start_action()
{

if (RotationTimer.Enabled == false)
{
RotationTimer.Enabled = true;
RotationTimer.Start();
show();
}
}

public void stop_action()
{
if (RotationTimer.Enabled == true)
{
RotationTimer.Enabled = false;
RotationTimer.Stop();
hide();
}
}

public void hide()
{
this.bnode.SetVisible(false);
}

public void show()
{
this.bnode.SetVisible(true);
}

/// <summary>
/// Generates a random string with the given length
/// </summary>
/// <param name="size">Size of the string</param>
/// <param name="lowerCase">If true, generate lowercase string</param>
/// <returns>Random string</returns>
public string RandomString(int size, bool lowerCase)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(System.Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
if (lowerCase)
return builder.ToString().ToLower();
return builder.ToString();
}

public void delete()
{
this.RotationTimer.Dispose();
mScM.DestroyBillboardSet(bbset);
mScM.DestroySceneNode(bnode.Name);
}



}
}