using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
namespace Sprite
{
public enum enuMirror { none, vertical, horizontal, VerticalAndHorizontal }
public struct udtSprite_StorageRetrieval
{
public string myName;
public udtLimb_StorageRetrieval[] limbs;
}
public struct udtLimb_StorageRetrieval
{
public string myName;
public Bitmap[] bmp;
public bool IRotate;
public bool AlwaysVertical;
public classMath.classRadialCoor radMaster;
public int MasterIndex;
public classMath.classRadialCoor radSlave;
public string hingeName;
}
/// <summary>
/// a hinge connects to limbs together
/// radial coordinates are relative to the center of each image
/// the slave's master coordinate is place at the same location as its master's slave coordinate onto the screen
/// </summary>
public class classSpriteHinge
{
string myName;
public bool bolFlag = true;
public string name
{
get { return myName; }
}
double myAngle;
/// <summary>
/// angle of slave limb relative to angle of master limb
/// </summary>
public double Angle
{
get { return myAngle; }
set
{
double dblTestAngle = value - (Math.PI / 16.0);
if (dblTestAngle < 0)
dblTestAngle += (Math.PI * 2.0);
int intDir = (int)(Math.Ceiling(dblTestAngle / (Math.PI / 8.0)));
myAngle = intDir * Math.PI / 8.0;
}
}
public classSpriteHinge(string name) { myName = name; }
/// <summary>
/// a hinge connects to limbs together
/// radial coordinates are relative to the center of each image
/// the slave's master coordinate is place at the same location as its master's slave coordinate onto the screen
/// </summary>
/// <param name="name">name of this hinge, e.g. "elbow"</param>
/// <param name="RadCoor_Master">radial coordinate (radians, pixels) of location of joint on master image relative to center</param>
/// <param name="RadCoor_Slave">radial coordinate (radians, pixels) of location of joint on slave image relative to center</param>
/// <param name="LimbMaster">pointer to Master-Limb</param>
/// <param name="LimbSlave">pointer to Slave-Limb</param>
public classSpriteHinge(string name, classMath.classRadialCoor RadCoor_Master, classMath.classRadialCoor RadCoor_Slave, classSpriteLimb LimbMaster, classSpriteLimb LimbSlave)
{
udrRadCoor_Master = RadCoor_Master;
udrRadCoor_Slave = RadCoor_Slave;
classLimb_Master = LimbMaster;
classLimb_Slave = LimbSlave;
myName = name;
}
classMath.classRadialCoor udrRadCoor_Master;
/// <summary>
/// radial coordinate location relative to center of image
/// </summary>
public classMath.classRadialCoor RadCoor_Master
{
get { return udrRadCoor_Master; }
set { udrRadCoor_Master = value; }
}
classMath.classRadialCoor udrRadCoor_Slave;
/// <summary>
/// radial coordinate location relative to center of image
/// </summary>
public classMath.classRadialCoor RadCoor_Slave
{
get { return udrRadCoor_Slave; }
set { udrRadCoor_Slave = value; }
}
classSpriteLimb classLimb_Master;
/// <summary>
/// pointer to limb connected to this hinge
/// </summary>
public classSpriteLimb Limb_Master
{
get { return classLimb_Master; }
set { classLimb_Master = value; }
}
classSpriteLimb classLimb_Slave;
/// <summary>
/// pointer to limb connected to this hinge
/// </summary>
public classSpriteLimb Limb_Slave
{
get { return classLimb_Slave; }
set { classLimb_Slave = value; }
}
}
/// <summary>
/// one element in array of 16 that describes a limb's position relative to its master
/// as well as the locations of any number of slaves relative to it
/// </summary>
public class classSpriteLimbImage
{
public classSpriteLimbImage() { }
public classSpriteLimbImage(Bitmap bmpOriginal) { bmp = bmpOriginal; }
/// <summary>
/// this sprite limb's image for this angle
/// </summary>
public Bitmap bmp;
}
public class classSpriteLimb
{
Sprite.classSprite mainSprite;
public bool bolFlag = true;
public Rectangle recDest;
public classSpriteLimbImage myCurrentImage;
public classSpriteLimb[] mySlaveLimbs;
int intMySlaveID;
/// <summary>
/// my index in my master's slave limb array
/// </summary>
public int MySlaveID
{
get { return intMySlaveID; }
set { intMySlaveID = value; }
}
bool bolAlwaysVertical = false;
/// <summary>
/// determines whether generated images are flipped to remain vertical or rotated 360 degrees
/// </summary>
public bool AlwaysVertical { get { return bolAlwaysVertical; } }
string myName;
public string Name { get { return myName; } }
Point ptLoc;
/// <summary>
/// location of top-left corner of image's rectangle
/// </summary>
public Point Loc
{
get { return ptLoc; }
set { ptLoc = value; }
}
int dir;
/// <summary>
/// 0-15 where 0 is east, 4 north, etc.
/// also corresponds to the udrSpriteLimbImages's index of currently displayed image
/// </summary>
public int Dir
{
get { return dir; }
set { dir = value; }
}
double angle;
/// <summary>
/// at which this limb currently has on the screen
/// </summary>
public double Angle
{
get { return -angle; }
set { angle = -value; }
}
/// <summary>
/// this limb's images
/// </summary>
public classSpriteLimbImage[] udrSpriteLimbImages;
bool bolIRotate = true;
/// <summary>
/// boolean variable which determines whether this limb rotates or animates
/// when true, SpriteLimbImages is expected to consist of 16 images at 16 angles
/// when false, SpriteLimbImages is either one or many images which are used to animate this limb
/// </summary>
public bool IRotate
{
get { return bolIRotate; }
set { bolIRotate = value; }
}
//bool bolIHaveNoMaster = false;
//public bool IHaveNoMaster { get { return bolIHaveNoMaster; } }
public classSpriteHinge MasterHinge;
/// <summary>
/// a limb consists of an array of images with their corresponding hinge locations
/// </summary>
/// <param name="IRotate">
/// when this is set the indices of udrSpriteLimbImage are direction of rotation, e.g. action-arm, these are created if not provided
/// when this is not set these are animation images, e.g. walking legs</param>
/// </param>
/// <param name="AlwaysVertical">
/// determines whether generated images are flipped to remain vertical or rotated 360 degrees
/// </param>
/// <param name="_myName">
/// used for ease of debugging e.g. "Torso", "left arm", "right hand"
/// </param>
/// <param name="bmpOriginal">
/// first elements of array of images
/// </param>
public classSpriteLimb(ref classSprite sprite, bool IRotate, bool AlwaysVertical, string _myName, params Bitmap[] bmpOriginal)
{
mainSprite = sprite;
myName = _myName;
bolIRotate = IRotate;
bolAlwaysVertical = AlwaysVertical;
initImages(bmpOriginal);
}
public void initImages(Bitmap[] bmpOriginal)
{
//myName = "arm(near fuck)";
if (bolIRotate)
{
udrSpriteLimbImages = new classSpriteLimbImage[16];
for (int intBmpCounter = 0; intBmpCounter < bmpOriginal.Length; intBmpCounter++)
udrSpriteLimbImages[intBmpCounter] = new classSpriteLimbImage(bmpOriginal[intBmpCounter]);
if (bmpOriginal.Length < 4)
{ // generate 1, 2 & 3 from 0
generateBaseFourImagesFromOriginal();
}
if (bmpOriginal.Length < 15)
{ // generate all from 0,1,2 & 3
for (int intImageCounter = 4; intImageCounter < 16; intImageCounter++)
{
udrSpriteLimbImages[intImageCounter] = getLimbImageFromArray_ByDir(ref udrSpriteLimbImages, intImageCounter);
}
}
}
else
{
udrSpriteLimbImages = new classSpriteLimbImage[bmpOriginal.Length];
for (int intBmpCounter = 0; intBmpCounter < bmpOriginal.Length; intBmpCounter++)
{
udrSpriteLimbImages[intBmpCounter] = new classSpriteLimbImage();
udrSpriteLimbImages[intBmpCounter].bmp = bmpOriginal[intBmpCounter];
}
}
}
#region "initialize images"
/// <summary>
/// generates three angled copies of the original(udrSpriteLimbImage[0]) and stores them in udrSpriteLimbImage[1,2,3]
/// </summary>
void generateBaseFourImagesFromOriginal()
{
classMath cLibMath = new classMath();
Color clrTransparent = udrSpriteLimbImages[0].bmp.GetPixel(0, 0);
double dblRotationAngle = 0;
for (int intImageCounter = 1; intImageCounter < 4; intImageCounter++)
{
dblRotationAngle = Math.PI + (Math.PI * (double)intImageCounter / 8.0);
udrSpriteLimbImages[intImageCounter] = new classSpriteLimbImage();
udrSpriteLimbImages[intImageCounter].bmp = rotate(udrSpriteLimbImages[0].bmp, dblRotationAngle, ref cLibMath);
}
}
Bitmap rotate(Bitmap bmpInput, double dblAngleRotation, ref classMath cLibMath)
{
int intMinSquare = bmpInput.Width > bmpInput.Height ?
3 * bmpInput.Width
: 3 * bmpInput.Height;
Color clrHole = Color.YellowGreen;// some color assumed NOT in the input bmp
Bitmap bmpCopy = new Bitmap(intMinSquare, intMinSquare);
Point ptTL;
Point ptBR;
Point ptCopyCenter = new Point(bmpCopy.Width / 2, bmpCopy.Height / 2);
Point ptOriginalCenter = new Point(bmpInput.Width / 2, bmpInput.Height / 2);
using (Graphics g = Graphics.FromImage(bmpCopy))
{
g.FillRectangle(new SolidBrush(clrHole), new Rectangle(new Point(0, 0), bmpCopy.Size));
ptTL = new Point(ptCopyCenter.X, ptCopyCenter.Y);
ptBR = new Point(ptCopyCenter.X, ptCopyCenter.Y);
for (int intX = 0; intX < bmpInput.Width; intX++)
{
for (int intY = 0; intY < bmpInput.Height; intY++)
{
int intDX = ptOriginalCenter.X - intX;
int intDY = ptOriginalCenter.Y - intY;
classMath.classRadialCoor udrOriginalRad = new classMath.classRadialCoor(classMath.arcTan(intDX, intDY), Math.Sqrt(intDX * intDX + intDY * intDY));
classMath.classRadialCoor udrCopyRad = new classMath.classRadialCoor(udrOriginalRad.angle - dblAngleRotation, udrOriginalRad.radius);
Point ptCopy = new Point((int)(ptCopyCenter.X + udrCopyRad.radius * Math.Cos(udrCopyRad.angle)),
(int)(ptCopyCenter.Y + udrCopyRad.radius * Math.Sin(udrCopyRad.angle)));
try { bmpCopy.SetPixel(ptCopy.X, ptCopy.Y, bmpInput.GetPixel(intX, intY)); }
catch (Exception) { }
// keep track of limits of output image
if (ptCopy.X < ptTL.X)
ptTL.X = ptCopy.X;
if (ptCopy.Y < ptTL.Y)
ptTL.Y = ptCopy.Y;
if (ptCopy.X > ptBR.X)
ptBR.X = ptCopy.X;
if (ptCopy.Y > ptBR.Y)
ptBR.Y = ptCopy.Y;
}
}
}
// write image to output array
Size szOfImage = new Size(ptBR.X - ptTL.X, ptBR.Y - ptTL.Y);
Rectangle recSrc = new Rectangle(ptTL, szOfImage);
Rectangle recDest = new Rectangle(new Point(0, 0), szOfImage);
// fill the blanks missed when rotating image
// scanning x from 0 to width created a problem in the fill-blank
for (int intX = ptTL.X; intX < ptBR.X; intX++)
for (int intY = ptTL.Y; intY < ptBR.Y; intY++)
{
Color clrTest = bmpCopy.GetPixel(intX, intY);
if (clrTest.A == clrHole.A
&& clrTest.R == clrHole.R
&& clrTest.G == clrHole.G
&& clrTest.B == clrHole.B)
{
udtPixilateColorFind[] udrColorFind = new udtPixilateColorFind[0];
if (intX > 0 && intX < bmpCopy.Width - 2 && intY > 0 && intY < bmpCopy.Height - 2)
{
Point ptUp = new Point(intX, intY - 1);
Point ptDown = new Point(intX, intY + 1);
Point ptLeft = new Point(intX - 1, intY);
Point ptRight = new Point(intX + 1, intY);
Point ptUL = new Point(intX - 1, intY - 1);
Point ptUR = new Point(intX + 1, intY - 1);
Point ptDR = new Point(intX + 1, intY + 1);
Point ptDL = new Point(intX - 1, intY + 1);
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUp.X, ptUp.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDown.X, ptDown.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptLeft.X, ptLeft.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptRight.X, ptRight.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDL.X, ptDL.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDR.X, ptDR.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUL.X, ptUL.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUR.X, ptUR.Y));
reorderPixilateColorFound(ref udrColorFind);
if (udrColorFind[0].numFound >= 2)
try { bmpCopy.SetPixel(intX, intY, udrColorFind[0].clr); }
catch (Exception) { }
else
{
int intDX = ptCopyCenter.X - intX;
int intDY = ptCopyCenter.Y - intY;
classMath.classRadialCoor udrOriginalRad = new classMath.classRadialCoor(classMath.arcTan(intDX, intDY), Math.Sqrt(intDX * intDX + intDY * intDY));
classMath.classRadialCoor udrCopyRad = new classMath.classRadialCoor(udrOriginalRad.angle + dblAngleRotation, udrOriginalRad.radius);
Point ptCopy = new Point((int)(ptOriginalCenter.X + udrCopyRad.radius * Math.Cos(udrCopyRad.angle)),
(int)(ptOriginalCenter.Y + udrCopyRad.radius * Math.Sin(udrCopyRad.angle)));
if (ptCopy.X >= 0 && ptCopy.X < bmpCopy.Width && ptCopy.Y >= 0 && ptCopy.Y < bmpCopy.Height)
try { bmpCopy.SetPixel(intX, intY, bmpInput.GetPixel(ptCopy.X, ptCopy.Y)); }
catch (Exception) { }
}
}
}
}
if (recDest.Width < 1)
recDest.Width = 1;
if (recDest.Height < 1)
recDest.Height = 1;
Bitmap bmpTemp = new Bitmap(recDest.Width, recDest.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bmpTemp.Width, bmpTemp.Height));
bmpCopy.MakeTransparent(bmpCopy.GetPixel(0, 0));
g.DrawImage(bmpCopy, recDest, recSrc, GraphicsUnit.Pixel);
}
return bmpTemp;
}
public struct udtPixilateColorFind
{
public Color clr;
public int numFound;
}
private void addPixilateColorFound(ref udtPixilateColorFind[] udrPixilateColorFind, Color clrFound)
{
if (udrPixilateColorFind == null)
{
udrPixilateColorFind = new udtPixilateColorFind[1];
udrPixilateColorFind[0] = new udtPixilateColorFind();
udrPixilateColorFind[0].clr = clrFound;
udrPixilateColorFind[0].numFound = 1;
}
else
{
for (int intClrCounter = 0; intClrCounter < udrPixilateColorFind.Length; intClrCounter++)
if (udrPixilateColorFind[intClrCounter].clr == clrFound)
{
udrPixilateColorFind[intClrCounter].numFound++;
return;
}
Array.Resize<udtPixilateColorFind>(ref udrPixilateColorFind, udrPixilateColorFind.Length + 1);
udrPixilateColorFind[udrPixilateColorFind.Length - 1] = new udtPixilateColorFind();
udrPixilateColorFind[udrPixilateColorFind.Length - 1].clr = clrFound;
udrPixilateColorFind[udrPixilateColorFind.Length - 1].numFound = 1;
}
}
void reorderPixilateColorFound(ref udtPixilateColorFind[] udrPixilateColorFind)
{
int intBestFind;
for (int intOuterLoop = 0; intOuterLoop < udrPixilateColorFind.Length - 1; intOuterLoop++)
{
intBestFind = intOuterLoop;
for (int intInnerLoop = intOuterLoop + 1; intInnerLoop < udrPixilateColorFind.Length; intInnerLoop++)
{
if (udrPixilateColorFind[intInnerLoop].numFound > udrPixilateColorFind[intBestFind].numFound)
intBestFind = intInnerLoop;
}
if (intBestFind != intOuterLoop)
{
udtPixilateColorFind udrTemp = udrPixilateColorFind[intOuterLoop];
udrPixilateColorFind[intOuterLoop] = udrPixilateColorFind[intBestFind];
udrPixilateColorFind[intBestFind] = udrTemp;
}
}
}
/// <summary>
/// returns image appropriate for this limb at current angle
/// selected from array of 16 images
/// </summary>
public classSpriteLimbImage getSpriteImageFromArray() { return getSpriteImageFromArray(ref udrSpriteLimbImages, angle); }
/// <summary>
/// returns image appropriate for this limb at input angle
/// selected from array of 16 images
/// </summary>
/// <param name="dblAngle">
/// angled image to be returned
/// </param>
/// <returns></returns>
public classSpriteLimbImage getSpriteImageFromArray(double dblAngle) { return getSpriteImageFromArray(ref udrSpriteLimbImages, dblAngle); }
/// <summary>
/// returns image appropriate for this limb at input angle
/// selected from array of 16 images
/// </summary>
/// <param name="udrSpriteImage">array of 4 images pointing in 16 angles where east is 0th, North-east is 2nd, North 4th, etc.</param>
/// <param name="dblAngle">angle in radians where 0 is east Pi/2 is north, Pi is west, and 3Pi/2 is south</param>
/// <returns></returns>
public classSpriteLimbImage getSpriteImageFromArray(ref classSpriteLimbImage[] udrSpriteImage, double dblAngle)
{
angle = dblAngle;
while (angle < 0)
angle += (2.0 * Math.PI);
while (angle > 2.0 * Math.PI)
angle -= (2.0 * Math.PI);
setDir();
return getLimbImageFromArray_ByDir(ref udrSpriteImage, dir);
}
public void setDir() { setDir(angle); }
public void setDir(double dblAngle)
{
double dblTestAngle = dblAngle - (Math.PI / 16.0);
if (dblTestAngle < 0)
dblTestAngle += (Math.PI * 2.0);
int intPicIndex = (int)(Math.Ceiling(dblTestAngle / (Math.PI / 8.0)));
if (intPicIndex == 16)
intPicIndex = 0;
dir = intPicIndex;
angle = dir * (Math.PI / 8);
}
/// <summary>
/// returns image appropriate for this limb at input direction
/// selected from array of 16 images
/// </summary>
/// <param name="udrSpriteImage">array of 4 images pointing in 16 angles where east is 0th, North-east is 2nd, North 4th, etc.</param>
/// <param name="intDir">indicates the desired direction of image where 0th is east, 4th is north, 8 is west and 12th south, etc.</param>
/// <returns></returns>
public classSpriteLimbImage getLimbImageFromArray_ByDir(ref classSpriteLimbImage[] udrSpriteImage, int intDir)
{
if (udrSpriteImage == null)
return null;
if (intDir < 0 || intDir > 15)
{
MessageBox.Show("error getLimbImageFromArray_ByDir");
return udrSpriteImage[0];
}
else
{
if (udrSpriteImage.Length > 1)
{
if (intDir < udrSpriteImage.Length && false)
{
return udrSpriteImage[intDir];
}
else
switch (intDir)
{
case 0:
case 1:
case 2:
case 3:
return udrSpriteImage[intDir];
default:
if (udrSpriteLimbImages[intDir] != null)
return udrSpriteLimbImages[intDir];
else
{
if (bolAlwaysVertical)
{
classSpriteLimbImage udrRetVal = new classSpriteLimbImage();
switch (intDir)
{
case 4:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
return udrRetVal;
case 5:
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
return udrRetVal;
case 6:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
return udrRetVal;
case 7:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
return udrRetVal;
case 8:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
return udrRetVal;
case 9:
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
return udrRetVal;
case 10:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
return udrRetVal;
case 11:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipY);
return udrRetVal;
case 12:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
case 13:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
case 14:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
default: // case 15
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
}
}
else
{
classSpriteLimbImage udrRetVal = new classSpriteLimbImage();
switch (intDir)
{
case 4:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
return udrRetVal;
case 5:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
return udrRetVal;
case 6:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
return udrRetVal;
case 7:
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
return udrRetVal;
case 8:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate180FlipNone);
//udrRetVal.bmp.Save("c:\\temp\\temp.bmp");
return udrRetVal;
case 9:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate180FlipNone);
return udrRetVal;
case 10:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate180FlipNone);
return udrRetVal;
case 11:
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate180FlipNone);
return udrRetVal;
case 12:
udrRetVal.bmp = new Bitmap(udrSpriteImage[0].bmp.Width, udrSpriteImage[0].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[0].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
case 13:
udrRetVal.bmp = new Bitmap(udrSpriteImage[1].bmp.Width, udrSpriteImage[1].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[1].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
case 14:
udrRetVal.bmp = new Bitmap(udrSpriteImage[2].bmp.Width, udrSpriteImage[2].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[2].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
default: // case 15
udrRetVal.bmp = new Bitmap(udrSpriteImage[3].bmp.Width, udrSpriteImage[3].bmp.Height);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
g.DrawImage(udrSpriteImage[3].bmp, new Point(0, 0));
udrRetVal.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return udrRetVal;
}
}
}
}
}
else
{
return udrSpriteImage[0];
}
}
}
#endregion
public void addLimb(classSpriteLimb newLimb, string hingeName, classMath.classRadialCoor radMasterJoint, classMath.classRadialCoor radSlaveJoint)
{
if (mySlaveLimbs == null)
mySlaveLimbs = new classSpriteLimb[0];
Array.Resize<classSpriteLimb>(ref mySlaveLimbs, mySlaveLimbs.Length + 1);
mySlaveLimbs[mySlaveLimbs.Length - 1] = newLimb;
mySlaveLimbs[mySlaveLimbs.Length - 1].MasterHinge = new classSpriteHinge(hingeName, radMasterJoint, radSlaveJoint, this, newLimb);
Array.Resize<Sprite.classSpriteHinge>(ref mainSprite.hinges, mainSprite.hinges.Length + 1);
mainSprite.hinges[mainSprite.hinges.Length - 1] = mySlaveLimbs[mySlaveLimbs.Length - 1].MasterHinge;
newLimb.intMySlaveID = mainSprite.hinges.Length - 1;
}
public void subLimb(ref classSpriteLimb thisLimb)
{
if (thisLimb.myName.CompareTo(mySlaveLimbs[thisLimb.MySlaveID].myName) != 0)
MessageBox.Show("we have a problem!");
disposeAllHinges(ref thisLimb);
mySlaveLimbs[thisLimb.MySlaveID] = mySlaveLimbs[mySlaveLimbs.Length - 1];
Array.Resize<Sprite.classSpriteLimb>(ref mySlaveLimbs, mySlaveLimbs.Length - 1);
}
void disposeAllHinges(ref Sprite.classSpriteLimb thisLimb)
{
for (int intSlaveCounter = 0; intSlaveCounter < mySlaveLimbs.Length; intSlaveCounter++)
disposeAllHinges(ref mySlaveLimbs[intSlaveCounter]);
for (int intHingeCounter = 0; intHingeCounter < mainSprite.hinges.Length; intHingeCounter++)
if (mainSprite.hinges[intHingeCounter].name.CompareTo(thisLimb.MasterHinge.name) == 0)
{
mainSprite.hinges[intHingeCounter] = mainSprite.hinges[mainSprite.hinges.Length - 1];
Array.Resize<Sprite.classSpriteHinge>(ref mainSprite.hinges, mainSprite.hinges.Length - 1);
}
}
}
public class classSpriteMaker
{
udtSprite_StorageRetrieval udrStorageSprite;
const int conMaxNameStringSize = 50;
const string conStrNull = "---NULL---";
public classSprite getSprite(bool masterLimbRotates, bool AlwaysVertical, string _myName, string MasterLimb_Name, params Bitmap[] bmpOriginal)
{
classSprite spriteRetVal = new classSprite();
spriteRetVal.myName = _myName;
spriteRetVal.MasterLimb = new classSpriteLimb(ref spriteRetVal, masterLimbRotates, AlwaysVertical, MasterLimb_Name, bmpOriginal);
return spriteRetVal;
}
#region "Storage and Retrieval"
public classSprite loadSprite(string strFilename)
{
udtSprite_StorageRetrieval udrThisSprite = new udtSprite_StorageRetrieval();
int intcutchr = strFilename.IndexOf(".");
if (intcutchr > 0)
strFilename = strFilename.Substring(0, intcutchr);
strFilename += ".sp2";
if (System.IO.File.Exists(strFilename))
return loadSprite_V2(strFilename);
else
{
classSprite sprRetVal = loadSprite_V1(strFilename);
saveSprite(ref sprRetVal, strFilename);
return sprRetVal;
}
}
public classSprite loadSprite_V2(string strFilename)
{
udtSprite_StorageRetrieval udrThisSprite = new udtSprite_StorageRetrieval();
int intcutchr = strFilename.LastIndexOf(".");
if (intcutchr > 0)
strFilename = strFilename.Substring(0, intcutchr);
strFilename += ".sp2";
FileStream fs = new FileStream(strFilename, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
udrThisSprite.myName = (string)formatter.Deserialize(fs);
int intNumLimbs = (int)formatter.Deserialize(fs);
udrThisSprite.limbs = new udtLimb_StorageRetrieval[intNumLimbs];
for (int intLimbCounter = 0; intLimbCounter < intNumLimbs; intLimbCounter++)
{
udrThisSprite.limbs[intLimbCounter].myName = (string)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].IRotate = (bool)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].AlwaysVertical = (bool)formatter.Deserialize(fs);
int intNumBaseImages = (int)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].bmp = new Bitmap[intNumBaseImages];
for (int intBaseImageCounter = 0; intBaseImageCounter < intNumBaseImages; intBaseImageCounter++)
udrThisSprite.limbs[intLimbCounter].bmp[intBaseImageCounter] = (Bitmap)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radMaster = new classMath.classRadialCoor();
udrThisSprite.limbs[intLimbCounter].radMaster.angle = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radMaster.radius = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radSlave = new classMath.classRadialCoor();
udrThisSprite.limbs[intLimbCounter].radSlave.angle = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radSlave.radius = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].MasterIndex = (int)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].hingeName = (string)formatter.Deserialize(fs);
}
classSprite retval = getSprite(udrThisSprite.limbs[0].IRotate, udrThisSprite.limbs[0].AlwaysVertical, udrThisSprite.myName, udrThisSprite.limbs[0].myName, udrThisSprite.limbs[0].bmp);
for (int intLimbCounter = 1; intLimbCounter < udrThisSprite.limbs.Length; intLimbCounter++)
{
Sprite.classSpriteLimb masterLimb = retval.getLimbByName(udrThisSprite.limbs[udrThisSprite.limbs[intLimbCounter].MasterIndex].myName);
if (masterLimb == null)
masterLimb = retval.MasterLimb;
Sprite.classSpriteLimb newLimb = new Sprite.classSpriteLimb(ref retval,
udrThisSprite.limbs[intLimbCounter].IRotate,
udrThisSprite.limbs[intLimbCounter].AlwaysVertical,
udrThisSprite.limbs[intLimbCounter].myName.Trim(),
udrThisSprite.limbs[intLimbCounter].bmp);
masterLimb.addLimb(newLimb,
udrThisSprite.limbs[intLimbCounter].hingeName.Trim(),
new classMath.classRadialCoor(udrThisSprite.limbs[intLimbCounter].radMaster.angle, udrThisSprite.limbs[intLimbCounter].radMaster.radius),
new classMath.classRadialCoor(udrThisSprite.limbs[intLimbCounter].radSlave.angle, udrThisSprite.limbs[intLimbCounter].radSlave.radius));
}
// load limb draw sequence here
//
int intNumDrawPointers = (int)formatter.Deserialize(fs);
retval.limbDrawSequence = new classSpriteLimb[intNumDrawPointers];
for (int intDrawCounter = 0; intDrawCounter < intNumDrawPointers; intDrawCounter++)
{
string strNameLimb = ((string)formatter.Deserialize(fs)).Trim();
retval.limbDrawSequence[intDrawCounter] = retval.getLimbByName(strNameLimb);
if (retval.limbDrawSequence[intDrawCounter] == null)
retval.limbDrawSequence[intDrawCounter] = retval.MasterLimb;
}
// load configurations
int intNumConfigurations = (int)formatter.Deserialize(fs);
Array.Resize<classConfiguration>(ref retval.Configurations, intNumConfigurations);
for (int intConfigurationCounter = 0; intConfigurationCounter < retval.Configurations.Length; intConfigurationCounter++)
{
classConfiguration thisCon = new classConfiguration();
thisCon.name = ((string)formatter.Deserialize(fs)).Trim();
int intNumberLimbs = (int)formatter.Deserialize(fs);
Array.Resize<classSpriteLimb>(ref thisCon.LimbDrawSequence, intNumberLimbs);
for (int intLimbCounter = 0; intLimbCounter < thisCon.LimbDrawSequence.Length; intLimbCounter++)
{
string strConLimbName = ((string)formatter.Deserialize(fs)).Trim();
thisCon.LimbDrawSequence[intLimbCounter] = retval.getLimbByName(strConLimbName);
if (thisCon.LimbDrawSequence[intLimbCounter] == null)
if (retval.MasterLimb.Name.ToUpper().Trim().CompareTo(strConLimbName.Trim().ToUpper()) == 0)
thisCon.LimbDrawSequence[intLimbCounter] = retval.MasterLimb;
}
int intNumSteps = (int)formatter.Deserialize(fs);
Array.Resize<udtConfigurationStep>(ref thisCon.steps, intNumSteps);
for (int intStepCounter = 0; intStepCounter < thisCon.steps.Length; intStepCounter++)
{
Array.Resize<udtConfigurationStepHinge>(ref thisCon.steps[intStepCounter].hingeDetails, intNumberLimbs);
for (int intHingeCounter = 0; intHingeCounter < thisCon.steps[intStepCounter].hingeDetails.Length; intHingeCounter++)
{
string strConStepHingeName = ((string)formatter.Deserialize(fs)).Trim();
thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge = retval.getHingeByName(strConStepHingeName);
thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].angle = (double)formatter.Deserialize(fs);
thisCon.steps[intStepCounter].BmpCacheByMirrorType = new udtConfigurationStepBmpMirrortype[4];
for (int intMirrorType = 0; intMirrorType < 4; intMirrorType++)
thisCon.steps[intStepCounter].BmpCacheByMirrorType[intMirrorType].dir = new udtBmpAndPtTLInfo[16];
}
}
retval.Configurations[intConfigurationCounter] = thisCon;
}
fs.Close();
return retval;
}
public classSprite loadSprite_V1(string strFilename)
{
udtSprite_StorageRetrieval udrThisSprite = new udtSprite_StorageRetrieval();
int intcutchr = strFilename.IndexOf(".");
if (intcutchr > 0)
strFilename = strFilename.Substring(0, intcutchr);
strFilename += ".spr";
FileStream fs = new FileStream(strFilename, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
udrThisSprite.myName = (string)formatter.Deserialize(fs);
int intNumLimbs = (int)formatter.Deserialize(fs);
udrThisSprite.limbs = new udtLimb_StorageRetrieval[intNumLimbs];
for (int intLimbCounter = 0; intLimbCounter < intNumLimbs; intLimbCounter++)
{
udrThisSprite.limbs[intLimbCounter].myName = (string)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].IRotate = (bool)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].AlwaysVertical = (bool)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].bmp = new Bitmap[1];
udrThisSprite.limbs[intLimbCounter].bmp[0] = (Bitmap)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radMaster = new classMath.classRadialCoor();
udrThisSprite.limbs[intLimbCounter].radMaster.angle = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radMaster.radius = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radSlave = new classMath.classRadialCoor();
udrThisSprite.limbs[intLimbCounter].radSlave.angle = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].radSlave.radius = (double)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].MasterIndex = (int)formatter.Deserialize(fs);
udrThisSprite.limbs[intLimbCounter].hingeName = (string)formatter.Deserialize(fs);
}
classSprite retval = getSprite(udrThisSprite.limbs[0].IRotate, udrThisSprite.limbs[0].AlwaysVertical, udrThisSprite.myName, udrThisSprite.limbs[0].myName, udrThisSprite.limbs[0].bmp);
for (int intLimbCounter = 1; intLimbCounter < udrThisSprite.limbs.Length; intLimbCounter++)
{
Sprite.classSpriteLimb masterLimb = retval.getLimbByName(udrThisSprite.limbs[udrThisSprite.limbs[intLimbCounter].MasterIndex].myName);
if (masterLimb == null)
masterLimb = retval.MasterLimb;
Sprite.classSpriteLimb newLimb = new Sprite.classSpriteLimb(ref retval,
udrThisSprite.limbs[intLimbCounter].IRotate,
udrThisSprite.limbs[intLimbCounter].AlwaysVertical,
udrThisSprite.limbs[intLimbCounter].myName.Trim(),
udrThisSprite.limbs[intLimbCounter].bmp);
masterLimb.addLimb(newLimb,
udrThisSprite.limbs[intLimbCounter].hingeName.Trim(),
new classMath.classRadialCoor(udrThisSprite.limbs[intLimbCounter].radMaster.angle, udrThisSprite.limbs[intLimbCounter].radMaster.radius),
new classMath.classRadialCoor(udrThisSprite.limbs[intLimbCounter].radSlave.angle, udrThisSprite.limbs[intLimbCounter].radSlave.radius));
}
// load limb draw sequence here
//
int intNumDrawPointers = (int)formatter.Deserialize(fs);
retval.limbDrawSequence = new classSpriteLimb[intNumDrawPointers];
for (int intDrawCounter = 0; intDrawCounter < intNumDrawPointers; intDrawCounter++)
{
string strNameLimb = ((string)formatter.Deserialize(fs)).Trim();
retval.limbDrawSequence[intDrawCounter] = retval.getLimbByName(strNameLimb);
if (retval.limbDrawSequence[intDrawCounter] == null)
retval.limbDrawSequence[intDrawCounter] = retval.MasterLimb;
}
// load configurations
int intNumConfigurations = (int)formatter.Deserialize(fs);
Array.Resize<classConfiguration>(ref retval.Configurations, intNumConfigurations);
for (int intConfigurationCounter = 0; intConfigurationCounter < retval.Configurations.Length; intConfigurationCounter++)
{
classConfiguration thisCon = new classConfiguration();
thisCon.name = ((string)formatter.Deserialize(fs)).Trim();
int intNumberLimbs = (int)formatter.Deserialize(fs);
Array.Resize<classSpriteLimb>(ref thisCon.LimbDrawSequence, intNumberLimbs);
for (int intLimbCounter = 0; intLimbCounter < thisCon.LimbDrawSequence.Length; intLimbCounter++)
{
string strConLimbName = ((string)formatter.Deserialize(fs)).Trim();
thisCon.LimbDrawSequence[intLimbCounter] = retval.getLimbByName(strConLimbName);
if (thisCon.LimbDrawSequence[intLimbCounter] == null)
if (retval.MasterLimb.Name.ToUpper().Trim().CompareTo(strConLimbName.Trim().ToUpper()) == 0)
thisCon.LimbDrawSequence[intLimbCounter] = retval.MasterLimb;
}
int intNumSteps = (int)formatter.Deserialize(fs);
Array.Resize<udtConfigurationStep>(ref thisCon.steps, intNumSteps);
for (int intStepCounter = 0; intStepCounter < thisCon.steps.Length; intStepCounter++)
{
Array.Resize<udtConfigurationStepHinge>(ref thisCon.steps[intStepCounter].hingeDetails, intNumberLimbs);
for (int intHingeCounter = 0; intHingeCounter < thisCon.steps[intStepCounter].hingeDetails.Length; intHingeCounter++)
{
string strConStepHingeName = ((string)formatter.Deserialize(fs)).Trim();
thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge = retval.getHingeByName(strConStepHingeName);
thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].angle = (double)formatter.Deserialize(fs);
thisCon.steps[intStepCounter].BmpCacheByMirrorType = new udtConfigurationStepBmpMirrortype[4];
for (int intMirrorType = 0; intMirrorType < 4; intMirrorType++)
thisCon.steps[intStepCounter].BmpCacheByMirrorType[intMirrorType].dir = new udtBmpAndPtTLInfo[16];
}
}
retval.Configurations[intConfigurationCounter] = thisCon;
}
fs.Close();
return retval;
}
/// <summary>
/// turns any string into a string of exact size (conMaxNameStringSize) for storage
/// </summary>
/// <param name="strName">input string of any length</param>
/// <returns>output copy of input parameter set to specific storage string length</returns>
string getNameFromString(string strName) { return (strName.Trim().PadRight(conMaxNameStringSize)).Substring(0, conMaxNameStringSize); }
public void saveSprite(ref Sprite.classSprite thisSprite, string strFilename)
{
udrStorageSprite = new udtSprite_StorageRetrieval();
udrStorageSprite.myName = getNameFromString(thisSprite.myName);
udrStorageSprite.limbs = new udtLimb_StorageRetrieval[0];
createStorageSpriteLimbs(ref thisSprite.MasterLimb);
strFilename = strFilename.ToUpper().Replace(".SPR", ".SP2");
FileStream fs = new FileStream(strFilename, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, udrStorageSprite.myName);
formatter.Serialize(fs, udrStorageSprite.limbs.Length);
for (int intLimbCounter = 0; intLimbCounter < udrStorageSprite.limbs.Length; intLimbCounter++)
{
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].myName);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].IRotate);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].AlwaysVertical);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].bmp.Length);
for (int intImageCounter = 0; intImageCounter < udrStorageSprite.limbs[intLimbCounter].bmp.Length; intImageCounter++)
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].bmp[intImageCounter]);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radMaster.angle);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radMaster.radius);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radSlave.angle);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radSlave.radius);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].MasterIndex);
formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].hingeName);
}
// save limb drawsequence
formatter.Serialize(fs, thisSprite.limbDrawSequence.Length);
for (int intLimbCounter = 0; intLimbCounter < thisSprite.limbDrawSequence.Length; intLimbCounter++)
{
if (thisSprite.limbDrawSequence[intLimbCounter] == null)
formatter.Serialize(fs, getNameFromString("---NULL---"));
else
formatter.Serialize(fs, getNameFromString(thisSprite.limbDrawSequence[intLimbCounter].Name));
}
// save configuration info
if (thisSprite.Configurations == null)
formatter.Serialize(fs, 0);
else
{
formatter.Serialize(fs, thisSprite.Configurations.Length);
for (int intConfigurationCounter = 0; intConfigurationCounter < thisSprite.Configurations.Length; intConfigurationCounter++)
{
classConfiguration thisCon = thisSprite.Configurations[intConfigurationCounter];
formatter.Serialize(fs, getNameFromString(thisCon.name));
formatter.Serialize(fs, thisCon.LimbDrawSequence.Length);
for (int intHingeCounter = 0; intHingeCounter < thisCon.LimbDrawSequence.Length; intHingeCounter++)
formatter.Serialize(fs, getNameFromString(thisCon.LimbDrawSequence[intHingeCounter].Name));
formatter.Serialize(fs, thisCon.steps.Length);
for (int intStepCounter = 0; intStepCounter < thisCon.steps.Length; intStepCounter++)
{
for (int intHingeCounter = 0; intHingeCounter < thisCon.steps[intStepCounter].hingeDetails.Length; intHingeCounter++)
{
if (thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge == null)
{
formatter.Serialize(fs, (getNameFromString(conStrNull)));
formatter.Serialize(fs, (double)0.0);
}
else
{
formatter.Serialize(fs, getNameFromString(thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge.name));
formatter.Serialize(fs, thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].angle);
}
}
}
thisSprite.Configurations[intConfigurationCounter] = thisCon;
}
}
fs.Close();
}
//public void saveSprite_V1(ref Sprite.classSprite thisSprite, string strFilename)
//{
// udrStorageSprite = new udtSprite_StorageRetrieval();
// udrStorageSprite.myName = getNameFromString(thisSprite.myName);
// udrStorageSprite.limbs = new udtLimb_StorageRetrieval[0];
// createStorageSpriteLimbs(ref thisSprite.MasterLimb);
// FileStream fs = new FileStream(strFilename, FileMode.Create);
// BinaryFormatter formatter = new BinaryFormatter();
// formatter.Serialize(fs, udrStorageSprite.myName);
// formatter.Serialize(fs, udrStorageSprite.limbs.Length);
// for (int intLimbCounter = 0; intLimbCounter < udrStorageSprite.limbs.Length; intLimbCounter++)
// {
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].myName);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].IRotate);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].AlwaysVertical);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].bmp);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radMaster.angle);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radMaster.radius);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radSlave.angle);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].radSlave.radius);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].MasterIndex);
// formatter.Serialize(fs, udrStorageSprite.limbs[intLimbCounter].hingeName);
// }
// // save limb drawsequence
// formatter.Serialize(fs, thisSprite.limbDrawSequence.Length);
// for (int intLimbCounter = 0; intLimbCounter < thisSprite.limbDrawSequence.Length; intLimbCounter++)
// {
// if (thisSprite.limbDrawSequence[intLimbCounter] == null)
// formatter.Serialize(fs, getNameFromString("---NULL---"));
// else
// formatter.Serialize(fs, getNameFromString(thisSprite.limbDrawSequence[intLimbCounter].Name));
// }
// // save configuration info
// if (thisSprite.Configurations == null)
// formatter.Serialize(fs, 0);
// else
// {
// formatter.Serialize(fs, thisSprite.Configurations.Length);
// for (int intConfigurationCounter = 0; intConfigurationCounter < thisSprite.Configurations.Length; intConfigurationCounter++)
// {
// classConfiguration thisCon = thisSprite.Configurations[intConfigurationCounter];
// formatter.Serialize(fs, getNameFromString(thisCon.name));
// formatter.Serialize(fs, thisCon.LimbDrawSequence.Length);
// for (int intHingeCounter = 0; intHingeCounter < thisCon.LimbDrawSequence.Length; intHingeCounter++)
// formatter.Serialize(fs, getNameFromString(thisCon.LimbDrawSequence[intHingeCounter].Name));
// formatter.Serialize(fs, thisCon.steps.Length);
// for (int intStepCounter = 0; intStepCounter < thisCon.steps.Length; intStepCounter++)
// {
// for (int intHingeCounter = 0; intHingeCounter < thisCon.steps[intStepCounter].hingeDetails.Length; intHingeCounter++)
// {
// if (thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge == null)
// {
// formatter.Serialize(fs, (getNameFromString(conStrNull)));
// formatter.Serialize(fs, (double)0.0);
// }
// else
// {
// formatter.Serialize(fs, getNameFromString(thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].hinge.name));
// formatter.Serialize(fs, thisCon.steps[intStepCounter].hingeDetails[intHingeCounter].angle);
// }
// }
// }
// thisSprite.Configurations[intConfigurationCounter] = thisCon;
// }
// }
// fs.Close();
//}
void createStorageSpriteLimbs(ref Sprite.classSpriteLimb thisLimb)
{
Array.Resize<udtLimb_StorageRetrieval>(ref udrStorageSprite.limbs, udrStorageSprite.limbs.Length + 1);
udtLimb_StorageRetrieval udrTemp = new udtLimb_StorageRetrieval();
udrTemp.myName = getNameFromString(thisLimb.Name);
udrTemp.AlwaysVertical = thisLimb.AlwaysVertical;
udrTemp.IRotate = thisLimb.IRotate;
udrTemp.bmp = new Bitmap[thisLimb.udrSpriteLimbImages.Length];
for (int intBaseImageCounter = 0; intBaseImageCounter < thisLimb.udrSpriteLimbImages.Length; intBaseImageCounter++)
udrTemp.bmp[intBaseImageCounter] = thisLimb.udrSpriteLimbImages[intBaseImageCounter].bmp;
udrTemp.radMaster = new classMath.classRadialCoor();
udrTemp.radSlave = new classMath.classRadialCoor();
try
{
udrTemp.radMaster.angle = thisLimb.MasterHinge.RadCoor_Master.angle;
udrTemp.radMaster.radius = thisLimb.MasterHinge.RadCoor_Master.radius;
}
catch (Exception)
{
udrTemp.radMaster.angle = 0;
udrTemp.radMaster.radius = 0;
}
try
{
udrTemp.radSlave.angle = thisLimb.MasterHinge.RadCoor_Slave.angle;
udrTemp.radSlave.radius = thisLimb.MasterHinge.RadCoor_Slave.radius;
}
catch (Exception)
{
udrTemp.radSlave.angle = 0;
udrTemp.radSlave.radius = 0;
}
try
{ udrTemp.MasterIndex = getLimbIndex(thisLimb.MasterHinge.Limb_Master.Name); }
catch (Exception)
{ udrTemp.MasterIndex = 0; }
try
{ udrTemp.hingeName = getNameFromString(thisLimb.MasterHinge.name); }
catch (Exception)
{ udrTemp.hingeName = ""; }
udrStorageSprite.limbs[udrStorageSprite.limbs.Length - 1] = udrTemp;
if (thisLimb.mySlaveLimbs != null)
for (int intSlaveCounter = 0; intSlaveCounter < thisLimb.mySlaveLimbs.Length; intSlaveCounter++)
createStorageSpriteLimbs(ref thisLimb.mySlaveLimbs[intSlaveCounter]);
}
int getLimbIndex(string strName)
{
for (int intLimbCounter = 0; intLimbCounter < udrStorageSprite.limbs.Length; intLimbCounter++)
if (udrStorageSprite.limbs[intLimbCounter].myName.Trim().CompareTo(strName) == 0)
return intLimbCounter;
return -1;
}
#endregion
}
public struct udtBmpAndPtTLInfo
{
public Bitmap bmp;
public Point ptTL;
public udtConfigStepLimbPosition[] limbPositions;
}
public struct udtConfigStepLimbPosition
{
public classSpriteLimb limb;
public Point pt;
public double dblAngle;
}
public struct udtConfigurationStepBmpMirrortype
{
public udtBmpAndPtTLInfo[] dir;
}
public struct udtConfigurationStep
{
public udtConfigurationStepHinge[] hingeDetails;
public udtConfigurationStepBmpMirrortype[] BmpCacheByMirrorType;
}
public struct udtConfigurationStepHinge
{
public classSpriteHinge hinge;
public double angle;
}
public class classConfiguration
{
public string name;
public classSpriteLimb[] LimbDrawSequence;
public udtConfigurationStep[] steps;
/// <summary>
/// returns the position of the limb identified by a string with reference to the master limb centered at the sprite's 'loc' for this specific configuration
/// </summary>
/// <param name="strLimbName">name of limb whose position is to be determined</param>
/// <param name="mirror">type of mirror image : vertical, horizontal or both</param>
/// <param name="intStep">configuration's step index</param>
/// <param name="intDir">direction(0-15 where east is 0) of the master block</param>
/// <returns>returns the location of limb relative to master limb</returns>
public Point getLimbPos(string strLimbName, enuMirror mirror, int intStep, int intDir)
{
strLimbName = strLimbName.ToUpper().Trim();
for (int intLimbCounter = 0; intLimbCounter < LimbDrawSequence.Length; intLimbCounter++)
{
if (strLimbName.CompareTo(LimbDrawSequence[intLimbCounter].Name.Trim().ToUpper()) == 0)
{
return getLimbPos(intLimbCounter, mirror, intStep, intDir);
}
}
return new Point(0, 0);
}
/// <summary>
/// returns the position of the limb identified by a string with reference to the master limb centered at the sprite's 'loc' for this specific configuration
/// assumes mirror = none, and intDir = 0(east)
/// </summary>
/// <param name="intLimbDrawSequenceIndex">index in drawsequence of limb whose position is to be determined</param>
/// <param name="intStep">configuration's step index</param>
/// <returns>returns the location of limb relative to master limb</returns>
public Point getLimbPos(int intLimbDrawSequenceIndex, int intStep)
{ return getLimbPos(intLimbDrawSequenceIndex, enuMirror.none, intStep, 0); }
/// <summary>
/// returns the position of the limb identified by a string with reference to the master limb centered at the sprite's 'loc' for this specific configuration
/// assumes intDir =0(east)
/// </summary>
/// <param name="intLimbDrawSequenceIndex">index in drawsequence of limb whose position is to be determined</param>
/// <param name="mirror">type of mirror image : vertical, horizontal or both</param>
/// <param name="intStep">configuration's step index</param>
/// <returns>returns the location of limb relative to master limb</returns>
public Point getLimbPos(int intLimbDrawSequenceIndex, enuMirror mirror, int intStep)
{ return getLimbPos(intLimbDrawSequenceIndex, mirror, 0, intStep); }
/// <summary>
/// returns the position of the limb identified by a string with reference to the master limb centered at the sprite's 'loc' for this specific configuration
/// assumes mirror = none
/// </summary>
/// <param name="intLimbDrawSequenceIndex">index in drawsequence of limb whose position is to be determined</param>
/// <param name="intStep">configuration's step index</param>
/// <param name="intDir">direction(0-15 where east is 0) of the master block</param>
/// <returns>returns the location of limb relative to master limb</returns>
public Point getLimbPos(int intLimbDrawSequenceIndex, int intStep, int intDir)
{ return getLimbPos(intLimbDrawSequenceIndex, enuMirror.none, intStep, intDir); }
/// <summary>
/// returns the position of the limb identified by a string with reference to the master limb centered at the sprite's 'loc' for this specific configuration
/// </summary>
/// <param name="intLimbDrawSequenceIndex">index in drawsequence of limb whose position is to be determined</param>
/// <param name="mirror">type of mirror image : vertical, horizontal or both</param>
/// <param name="intStep">configuration's step index</param>
/// <param name="intDir">direction(0-15 where east is 0) of the master block</param>
/// <returns>returns the location of limb relative to master limb</returns>
public Point getLimbPos(int intLimbDrawSequenceIndex, enuMirror mirror, int intStep, int intDir)
{ return steps[intStep].BmpCacheByMirrorType[(int)mirror].dir[intDir].limbPositions[intLimbDrawSequenceIndex].pt; }
/// <summary>
/// returns the index of a limb in this configuration's DrawSequence identified by its name string
/// </summary>
/// <param name="strLimbName">name of limb to find</param>
/// <returns>integer index of limb in drawSequence array, -1 if not found</returns>
public int getLimbDrawSequenceIndex(string strLimbName)
{
strLimbName = strLimbName.ToUpper().Trim();
for (int intLimbCounter = 0; intLimbCounter < LimbDrawSequence.Length; intLimbCounter++)
if (strLimbName.CompareTo(LimbDrawSequence[intLimbCounter].Name.Trim().ToUpper()) == 0)
return intLimbCounter;
return -1;
}
}
public class classSprite
{
public classSpriteLimb MasterLimb;
public classConfiguration[] Configurations;
public classConfiguration conCurrent;
public int intConfigurationStep_Current;
/// <summary>
/// array of pointers to the sprite's limbs equal in size to the size of the actual limbs & hinges arrays
/// the order in which the limbs are drawn is controlled by the order in which their pointers appear in this array.
/// only the limbs listed in this array will be drawn by the 'putSpriteToScreen()' function
/// </summary>
public classSpriteLimb[] limbDrawSequence;
string strMyName = "";
public string myName
{
get { return strMyName; }
set { strMyName = value; }
}
double dblDisplaySize = 1.0;
/// <summary>
/// double variable factor which determines size of output image relative to original images size where 1.0 is the same
/// </summary>
public double DisplaySize
{
get { return dblDisplaySize; }
set { dblDisplaySize = value; }
}
public Sprite.classSpriteHinge[] hinges = new classSpriteHinge[0];
/// <summary>
/// displays the sprite in the specified configuration and step at a point on referenced bitmap
/// all of the sprite's hinges are set to their specified configuration and step values
/// </summary>
/// <param name="bmpOutput">reference bitmap on which the sprite is to be drawn</param>
/// <param name="intConfigurationIndex">sprite's output configuration index value</param>
/// <param name="intConfigurationStep">sprite's output configuration step value</param>
/// <param name="ptOnScreenLocation">point on the screen where the center of the sprite's master limb is to be located</param>
public void putConfigurationOnScreen(ref Bitmap bmpOutput,
int intConfigurationIndex,
int intConfigurationStep,
Point ptOnScreenLocation)
{
putConfigurationOnScreen(ref bmpOutput,
intConfigurationIndex,
intConfigurationStep,
ptOnScreenLocation,
0,
DisplaySize,
enuMirror.none,
false);
}
/// <summary>
/// displays the sprite in the specified configuration and step at a point on referenced bitmap
/// all of the sprite's hinges are set to their specified configuration and step values
/// </summary>
/// <param name="bmpOutput">reference bitmap on which the sprite is to be drawn</param>
/// <param name="strConfigurationName">sprite's output configuration name</param>
/// <param name="intConfigurationStep">sprite's output configuration step value</param>
/// <param name="ptOnScreenLocation">point on the screen where the center of the sprite's master limb is to be located</param>
public void putConfigurationOnScreen(ref Bitmap bmpOutput,
string strConfigurationName,
int intConfigurationStep,
Point ptOnScreenLocation)
{
putConfigurationOnScreen(ref bmpOutput,
getIndexOfConfigurationByName(strConfigurationName),
intConfigurationStep,
ptOnScreenLocation,
0,
DisplaySize,
enuMirror.none,
false);
}
/// <summary>
/// displays the sprite in the specified configuration and step at a point on referenced bitmap
/// all of the sprite's hinges are set to their specified configuration and step values
/// </summary>
/// <param name="bmpOutput">reference bitmap on which the sprite is to be drawn</param>
/// <param name="strConfigurationName">sprite's output configuration name</param>
/// <param name="intConfigurationStep">sprite's output configuration step value</param>
/// <param name="ptOnScreenLocation">point on the screen where the center of the sprite's master limb is to be located</param>
/// <param name="DisplaySize">double variable which is multiplied times all size relevant parameters in the drawing sequence 1.0=original image size</param>
/// <param name="mirror">configuration image reflected in any of four directions, (none, vertical, horizontal or both)</param>
public void putConfigurationOnScreen(ref Bitmap bmpOutput,
string strConfigurationName,
int intConfigurationStep,
Point ptOnScreenLocation,
double displaySize,
enuMirror mirror)
{
putConfigurationOnScreen(ref bmpOutput,
getIndexOfConfigurationByName(strConfigurationName),
intConfigurationStep,
ptOnScreenLocation,
0,
displaySize,
mirror,
false);
}
/// <summary>
/// displays the sprite in the specified configuration and step at a point on referenced bitmap
/// all of the sprite's hinges are set to their specified configuration and step values
/// </summary>
/// <param name="bmpOutput">reference bitmap on which the sprite is to be drawn</param>
/// <param name="intConfigurationIndex">sprite's output configuration index value</param>
/// <param name="intConfigurationStep">sprite's output configuration step value</param>
/// <param name="ptOnScreenLocation">point on the screen where the center of the sprite's master limb is to be located</param>
/// <param name="DisplaySize">double variable which is multiplied times all size relevant parameters in the drawing sequence 1.0=original image size</param>
/// <param name="mirror">configuration image reflected in any of four directions, (none, vertical, horizontal or both)</param>
public void putConfigurationOnScreen(ref Bitmap bmpOutput,
int intConfigurationIndex,
int intConfigurationStep,
Point ptOnScreenLocation,
double dblAngle,
double DisplaySize,
enuMirror mirror,
bool bolForceRebuild)
{
if (bmpOutput == null)
return;
if (Configurations.Length <= intConfigurationIndex
|| intConfigurationIndex < 0
|| intConfigurationStep < 0
|| Configurations[intConfigurationIndex].steps == null
|| Configurations[intConfigurationIndex].steps.Length <= intConfigurationStep
)
return;
conCurrent = Configurations[intConfigurationIndex];
intConfigurationStep_Current = intConfigurationStep;
if (MasterLimb.IRotate)
{
MasterLimb.Angle = dblAngle;
MasterLimb.setDir();
}
setSpriteHingesToConfiguration(intConfigurationIndex, intConfigurationStep);
if (Configurations[intConfigurationIndex].steps != null)
{
if (Configurations[intConfigurationIndex].steps[intConfigurationStep].BmpCacheByMirrorType[(int)mirror].dir[MasterLimb.Dir].bmp == null
|| bolForceRebuild)
{
classSpriteLimb[] limDrawSequence = Configurations[intConfigurationIndex].LimbDrawSequence;
Configurations[intConfigurationIndex].steps[intConfigurationStep].BmpCacheByMirrorType[(int)mirror].dir[MasterLimb.Dir] = getImageOnBitmap(DisplaySize, mirror, limDrawSequence);
}
drawImageOnoutPutBitmap(ref bmpOutput,
Configurations[intConfigurationIndex].steps[intConfigurationStep].BmpCacheByMirrorType[(int)mirror].dir[MasterLimb.Dir],
ptOnScreenLocation);
}
}
/// <summary>
/// this function arranges the sprite's hinges according to the values stored in its configurations for a specific configuration & step
/// </summary>
/// <param name="intConfigurationIndex">configuration index to which hinges are to be set</param>
/// <param name="intConfigurationStep">configuration step to which hinges are to be set</param>
public void setSpriteHingesToConfiguration(int intConfigurationIndex, int intConfigurationStep)
{
for (int intHingeCounter = 0;
intHingeCounter < Configurations[intConfigurationIndex].steps[intConfigurationStep].hingeDetails.Length;
intHingeCounter++)
try
{
Configurations[intConfigurationIndex]
.steps[intConfigurationStep]
.hingeDetails[intHingeCounter].hinge.Angle
= Configurations[intConfigurationIndex].steps[intConfigurationStep].hingeDetails[intHingeCounter]
.angle;
}
catch (Exception) { }
}
/// <summary>
/// draws this sprite onto bitmap at point
/// </summary>
/// <param name="bmpOutput">bitmap onto which this sprite is drawn given its current configuration</param>
/// <param name="ptOnScreenLocation">location on bitmap where this sprite is drawn</param>
public void putImageOnScreen(ref Bitmap bmpOutput, Point ptOnScreenLocation)
{ putImageOnScreen(ref bmpOutput, ptOnScreenLocation, dblDisplaySize, enuMirror.none); }
/// <summary>
/// draws this sprite onto bitmap at point
/// </summary>
/// <param name="bmpOutput">bitmap onto which this sprite is drawn given its current configuration</param>
/// <param name="ptOnScreenLocation">location on bitmap where this sprite is drawn</param>
/// <param name="DisplaySize">factor by which images are multiplied, e.g. 1.0 original size, 2.0 twice original & 0.5 half original size</param>
public void putImageOnScreen(ref Bitmap bmpOutput, Point ptOnScreenLocation, double DisplaySize, enuMirror mirror)
{
if (bmpOutput == null)
return;
if (MasterLimb.IRotate)
MasterLimb.setDir();
udtBmpAndPtTLInfo udrTemp = getImageOnBitmap(DisplaySize, mirror, limbDrawSequence);
drawImageOnoutPutBitmap(ref bmpOutput, udrTemp, ptOnScreenLocation);
}
void drawImageOnoutPutBitmap(ref Bitmap bmpOutput, udtBmpAndPtTLInfo udrBmpAndPtTL, Point ptOnScreenLocation)
{
using (Graphics g = Graphics.FromImage(bmpOutput))
{ g.DrawImage(udrBmpAndPtTL.bmp, new Point(ptOnScreenLocation.X + udrBmpAndPtTL.ptTL.X, ptOnScreenLocation.Y + udrBmpAndPtTL.ptTL.Y)); }
for (int intLimbCounter = 0; intLimbCounter < hinges.Length; intLimbCounter++)
{
hinges[intLimbCounter].Limb_Slave.Loc = new Point(ptOnScreenLocation.X + udrBmpAndPtTL.ptTL.X + hinges[intLimbCounter].Limb_Slave.Loc.X,
ptOnScreenLocation.Y + udrBmpAndPtTL.ptTL.Y + hinges[intLimbCounter].Limb_Slave.Loc.Y);
}
MasterLimb.Loc = ptOnScreenLocation;
}
/// <summary>
/// this function returns the sprite's image, as it appears with the hinges
/// already set, onto the smallest bitmap that will fit the resultant image
/// </summary>
/// <param name="DisplaySize">factor by which the original image size is multiplied before out is generated</param>
/// <param name="mirror">mirror option, e.g. horizontal, vertical, both or neither</param>
/// <param name="limDrawSequence">classSpriteLimb array specifying in which order the different limbs are to be put onto the screen/param>
/// <returns>returns a structure of type udtBmpAndPTTLInfo which holds the smallest bitmap that will fit the output image it contains.
/// the center of the image is not necessarily the center of the bitmap but is described by the point ptTL</returns>
public udtBmpAndPtTLInfo getImageOnBitmap(double DisplaySize,
enuMirror mirror,
classSpriteLimb[] limDrawSequence)
{
udtBmpAndPtTLInfo udrRetVal = new udtBmpAndPtTLInfo();
MasterLimb.Loc = new Point(0, 0);
putImageOntoScreen_recursion(ref MasterLimb, DisplaySize);
udrRetVal.ptTL = new Point(-MasterLimb.myCurrentImage.bmp.Width / 2, -MasterLimb.myCurrentImage.bmp.Height / 2);
Point ptBR = new Point(MasterLimb.myCurrentImage.bmp.Width / 2, MasterLimb.myCurrentImage.bmp.Height / 2);
for (int intHingeCounter = 0; intHingeCounter < hinges.Length; intHingeCounter++)
{
Sprite.classSpriteLimb thisLimb = hinges[intHingeCounter].Limb_Slave;
if (thisLimb.recDest.Left < udrRetVal.ptTL.X)
udrRetVal.ptTL.X = thisLimb.recDest.Left;
if (thisLimb.recDest.Left + thisLimb.recDest.Width > ptBR.X)
ptBR.X = thisLimb.recDest.Left + thisLimb.recDest.Width;
if (thisLimb.recDest.Top < udrRetVal.ptTL.Y)
udrRetVal.ptTL.Y = thisLimb.recDest.Top;
if (thisLimb.recDest.Top + thisLimb.recDest.Height > ptBR.Y)
ptBR.Y = thisLimb.recDest.Top + thisLimb.recDest.Height;
}
if (ptBR.X == udrRetVal.ptTL.X)
ptBR.X += 1;
if (ptBR.Y == udrRetVal.ptTL.Y)
ptBR.Y += 1;
udrRetVal.bmp = new Bitmap(ptBR.X - udrRetVal.ptTL.X, ptBR.Y - udrRetVal.ptTL.Y);
using (Graphics g = Graphics.FromImage(udrRetVal.bmp))
{
if (limDrawSequence != null)
{
udrRetVal.limbPositions = new udtConfigStepLimbPosition[limDrawSequence.Length];
for (int intLimbCounter = 0; intLimbCounter < limDrawSequence.Length; intLimbCounter++)
{
Sprite.classSpriteLimb thisLimb = limDrawSequence[intLimbCounter];
if (thisLimb != null)
{
thisLimb.myCurrentImage.bmp.MakeTransparent();
Point ptPos = new Point((int)(-udrRetVal.ptTL.X + thisLimb.recDest.Left), (int)(-udrRetVal.ptTL.Y + thisLimb.recDest.Top));
thisLimb.Loc = new Point(ptPos.X + (int)(thisLimb.myCurrentImage.bmp.Width * DisplaySize / 2),
ptPos.Y + (int)(thisLimb.myCurrentImage.bmp.Height * DisplaySize / 2));
if (conCurrent != null)
{
int intDrawSequenceIndex = conCurrent.getLimbDrawSequenceIndex(thisLimb.Name.ToString());
if (intDrawSequenceIndex >= 0)
{
udrRetVal.limbPositions[intDrawSequenceIndex].limb = thisLimb;
udrRetVal.limbPositions[intDrawSequenceIndex].pt = new Point(thisLimb.Loc.X - MasterLimb.Loc.X, thisLimb.Loc.Y - MasterLimb.Loc.Y);
udrRetVal.limbPositions[intDrawSequenceIndex].dblAngle = thisLimb.Angle;
}
}
g.DrawImage(new Bitmap(thisLimb.myCurrentImage.bmp, thisLimb.recDest.Size), ptPos);
}
}
}
}
if (mirror == enuMirror.vertical)
{
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
for (int intLimbCounter = 0; intLimbCounter < hinges.Length; intLimbCounter++)
{
if (conCurrent != null)
{
int intDrawSequenceIndex = conCurrent.getLimbDrawSequenceIndex(hinges[intLimbCounter].Limb_Slave.Name.ToString());
if (intDrawSequenceIndex >= 0)
{
udrRetVal.limbPositions[intDrawSequenceIndex].limb = hinges[intLimbCounter].Limb_Slave;
udrRetVal.limbPositions[intDrawSequenceIndex].pt = new Point(udrRetVal.limbPositions[intDrawSequenceIndex].pt.X,
-udrRetVal.limbPositions[intDrawSequenceIndex].pt.Y);
udrRetVal.limbPositions[intDrawSequenceIndex].dblAngle = udrRetVal.limbPositions[intDrawSequenceIndex].limb.Angle;
}
}
hinges[intLimbCounter].Limb_Slave.Loc = new Point(hinges[intLimbCounter].Limb_Slave.Loc.X, udrRetVal.bmp.Height - hinges[intLimbCounter].Limb_Slave.Loc.Y);
}
udrRetVal.ptTL.Y = -ptBR.Y;
}
else if (mirror == enuMirror.horizontal)
{
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
for (int intLimbCounter = 0; intLimbCounter < hinges.Length; intLimbCounter++)
{
if (conCurrent != null)
{
int intDrawSequenceIndex = conCurrent.getLimbDrawSequenceIndex(hinges[intLimbCounter].Limb_Slave.Name.ToString());
if (intDrawSequenceIndex >= 0)
{
udrRetVal.limbPositions[intDrawSequenceIndex].limb = hinges[intLimbCounter].Limb_Slave;
udrRetVal.limbPositions[intDrawSequenceIndex].pt = new Point(-udrRetVal.limbPositions[intDrawSequenceIndex].pt.X,
udrRetVal.limbPositions[intDrawSequenceIndex].pt.Y);
udrRetVal.limbPositions[intDrawSequenceIndex].dblAngle = udrRetVal.limbPositions[intDrawSequenceIndex].limb.Angle;
}
}
hinges[intLimbCounter].Limb_Slave.Loc = new Point(udrRetVal.bmp.Width - hinges[intLimbCounter].Limb_Slave.Loc.X, hinges[intLimbCounter].Limb_Slave.Loc.Y);
}
udrRetVal.ptTL.X = -ptBR.X;
}
else if (mirror == enuMirror.VerticalAndHorizontal)
{
udrRetVal.bmp.RotateFlip(RotateFlipType.RotateNoneFlipXY);
for (int intLimbCounter = 0; intLimbCounter < hinges.Length; intLimbCounter++)
{
if (conCurrent != null)
{
int intDrawSequenceIndex = conCurrent.getLimbDrawSequenceIndex(hinges[intLimbCounter].Limb_Slave.Name.ToString());
if (intDrawSequenceIndex >= 0)
{
udrRetVal.limbPositions[intDrawSequenceIndex].limb = hinges[intLimbCounter].Limb_Slave;
udrRetVal.limbPositions[intDrawSequenceIndex].pt = new Point(-udrRetVal.limbPositions[intDrawSequenceIndex].pt.X,
-udrRetVal.limbPositions[intDrawSequenceIndex].pt.Y);
udrRetVal.limbPositions[intDrawSequenceIndex].dblAngle = udrRetVal.limbPositions[intDrawSequenceIndex].limb.Angle;
}
}
hinges[intLimbCounter].Limb_Slave.Loc = new Point(udrRetVal.bmp.Width - hinges[intLimbCounter].Limb_Slave.Loc.X,
udrRetVal.bmp.Height - hinges[intLimbCounter].Limb_Slave.Loc.Y);
}
udrRetVal.ptTL = new Point(-ptBR.X, -ptBR.Y);
}
udrRetVal.bmp.MakeTransparent();
return udrRetVal;
}
/// <summary>
/// this function receives a limb which has already been angled and positioned
/// this limb then places all of its slaves limbs by setting their respective positions & angles
/// then calls itself once for each slave that recurses with each of these limbs
/// </summary>
/// <param name="thisLimb">reference to this recursion's master-limb which will recurse for each of its slave limbs</param>
/// <param name="dblLocalSizeFactor">factor by which original image is multiplied when calculating positions of slave limbs</param>
public void putImageOntoScreen_recursion(ref classSpriteLimb thisLimb,
double dblLocalSizeFactor)
{
if (thisLimb.IRotate)
thisLimb.setDir();
thisLimb.myCurrentImage = thisLimb.getSpriteImageFromArray();
thisLimb.recDest = new Rectangle(new Point(thisLimb.Loc.X - (int)(thisLimb.myCurrentImage.bmp.Width * dblLocalSizeFactor / 2),
thisLimb.Loc.Y - (int)(thisLimb.myCurrentImage.bmp.Height * dblLocalSizeFactor / 2)),
new Size((int)((double)thisLimb.myCurrentImage.bmp.Size.Width * dblLocalSizeFactor),
(int)((double)thisLimb.myCurrentImage.bmp.Size.Height * dblLocalSizeFactor)));
if (thisLimb.recDest.Width < 1)
thisLimb.recDest.Width = 1;
if (thisLimb.recDest.Height < 1)
thisLimb.recDest.Height = 1;
if (thisLimb.mySlaveLimbs != null)
for (int intSlaveCounter = 0; intSlaveCounter < thisLimb.mySlaveLimbs.Length; intSlaveCounter++)
{
double dblNewAngle = thisLimb.Angle
+ thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.Angle;
thisLimb.mySlaveLimbs[intSlaveCounter].Angle = dblNewAngle;
thisLimb.mySlaveLimbs[intSlaveCounter].setDir();
Point ptOnMaster = new Point(thisLimb.Loc.X + (int)(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Master.radius * dblLocalSizeFactor * Math.Cos(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Master.angle - thisLimb.Angle)),
thisLimb.Loc.Y - (int)(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Master.radius * dblLocalSizeFactor * Math.Sin(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Master.angle - thisLimb.Angle)));
thisLimb.mySlaveLimbs[intSlaveCounter].Loc = new Point(ptOnMaster.X + (int)(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Slave.radius * dblLocalSizeFactor * Math.Cos(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Slave.angle + thisLimb.mySlaveLimbs[intSlaveCounter].Angle + Math.PI)),
ptOnMaster.Y + (int)(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Slave.radius * dblLocalSizeFactor * Math.Sin(thisLimb.mySlaveLimbs[intSlaveCounter].MasterHinge.RadCoor_Slave.angle + thisLimb.mySlaveLimbs[intSlaveCounter].Angle + Math.PI)));
putImageOntoScreen_recursion(ref thisLimb.mySlaveLimbs[intSlaveCounter],
dblLocalSizeFactor);
}
}
/// <summary>
/// returns a pointer to the limb identified by name
/// </summary>
/// <param name="LimbName">name of the limb to be searched</param>
/// <returns>returns a pointer to an object of type classSpriteLimb</returns>
public Sprite.classSpriteLimb getLimbByName(string LimbName)
{
LimbName = LimbName.Trim().ToUpper();
for (int intHingeCounter = 0; intHingeCounter < hinges.Length; intHingeCounter++)
{
if (hinges[intHingeCounter].Limb_Slave.Name.Trim().ToUpper().CompareTo(LimbName) == 0)
return hinges[intHingeCounter].Limb_Slave;
}
if (MasterLimb.Name.Trim().CompareTo(LimbName) == 0)
return MasterLimb;
return null;
}
/// <summary>
/// returns a pointer to the hinge identified by name
/// </summary>
/// <param name="HingeName">name of hinge to be searched</param>
/// <returns>returns a pointer to an object of type classSpriteHinge </returns>
public Sprite.classSpriteHinge getHingeByName(string HingeName)
{
HingeName = HingeName.ToUpper();
for (int intHingeCounter = 0; intHingeCounter < hinges.Length; intHingeCounter++)
if (hinges[intHingeCounter].name.ToUpper().CompareTo(HingeName) == 0)
return hinges[intHingeCounter];
return null;
}
public Sprite.classConfiguration getConfigurationByName(string ConfigurationName)
{
ConfigurationName = ConfigurationName.Trim().ToUpper();
for (int intConfigurationCounter = 0; intConfigurationCounter < Configurations.Length; intConfigurationCounter++)
if (Configurations[intConfigurationCounter].name.Trim().ToUpper().CompareTo(ConfigurationName) == 0)
return Configurations[intConfigurationCounter];
return null;
}
public int getIndexOfConfigurationByName(string ConfigurationName)
{
ConfigurationName = ConfigurationName.Trim().ToUpper();
for (int intConfigurationCounter = 0; intConfigurationCounter < Configurations.Length; intConfigurationCounter++)
if (Configurations[intConfigurationCounter].name.Trim().ToUpper().CompareTo(ConfigurationName) == 0)
return intConfigurationCounter;
return -1;
}
public int getIndexOfHingeByName(string hingeName)
{
hingeName = hingeName.Trim().ToUpper();
for (int intHingeCounter = 0; intHingeCounter < hinges.Length; intHingeCounter++)
if (hinges[intHingeCounter].name.Trim().ToUpper().CompareTo(hingeName) == 0)
return intHingeCounter;
return -1;
}
public int getIndexOfLimbByName(string limbName)
{
limbName = limbName.Trim().ToUpper();
for (int intlimbCounter = 0; intlimbCounter < hinges.Length; intlimbCounter++)
if (hinges[intlimbCounter].Limb_Slave.Name.Trim().ToUpper().CompareTo(limbName) == 0)
return intlimbCounter;
return -1;
}
}
public class classMath
{
public class classMaxMinDouble
{
public double Min;
public double Max;
public classMaxMinDouble()
{
Min = 0.0;
Max = 0.0;
}
public classMaxMinDouble(double min, double max)
{
Min = min;
Max = max;
}
}
public class classRadialCoor
{
public double angle;
public double radius;
public classRadialCoor()
{
angle = 0;
radius = 0;
}
public classRadialCoor(double Angle, double Radius)
{
angle = Angle;
radius = Radius;
}
}
/// <summary>
/// converts a radial coordinate system into cartesian with origin as initial coordinate
/// </summary>
/// <param name="radCoor">radial vector</param>
/// <returns>cartesian point</returns>
public static Point getRadLocation(classRadialCoor radCoor) { return getRadLocation(new Point(0, 0), radCoor); }
/// <summary>
/// calculates the cartesian location away from input point using radial vector
/// </summary>
/// <param name="pt">input point from which </param>
/// <param name="radCoor">radial vector</param>
/// <returns>cartesian point</returns>
public static Point getRadLocation(Point pt, classRadialCoor radCoor)
{ return new Point((int)(pt.X + radCoor.radius * Math.Cos(radCoor.angle)), (int)(pt.Y + radCoor.radius * Math.Sin(radCoor.angle))); }
/// <summary>
/// returns the angle in radians between the points ptA and ptB
/// </summary>
/// <param name="ptA">first point</param>
/// <param name="ptB">second point</param>
/// <returns>double variable equal to angle between origin and point(dX, dY) in radians</returns>
public static double arcTan(Point ptA, Point ptB) { return arcTan(ptA.X - ptB.X, ptA.Y - ptB.Y); }
/// <summary>
/// returns the angle in radians between the origin and the point located at (dX, dY)
/// </summary>
/// <param name="dX">x coordinate of vector end</param>
/// <param name="dY">y coordinate of vector end</param>
/// <returns>double variable equal to angle between origin and point(dX, dY) in radians</returns>
public static double arcTan(double dX, double dY)
{
double dblAngle = 0;
if (dX == 0)
if (dY < 0)
dblAngle = 3.0 * Math.PI / 2.0;
else
dblAngle = Math.PI / 2.0;
else
{
dblAngle = Math.Atan((double)dY / (double)dX);
// Q2 Q1
// Q3 Q4
if (dX < 0)
{
if (dY < 0) // Q3
dblAngle = Math.PI + dblAngle;
else // Q2
dblAngle = Math.PI + dblAngle;
}
else if (dX > 0)
{
if (dY < 0) // Q4
dblAngle = 2.0 * Math.PI + dblAngle;
else // Q1
;
}
}
cleanAngle(ref dblAngle);
return dblAngle;
}
public static void cleanRadians(ref classRadialCoor udrRadCoor) { cleanAngle(ref udrRadCoor.angle); }
public static double cleanAngle(ref double angle)
{
while (angle < 0)
angle += 2 * Math.PI;
while (angle > 2 * Math.PI)
angle -= 2 * Math.PI;
return angle;
}
public static double distanceBetweenTwoPoints(Point pt1, Point pt2) { return Math.Sqrt(Math.Pow(pt1.X - pt2.X, 2) + Math.Pow(pt1.Y - pt2.Y, 2)); }
}
}