andyhebear1
26-04-2010 05:31:11
//--------------------------------------
//Rains http://hi.baidu.com/andyhebear
//QQ:233685340
//DateTime:2010-04-26
//Memo:Convert MovableText c++ To C#
//but i am not to test! Hope can help you!
//---------------------------------------
public class MovableText : SimpleRenderable {
const ushort POS_TEX_BINDING = 0;
const ushort COLOUR_BINDING = 1;
const byte UNICODE_NEL = 0x0085; ///< next line
const byte UNICODE_CR = 0x000D; ///< carriage return
const byte UNICODE_LF = 0x000A; ///< line feed
const byte UNICODE_SPACE = 0x0020; ///< space
const byte UNICODE_ZERO = 0x0030; ///< 0
const ushort OGRE_RENDERABLE_DEFAULT_PRIORITY=100;
//******************************** MovableText data ***************************
public enum HorizontalAlignment { H_LEFT, H_CENTER };
public enum VerticalAlignment { V_BELOW, V_ABOVE };
protected string mFontName = "BlueHighway";
protected string mType;//"MovableText"
protected string mName;
protected string mCaption;
protected HorizontalAlignment mHorizontalAlignment;
protected VerticalAlignment mVerticalAlignment;
protected ColourValue mColor = ColourValue.White;
protected RenderOperation mRenderOp;
protected AxisAlignedBox mAABB;
protected LightList mLList;
protected uint mCharHeight = 32;
protected uint mSpaceWidth;
protected bool mNeedUpdate;
protected bool mUpdateColors;
protected bool mOnTop;
protected float mTimeUntilNextToggle;
protected float mRadius;
protected float mAdditionalHeight;
protected Camera mpCam;//*mpCam;
protected RenderWindow mpWin;//*mpWin;
protected Font mpFont;//*mpFont;
protected MaterialPtr mpMaterial;
protected MaterialPtr mpBackgroundMaterial;
//******************************** public methods *****************************
//fontName= "BlueHighway" int charHeight = 32, const ColourValue &color = ColourValue::White
public unsafe MovableText(string name, string caption, string fontName, uint charHeight, ColourValue color) :
base(null) {
//ToDo
this.mName = name;
this.mCaption = caption;
this.mFontName = fontName;
this.mCharHeight = charHeight;
this.mColor = color;
//
if (name == "")
throw new Exception("Trying to create MovableText without name" + "MovableText:MovableText");
if (caption == "")
throw new Exception("Trying to create MovableText without caption" + "MovableText::MovableText");
mRenderOp.vertexData = null;
this.setFontName(mFontName);
this._setupGeometry();
}
~MovableText() {
if (mRenderOp.vertexData != null)
mRenderOp.vertexData.Dispose();
}
public string FontName {
get { return this.mFontName; }
set { this.mFontName = value; }
}
public string Caption {
get { return this.mCaption; }
set { this.mCaption = value; }
}
public ColourValue Color {
get { return this.mColor; }
set { this.mColor = value; }
}
public uint CharacterHeight {
get { return this.mCharHeight; }
set { this.mCharHeight = value; }
}
public uint SpaceWidth {
get { return this.mSpaceWidth; }
set { this.mSpaceWidth = value; }
}
public float AdditionalHeight {
get { return this.mAdditionalHeight; }
set { this.mAdditionalHeight = value; }
}
public bool ShowOnTop {
get { return this.mOnTop; }
set { this.mOnTop = value; }
}
// Set settings
public unsafe void setFontName(string fontName) {
if (MaterialManager.Singleton.ResourceExists(mName + "Material")) {
MaterialManager.Singleton.Remove(mName + "Material");
}
if (mFontName != fontName || mpMaterial == null || mpFont == null) {
mFontName = fontName;
mpFont = (FontPtr)FontManager.Singleton.GetByName(mFontName);
if (mpFont == null) {
throw new Exception("Could not find font " + fontName + "MovableText::setFontName");
mpFont.Load();
//
if (mpMaterial != null) {
MaterialManager.Singleton.Remove(mpMaterial.Name);
mpMaterial.Dispose();
}
mpMaterial = mpFont.GetMaterial().Clone(mName + "Material");
if (!mpMaterial.IsLoaded)
mpMaterial.Load();
mpMaterial.SetDepthCheckEnabled(!mOnTop);
mpMaterial.GetTechnique(0).GetPass(0).SetDepthBias(((!mOnTop)?1f:0f)); //setDepthBias(!mOnTop);
mpMaterial.SetDepthWriteEnabled(mOnTop);
mpMaterial.SetLightingEnabled(false);
mNeedUpdate = true;
}
#region
// if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material")))
//{
// Ogre::MaterialManager::getSingleton().remove(mName + "Material");
//}
//if (mFontName != fontName || mpMaterial.isNull() || !mpFont)
//{
// mFontName = fontName;
// mpFont = (Font *)FontManager::getSingleton().getByName(mFontName).getPointer();
// if (!mpFont)
// Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "MovableText::setFontName");
// mpFont->load();
// if (!mpMaterial.isNull())
// {
// MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
// mpMaterial.setNull();
// }
// mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
// if (!mpMaterial->isLoaded())
// mpMaterial->load();
// mpMaterial->setDepthCheckEnabled(!mOnTop);
// mpMaterial->getTechnique(0)->getPass(0)->setDepthBias(!mOnTop); //setDepthBias(!mOnTop);
// mpMaterial->setDepthWriteEnabled(mOnTop);
// mpMaterial->setLightingEnabled(false);
// mNeedUpdate = true;
//}
#endregion
}
}
public void setCaption(string caption) {
if (caption != mCaption) {
mCaption = caption;
this.mNeedUpdate = true;
}
}
public void setColor(ColourValue color) {
if (color != mColor) {
mColor = color;
mUpdateColors = true;
}
}
public void setCharacterHeight(uint height) {
if (height != mCharHeight) {
mCharHeight = height;
mNeedUpdate = true;
}
}
public void setSpaceWidth(uint width) {
if (width != mSpaceWidth) {
mSpaceWidth = width;
mNeedUpdate = true;
}
}
public void setTextAlignment(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
if (mHorizontalAlignment != horizontalAlignment) {
mHorizontalAlignment = horizontalAlignment;
mNeedUpdate = true;
}
if (mVerticalAlignment != verticalAlignment) {
mVerticalAlignment = verticalAlignment;
mNeedUpdate = true;
}
}
public void setAdditionalHeight(float height) {
if (mAdditionalHeight != height) {
mAdditionalHeight = height;
mNeedUpdate = true;
}
}
public void showOnTop(bool show) {
if (mOnTop != show && mpMaterial != null) {
mOnTop = show;
int dep = 1;
if (show)
dep = 0;
mpMaterial.GetTechnique(0).GetPass(0).SetDepthBias(dep);
mpMaterial.SetDepthCheckEnabled(!mOnTop);
mpMaterial.SetDepthWriteEnabled(mOnTop);
}
}
// Get settings
public string getFontName() { return mFontName; }
public string getCaption() { return mCaption; }
public ColourValue getColor() { return mColor; }
public uint getCharacterHeight() { return mCharHeight; }
public uint getSpaceWidth() { return mSpaceWidth; }
public float getAdditionalHeight() { return mAdditionalHeight; }
public bool getShowOnTop() { return mOnTop; }
public AxisAlignedBox GetAABB() { return mAABB; }
//******************************** protected methods and overload *************
// from MovableText, create the object
protected unsafe void _setupGeometry() {
System.Diagnostics.Debug.Assert(mpFont != null);
System.Diagnostics.Debug.Assert(mpMaterial != null);
uint vertexCount = (uint)(mCaption.Length * 6);
if (mRenderOp.vertexData != null) {
// Removed this test as it causes problems when replacing a caption
// of the same size: replacing "Hello" with "hello"
// as well as when changing the text alignment
if (mRenderOp.vertexData.vertexCount != vertexCount) {
mRenderOp.vertexData.Dispose();
mRenderOp.vertexData = null;
mUpdateColors = true;
}
}
if (mRenderOp.vertexData != null)
mRenderOp.vertexData = new VertexData();
mRenderOp.indexData = new IndexData();
mRenderOp.vertexData.vertexStart = 0;
mRenderOp.vertexData.vertexCount = vertexCount;
mRenderOp.operationType = RenderOperation.OperationTypes.OT_TRIANGLE_LIST;
mRenderOp.useIndexes = false;
VertexDeclaration decl = mRenderOp.vertexData.vertexDeclaration;
VertexBufferBinding bind = mRenderOp.vertexData.vertexBufferBinding;
uint offset = 0;
// create/bind positions/tex.ccord. buffer
if (decl.FindElementBySemantic(VertexElementSemantic.VES_POSITION) != null)
decl.AddElement(POS_TEX_BINDING, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION);
offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
if (decl.FindElementBySemantic(VertexElementSemantic.VES_TEXTURE_COORDINATES) != null)
decl.AddElement(POS_TEX_BINDING, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0);
HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(decl.GetVertexSize(POS_TEX_BINDING),
mRenderOp.vertexData.vertexCount,
HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY);
bind.SetBinding(POS_TEX_BINDING, ptbuf);
//// Colours - store these in a separate buffer because they change less often
if (decl.FindElementBySemantic(VertexElementSemantic.VES_DIFFUSE)!=null)
decl.AddElement(COLOUR_BINDING, 0, VertexElementType.VET_COLOUR, VertexElementSemantic.VES_DIFFUSE);
HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(decl.GetVertexSize(COLOUR_BINDING),
mRenderOp.vertexData.vertexCount,
HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY);
bind.SetBinding(COLOUR_BINDING, cbuf);
int charlen = mCaption.Length;
float* pPCBuff = (float*)(ptbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD));
float largestWidth = 0f;
float left = 0f * 2.0f - 1.0f;
float top = -((0f * 2.0f) - 1.0f);
//// Derive space width from a capital A
if (mSpaceWidth == 0)
mSpaceWidth = System.Convert.ToUInt32(mpFont.GetGlyphAspectRatio('A') * mCharHeight * 2.0f);
//// for calculation of AABB
Mogre.Vector3 min=new Vector3(0,0,0), max=new Vector3(0,0,0), currPos;
float maxSquaredRadius=0f;
bool first = true;
//// Use iterator
int i, iend;
iend = mCaption.Length;
bool newLine = true;
float len = 0.0f;
if(mVerticalAlignment ==VerticalAlignment.V_ABOVE)
{
// Raise the first line of the caption
top += mCharHeight;
for (i = 0; i != iend; ++i)
{
if (Caption[i] == '\n')
top += mCharHeight * 2.0f;
}
}
for (i = 0; i != iend; ++i)
{
if (newLine)
{
len = 0.0f;
for (int j = i; j != iend && Caption[j] != '\n'; j++)
{
if (Caption[j] == ' ')
len += mSpaceWidth;
else
len += mpFont.GetGlyphAspectRatio((uint)j) * mCharHeight * 2.0f;
}
newLine = false;
}
if (Caption[i] == '\n') {
left = 0f * 2.0f - 1.0f;
top -= mCharHeight * 2.0f;
newLine = true;
continue;
}
if (Caption[i] == ' ') {
// Just leave a gap, no tris
left += mSpaceWidth;
// Also reduce tri count
mRenderOp.vertexData.vertexCount -= 6;
continue;
}
float horiz_height = mpFont.GetGlyphAspectRatio((uint)i);
float u1, u2, v1, v2;
Mogre.FloatRect rect;
rect = mpFont.GetGlyphTexCoords((uint)i); // (*i, u1, v1, u2, v2);
u1 = rect.left;
v1 = rect.top;
u2 = rect.right;
v2 = rect.bottom;
// each vert is (x, y, z, u, v)
//-------------------------------------------------------------------------------------
// First tri
//
// Upper left
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u1;
*pPCBuff++ = v1;
// Deal with bounds
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
currPos =new Mogre.Vector3(left, top, -1.0f);
else
currPos =new Vector3(left - (len / 2f), top, -1.0f);
if (first)
{
min = max = currPos;
maxSquaredRadius = currPos.SquaredLength;
first = false;
}
else
{
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
}
top -= mCharHeight * 2.0f;
// Bottom left
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u1;
*pPCBuff++ = v2;
// Deal with bounds
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
currPos =new Vector3(left, top, -1.0f);
else
currPos =new Vector3(left - (len / 2f), top, -1.0f);
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
top += mCharHeight * 2.0f;
left += horiz_height * mCharHeight * 2.0f;
// Top right
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u2;
*pPCBuff++ = v1;
//-------------------------------------------------------------------------------------
// Deal with bounds
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
currPos = new Vector3(left, top, -1.0f);
else
currPos = new Vector3(left - (len / 2f), top, -1.0f);
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
//-------------------------------------------------------------------------------------
// Second tri
//
// Top right (again)
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2f);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u2;
*pPCBuff++ = v1;
currPos = new Vector3(left, top, -1.0f);
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
top -= mCharHeight * 2.0f;
left -= horiz_height * mCharHeight * 2.0f;
// Bottom left (again)
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2f);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u1;
*pPCBuff++ = v2;
currPos =new Vector3(left, top, -1.0f);
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
left += horiz_height * mCharHeight * 2.0f;
// Bottom right
if(mHorizontalAlignment == HorizontalAlignment.H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2f);
*pPCBuff++ = top;
*pPCBuff++ = -1.0f;
*pPCBuff++ = u2;
*pPCBuff++ = v2;
//-------------------------------------------------------------------------------------
currPos =new Vector3(left, top, -1.0f);
min.MakeFloor(currPos);
max.MakeCeil(currPos);
maxSquaredRadius = System.Math.Max(maxSquaredRadius, currPos.SquaredLength);
// Go back up with top
top += mCharHeight * 2.0f;
float currentWidth = (left + 1)/2 - 0;
if (currentWidth > largestWidth)
largestWidth = currentWidth;
}
// Unlock vertex buffer
ptbuf.Unlock();
// update AABB/Sphere radius
mAABB =new AxisAlignedBox(min, max);
mRadius = Mogre.Math.Sqrt(maxSquaredRadius);
if (mUpdateColors)
this._updateColors();
mNeedUpdate = false;
}
protected unsafe void _updateColors() {
System.Diagnostics.Debug.Assert(mpFont != null);
System.Diagnostics.Debug.Assert(mpMaterial != null);
// Convert to system-specific
uint color;
Root.Singleton.ConvertColourValue(mColor, out color);
HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData.vertexBufferBinding.GetBuffer(COLOUR_BINDING);
byte* pDest = (byte*)vbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD);
for (uint i = 0; i < mRenderOp.vertexData.vertexCount; ++i)
*pDest++ = (byte)color;
vbuf.Unlock();
}
// from MovableObject
protected void getWorldTransforms(Matrix4 xform) {
if (this.IsVisible() && mpCam != null) {
Matrix3 rot3x3 = Matrix3.IDENTITY, scale3x3 = Matrix3.IDENTITY;
// store rotation in a matrix
rot3x3=mpCam.DerivedOrientation.ToRotationMatrix();
// parent node position
Vector3 ppos = ParentNode._getDerivedPosition() + Vector3.UNIT_Y * mAdditionalHeight;
// apply scale
scale3x3[0,0] = ParentNode._getDerivedScale().x / 2;
scale3x3[1,1] = ParentNode._getDerivedScale().y / 2;
scale3x3[2,2] = ParentNode._getDerivedScale().z / 2;
// apply all transforms to xform
xform=new Matrix4(rot3x3 * scale3x3);
xform.SetTrans(ppos);
}
}
protected float getBoundingRadius() { return mRadius; }
protected float getSquaredViewDepth(Camera cam) { return 0; }
protected Quaternion getWorldOrientation() {
System.Diagnostics.Debug.Assert(mpCam != null);
return mpCam.DerivedOrientation;
}
protected Vector3 getWorldPosition() {
System.Diagnostics.Debug.Assert(ParentNode != null);
return this.ParentNode._getDerivedPosition();
}
protected AxisAlignedBox getBoundingBox() { return mAABB; }
protected string getName() { return mName; }
protected string getMovableType() { string movType = "MovableText"; return movType; }
protected new void _notifyCurrentCamera(Camera cam) {
mpCam = cam;
}
protected new void _updateRenderQueue(RenderQueue queue) {
if (this.IsVisible()) {
if (mNeedUpdate)
this._setupGeometry();
if (mUpdateColors)
this._updateColors();
// queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
queue.AddRenderable(this, (byte)RenderQueueGroupID.RENDER_QUEUE_OVERLAY, OGRE_RENDERABLE_DEFAULT_PRIORITY);
// queue->addRenderable(this, mRenderQueueID, RENDER_QUEUE_SKIES_LATE);
}
}
// from renderable
protected void getRenderOperation(RenderOperation op) {
if (this.IsVisible()) {
if (mNeedUpdate)
this._setupGeometry();
if (mUpdateColors)
this._updateColors();
op = mRenderOp;
}
}
protected MaterialPtr getMaterial() { return mpMaterial; }
protected LightList getLights() { return mLList; }
}