HollowCylinder.java 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package min3d.objectPrimitives;
  2. import min3d.core.Object3dContainer;
  3. import min3d.vos.Color4;
  4. import min3d.vos.Face;
  5. import min3d.vos.Number3d;
  6. import min3d.vos.Uv;
  7. /**
  8. * Example of a more complex programmatically-drawn object.
  9. *
  10. * Unfortunately, because the object's faces share as many vertices as possible,
  11. * shading is incorrect on the cylinder surfaces.
  12. *
  13. * To fix would require duplicating vertices, adding new normals,
  14. * and generally reworking algorithm. Yek.
  15. */
  16. public class HollowCylinder extends Object3dContainer
  17. {
  18. private double DEG = Math.PI / 180;
  19. private int _segs;
  20. private float _radiusOuter;
  21. private float _radiusInner;
  22. private float _height;
  23. public HollowCylinder(float $radiusOuter, float $radiusInner, float $height, int $segs)
  24. {
  25. super($segs * 4, $segs * 8);
  26. _segs = $segs;
  27. _height = $height;
  28. _radiusOuter = $radiusOuter;
  29. _radiusInner = $radiusInner;
  30. addHorizontalSurface(false, _height / +2);
  31. addHorizontalSurface(true, _height / -2);
  32. addVerticalSurface(true);
  33. addVerticalSurface(false);
  34. }
  35. private void addHorizontalSurface(boolean $isTopSide, float $zOffset)
  36. {
  37. int indexOffset = _vertices.size();
  38. float step = (float)((360.0 / _segs) * DEG);
  39. // verts
  40. Color4 col = $isTopSide ? new Color4(255,0,0,255) : new Color4(0,255,0,255);
  41. for (int i = 0; i < _segs; i++)
  42. {
  43. float angle = (float)i * step;
  44. // outer
  45. float x1 = (float) Math.sin(angle) * _radiusOuter;
  46. float y1 = (float) Math.cos(angle) * _radiusOuter;
  47. float z1 = $zOffset;
  48. Uv uv1 = new Uv(x1,y1);
  49. Number3d n1 = new Number3d(0,0, $isTopSide ? -1 : +1);
  50. this.vertices().addVertex(new Number3d(x1,y1,z1), uv1, n1, col);
  51. // inner
  52. float x2 = (float) Math.sin(angle) * _radiusInner;
  53. float y2 = (float) Math.cos(angle) * _radiusInner;
  54. float z2 = $zOffset;
  55. Uv uv2 = new Uv(x2,y2);
  56. Number3d n2 = new Number3d(0,0, $isTopSide ? -1 : +1);
  57. this.vertices().addVertex(new Number3d(x2,y2,z2), uv2, n2, col);
  58. }
  59. // indicies
  60. for (int i = 2; i <= _segs; i++)
  61. {
  62. int a = indexOffset + i*2 - 3 - 1;
  63. int b = indexOffset + i*2 - 2 - 1;
  64. int c = indexOffset + i*2 - 1 - 1;
  65. int d = indexOffset + i*2 - 0 - 1;
  66. addQuad(a,b,c,d, $isTopSide);
  67. }
  68. int a = indexOffset + _segs*2 - 1 - 1; // ... connect last segment
  69. int b = indexOffset + _segs*2 - 0 - 1;
  70. int c = indexOffset + 0;
  71. int d = indexOffset + 1;
  72. addQuad(a,b,c,d, $isTopSide);
  73. }
  74. //
  75. private void addVerticalSurface(boolean $isOuter)
  76. {
  77. int off = (int)(_vertices.size() / 2);
  78. for (int i = 0; i < _segs - 1; i++)
  79. {
  80. int ul = i*2;
  81. int bl = ul + off;
  82. int ur = i*2 + 2;
  83. int br = ur + off;
  84. if (!$isOuter) {
  85. ul++;
  86. bl++;
  87. ur++;
  88. br++;
  89. }
  90. addQuad(ul,bl,ur,br, $isOuter);
  91. }
  92. int ul = (_segs-1)*2;
  93. int bl = ul + off;
  94. int ur = 0*2;
  95. int br = ur + off;
  96. if (!$isOuter) {
  97. ul++;
  98. bl++;
  99. ur++;
  100. br++;
  101. }
  102. addQuad(ul,bl,ur,br, $isOuter);
  103. }
  104. private void addQuad(int ul, int bl, int ur, int br, boolean $flipped)
  105. {
  106. Face t;
  107. if (! $flipped)
  108. {
  109. _faces.add((short)ul,(short)bl,(short)ur);
  110. _faces.add((short)bl,(short)br,(short)ur);
  111. }
  112. else
  113. {
  114. _faces.add((short)ur,(short)br,(short)ul);
  115. _faces.add((short)br,(short)bl,(short)ul);
  116. }
  117. }
  118. }