00001
00009 using System;
00010
00011 using GRV11;
00012
00013 namespace Objects3D
00014 {
00022 public class Cube
00023 {
00024 protected byte FID = 0;
00025
00026 protected Coordinate[,] FMatrix;
00027 protected Coordinate[] FPoints;
00028
00029 protected Coordinate FPos = null;
00030 protected Coordinate FRot = null;
00031 protected Coordinate FScale = null;
00032
00033 protected float FScaleMultiplier = 1.0F;
00034
00035 protected void OnAssignedPos(Coordinate ACoordinate, float AOldX, float AOldY, float AOldZ)
00036 {
00037 if (!(FPos.Equals(AOldX, AOldY, AOldZ)))
00038 {
00039 foreach (Coordinate LIndex in FPoints)
00040 {
00041 LIndex.Translate(AOldX, AOldY, AOldZ, false);
00042
00043 LIndex.Translate(FPos, true);
00044 }
00045 }
00046 }
00047
00048 protected void OnAssignedRot(Coordinate ACoordinate, float AOldX, float AOldY, float AOldZ)
00049 {
00050 if (!(FRot.Equals(AOldX, AOldY, AOldZ)))
00051 {
00052 foreach (Coordinate LIndex in FPoints)
00053 {
00054 LIndex.Translate(FPos, false);
00055 LIndex.Rotate(AOldX, AOldY, AOldZ, false);
00056
00057 LIndex.Rotate(FRot, true);
00058 LIndex.Translate(FPos, true);
00059 }
00060 }
00061 }
00062
00063 protected void OnAssignedScale(Coordinate ACoordinate, float AOldX, float AOldY, float AOldZ)
00064 {
00065 if (!(FScale.Equals(AOldX, AOldY, AOldZ)))
00066 {
00067 foreach (Coordinate LIndex in FPoints)
00068 {
00069 LIndex.Translate(FPos, false);
00070 LIndex.Rotate(FRot, false);
00071 LIndex.Scale(AOldX, AOldY, AOldZ, FScaleMultiplier, false);
00072
00073 LIndex.Scale(FScale, FScaleMultiplier, true);
00074 LIndex.Rotate(FRot, true);
00075 LIndex.Translate(FPos, true);
00076 }
00077 }
00078 }
00079
00080 public Cube()
00081 {
00082 FID = 0;
00083
00084 FPoints = new Coordinate[8];
00085 FPoints[0] = new Coordinate(-0.5F, -0.5F, -0.5F);
00086 FPoints[1] = new Coordinate(+0.5F, -0.5F, -0.5F);
00087 FPoints[2] = new Coordinate(-0.5F, +0.5F, -0.5F);
00088 FPoints[3] = new Coordinate(-0.5F, -0.5F, +0.5F);
00089 FPoints[4] = new Coordinate(+0.5F, +0.5F, -0.5F);
00090 FPoints[5] = new Coordinate(+0.5F, -0.5F, +0.5F);
00091 FPoints[6] = new Coordinate(-0.5F, +0.5F, +0.5F);
00092 FPoints[7] = new Coordinate(+0.5F, +0.5F, +0.5F);
00093
00094 FMatrix = new Coordinate[6, 4];
00095
00096
00097 FMatrix[0, 0] = FPoints[2];
00098 FMatrix[0, 1] = FPoints[6];
00099 FMatrix[0, 2] = FPoints[7];
00100 FMatrix[0, 3] = FPoints[4];
00101
00102
00103 FMatrix[1, 0] = FPoints[1];
00104 FMatrix[1, 1] = FPoints[5];
00105 FMatrix[1, 2] = FPoints[3];
00106 FMatrix[1, 3] = FPoints[0];
00107
00108
00109 FMatrix[2, 0] = FPoints[2];
00110 FMatrix[2, 1] = FPoints[0];
00111 FMatrix[2, 2] = FPoints[3];
00112 FMatrix[2, 3] = FPoints[6];
00113
00114
00115 FMatrix[3, 0] = FPoints[7];
00116 FMatrix[3, 1] = FPoints[5];
00117 FMatrix[3, 2] = FPoints[1];
00118 FMatrix[3, 3] = FPoints[4];
00119
00120
00121 FMatrix[4, 0] = FPoints[6];
00122 FMatrix[4, 1] = FPoints[3];
00123 FMatrix[4, 2] = FPoints[5];
00124 FMatrix[4, 3] = FPoints[7];
00125
00126
00127 FMatrix[5, 0] = FPoints[4];
00128 FMatrix[5, 1] = FPoints[1];
00129 FMatrix[5, 2] = FPoints[0];
00130 FMatrix[5, 3] = FPoints[2];
00131
00132 FPos = new Coordinate(0.0F, 0.0F, 0.0F);
00133 FRot = new Coordinate(0.0F, 0.0F, 0.0F);
00134 FScale = new Coordinate(1.0F, 1.0F, 1.0F);
00135
00136 FPos.OnAssigned += new Coordinate.OnChangedHandler(OnAssignedPos);
00137 FRot.OnAssigned += new Coordinate.OnChangedHandler(OnAssignedRot);
00138 FScale.OnAssigned += new Coordinate.OnChangedHandler(OnAssignedScale);
00139
00140 FScaleMultiplier = 1.0F;
00141 }
00142
00150 public static int ByteSize
00151 {
00152 get
00153 {
00154 return ((Coordinate.ByteSize * 3) + (sizeof(float) * 1) + (sizeof(byte) * 1));
00155 }
00156 }
00157
00167 public byte[] GetBytes()
00168 {
00169 byte[] LResult = new byte[ByteSize];
00170
00171 byte[] LID = new byte[1]{FID};
00172
00173 byte[] LPos = FPos.GetBytes();
00174 byte[] LRot = FRot.GetBytes();
00175 byte[] LScale = FScale.GetBytes();
00176
00177 byte[] LScaleMultiplier = BitConverter.GetBytes(FScaleMultiplier);
00178
00179 LID.CopyTo(LResult, 0);
00180
00181 LPos.CopyTo(LResult, (Coordinate.ByteSize * 0) + (sizeof(byte) * LID.Length));
00182 LRot.CopyTo(LResult, (Coordinate.ByteSize * 1) + (sizeof(byte) * LID.Length));
00183 LScale.CopyTo(LResult, (Coordinate.ByteSize * 2) + (sizeof(byte) * LID.Length));
00184
00185 LScaleMultiplier.CopyTo(LResult, (Coordinate.ByteSize * 3) + (sizeof(byte) * LID.Length));
00186
00187 return LResult;
00188 }
00189
00202 public bool SetBytes(byte[] ABytes, int AOffset)
00203 {
00204 bool LResult = false;
00205
00206 if (((ABytes.Length - AOffset) >= ByteSize) && (AOffset >= 0))
00207 {
00208 FID = ABytes[AOffset];
00209
00210 FPos.SetBytes(ABytes, (Coordinate.ByteSize * 0) + (sizeof(byte) * 1) + AOffset);
00211 FRot.SetBytes(ABytes, (Coordinate.ByteSize * 1) + (sizeof(byte) * 1) + AOffset);
00212 FScale.SetBytes(ABytes, (Coordinate.ByteSize * 2) + (sizeof(byte) * 1) + AOffset);
00213
00214 ScaleMultiplier = BitConverter.ToSingle(ABytes, (Coordinate.ByteSize * 3) + (sizeof(byte) * 1) + AOffset);
00215
00216 LResult = true;
00217 }
00218
00219 return LResult;
00220 }
00221
00229 public byte ID
00230 {
00231 get
00232 {
00233 return FID;
00234 }
00235
00236 set
00237 {
00238 FID = value;
00239 }
00240 }
00241
00249 public float ScaleMultiplier
00250 {
00251 get
00252 {
00253 return FScaleMultiplier;
00254 }
00255
00256 set
00257 {
00258 if (value != FScaleMultiplier)
00259 {
00260 foreach (Coordinate LIndex in FPoints)
00261 {
00262 LIndex.Translate(FPos, false);
00263 LIndex.Rotate(FRot, false);
00264 LIndex.Scale(FScale, FScaleMultiplier, false);
00265
00266 LIndex.Scale(FScale, value, true);
00267 LIndex.Rotate(FRot, true);
00268 LIndex.Translate(FPos, true);
00269 }
00270
00271 FScaleMultiplier = value;
00272 }
00273 }
00274 }
00275
00283 public Coordinate Pos
00284 {
00285 get
00286 {
00287 return FPos;
00288 }
00289
00290 set
00291 {
00292 if (!(FPos.Equals(value)))
00293 {
00294 foreach (Coordinate LIndex in FPoints)
00295 {
00296 LIndex.Translate(FPos, false);
00297
00298 LIndex.Translate(value, true);
00299 }
00300
00301 FPos.Assign(value);
00302 }
00303 }
00304 }
00305
00313 public Coordinate Rot
00314 {
00315 get
00316 {
00317 return FRot;
00318 }
00319
00320 set
00321 {
00322 if (!(FRot.Equals(value)))
00323 {
00324 foreach (Coordinate LIndex in FPoints)
00325 {
00326 LIndex.Translate(FPos, false);
00327 LIndex.Rotate(FRot, false);
00328
00329 LIndex.Rotate(value, true);
00330 LIndex.Translate(FPos, true);
00331 }
00332
00333 FRot.Assign(value);
00334 }
00335 }
00336 }
00337
00345 public Coordinate Scale
00346 {
00347 get
00348 {
00349 return FScale;
00350 }
00351
00352 set
00353 {
00354 if (!(FScale.Equals(value)))
00355 {
00356 foreach (Coordinate LIndex in FPoints)
00357 {
00358 LIndex.Translate(FPos, false);
00359 LIndex.Rotate(FRot, false);
00360 LIndex.Scale(FScale, FScaleMultiplier, false);
00361
00362 LIndex.Scale(value, FScaleMultiplier, true);
00363 LIndex.Rotate(FRot, true);
00364 LIndex.Translate(FPos, true);
00365 }
00366
00367 FScale.Assign(value);
00368 }
00369 }
00370 }
00371
00379 public Coordinate[,] Matrix
00380 {
00381 get
00382 {
00383 return FMatrix;
00384 }
00385 }
00386
00394 public Coordinate[] Points
00395 {
00396 get
00397 {
00398 return FPoints;
00399 }
00400 }
00401
00413 public bool Assign(Cube ACube)
00414 {
00415 bool LResult = false;
00416
00417 if (ACube != null)
00418 {
00419 ID = ACube.ID;
00420
00421 LResult = FPos.Assign(ACube.Pos);
00422 LResult = (LResult && FRot.Assign(ACube.Rot));
00423 LResult = (LResult && FScale.Assign(ACube.Scale));
00424
00425 ScaleMultiplier = ACube.ScaleMultiplier;
00426 }
00427
00428 return LResult;
00429 }
00430
00446 public bool IsInBoundingBox(float AX, float AY, float AZ, float ARadius, ref float ANewY)
00447 {
00448 bool LResult = false;
00449
00450 float LXmax = FPoints[0].X;
00451 float LXmin = FPoints[0].X;
00452 float LYmax = FPoints[0].Y;
00453 float LYmin = FPoints[0].Y;
00454 float LZmax = FPoints[0].Z;
00455 float LZmin = FPoints[0].Z;
00456
00457 for (int LIndex = 1; LIndex < FPoints.GetLength(0); LIndex++)
00458 {
00459 if (FPoints[LIndex].X < LXmin)
00460 {
00461 LXmin = FPoints[LIndex].X;
00462 }
00463 if (FPoints[LIndex].X > LXmax)
00464 {
00465 LXmax = FPoints[LIndex].X;
00466 }
00467
00468 if (FPoints[LIndex].Y < LYmin)
00469 {
00470 LYmin = FPoints[LIndex].Y;
00471 }
00472 if (FPoints[LIndex].Y > LYmax)
00473 {
00474 LYmax = FPoints[LIndex].Y;
00475 }
00476
00477 if (FPoints[LIndex].Z < LZmin)
00478 {
00479 LZmin = FPoints[LIndex].Z;
00480 }
00481 if (FPoints[LIndex].Z > LZmax)
00482 {
00483 LZmax = FPoints[LIndex].Z;
00484 }
00485 }
00486
00487 LResult = (LXmin <= AX) && (LXmax >= AX);
00488 if (LResult)
00489 {
00490 LResult = LResult = (LZmin <= AZ) && (LZmax >= AZ);
00491 if (LResult)
00492 {
00493 LResult = (LYmin - 0.5F <= AY + ARadius) && (LYmin + 0.5F >= AY + ARadius);
00494 if (LResult)
00495 {
00496 ANewY = AY;
00497 }
00498 }
00499 }
00500
00501
00502 return LResult;
00503 }
00504
00514 public void Draw(GR AGR)
00515 {
00516 if (AGR != null)
00517 {
00518 AGR.glBegin(GR.GL_QUADS);
00519
00520 for (int LIndexA = 0; LIndexA < FMatrix.GetLength(0); LIndexA++)
00521 {
00522 for (int LIndexB = 0; LIndexB < FMatrix.GetLength(1); LIndexB++)
00523 {
00524 AGR.glVertex3f(FMatrix[LIndexA, LIndexB].X, FMatrix[LIndexA, LIndexB].Y, FMatrix[LIndexA, LIndexB].Z);
00525 }
00526 }
00527
00528 AGR.glEnd();
00529 }
00530 }
00531 }
00532 }