PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/external/jmonkeyengine/engine/src/core/com/jme3/scene/shape/Curve.java

https://bitbucket.org/rlyspn/androidrr
Java | 271 lines | 177 code | 21 blank | 73 comment | 13 complexity | 0b0f81a57ef5dccca0da1d21cbafe384 MD5 | raw file
  1. /*
  2. * Copyright (c) 2009-2010 jMonkeyEngine
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. package com.jme3.scene.shape;
  33. import com.jme3.math.Spline;
  34. import com.jme3.math.Vector3f;
  35. import com.jme3.scene.Mesh;
  36. import com.jme3.scene.VertexBuffer;
  37. import java.util.Iterator;
  38. import java.util.List;
  39. /**
  40. * A <code>Curve</code> is a visual, line-based representation of a {@link Spline}.
  41. * The underlying Spline will be sampled N times where N is the number of
  42. * segments as specified in the constructor. Each segment will represent
  43. * one line in the generated mesh.
  44. *
  45. * @author Nehon
  46. */
  47. public class Curve extends Mesh {
  48. private Spline spline;
  49. private Vector3f temp = new Vector3f();
  50. /**
  51. * Serialization only. Do not use.
  52. */
  53. public Curve(){
  54. }
  55. /**
  56. * Create a curve mesh.
  57. * Use a CatmullRom spline model that does not cycle.
  58. *
  59. * @param controlPoints the control points to use to create this curve
  60. * @param nbSubSegments the number of subsegments between the control points
  61. */
  62. public Curve(Vector3f[] controlPoints, int nbSubSegments) {
  63. this(new Spline(Spline.SplineType.CatmullRom, controlPoints, 10, false), nbSubSegments);
  64. }
  65. /**
  66. * Create a curve mesh from a Spline
  67. *
  68. * @param spline the spline to use
  69. * @param nbSubSegments the number of subsegments between the control points
  70. */
  71. public Curve(Spline spline, int nbSubSegments) {
  72. super();
  73. this.spline = spline;
  74. switch (spline.getType()) {
  75. case CatmullRom:
  76. this.createCatmullRomMesh(nbSubSegments);
  77. break;
  78. case Bezier:
  79. this.createBezierMesh(nbSubSegments);
  80. break;
  81. case Nurb:
  82. this.createNurbMesh(nbSubSegments);
  83. break;
  84. case Linear:
  85. default:
  86. this.createLinearMesh();
  87. break;
  88. }
  89. }
  90. private void createCatmullRomMesh(int nbSubSegments) {
  91. float[] array = new float[((spline.getControlPoints().size() - 1) * nbSubSegments + 1) * 3];
  92. short[] indices = new short[(spline.getControlPoints().size() - 1) * nbSubSegments * 2];
  93. int i = 0;
  94. int cptCP = 0;
  95. for (Iterator<Vector3f> it = spline.getControlPoints().iterator(); it.hasNext();) {
  96. Vector3f vector3f = it.next();
  97. array[i] = vector3f.x;
  98. i++;
  99. array[i] = vector3f.y;
  100. i++;
  101. array[i] = vector3f.z;
  102. i++;
  103. if (it.hasNext()) {
  104. for (int j = 1; j < nbSubSegments; j++) {
  105. spline.interpolate((float) j / nbSubSegments, cptCP, temp);
  106. array[i] = temp.getX();
  107. i++;
  108. array[i] = temp.getY();
  109. i++;
  110. array[i] = temp.getZ();
  111. i++;
  112. }
  113. }
  114. cptCP++;
  115. }
  116. i = 0;
  117. int k = 0;
  118. for (int j = 0; j < (spline.getControlPoints().size() - 1) * nbSubSegments; j++) {
  119. k = j;
  120. indices[i] = (short) k;
  121. i++;
  122. k++;
  123. indices[i] = (short) k;
  124. i++;
  125. }
  126. this.setMode(Mesh.Mode.Lines);
  127. this.setBuffer(VertexBuffer.Type.Position, 3, array);
  128. this.setBuffer(VertexBuffer.Type.Index, 2, indices);//(spline.getControlPoints().size() - 1) * nbSubSegments * 2
  129. this.updateBound();
  130. this.updateCounts();
  131. }
  132. /**
  133. * This method creates the Bezier path for this curve.
  134. *
  135. * @param nbSubSegments
  136. * amount of subsegments between position control points
  137. */
  138. private void createBezierMesh(int nbSubSegments) {
  139. if(nbSubSegments==0) {
  140. nbSubSegments = 1;
  141. }
  142. int centerPointsAmount = (spline.getControlPoints().size() + 2) / 3;
  143. //calculating vertices
  144. float[] array = new float[((centerPointsAmount - 1) * nbSubSegments + 1) * 3];
  145. int currentControlPoint = 0;
  146. List<Vector3f> controlPoints = spline.getControlPoints();
  147. int lineIndex = 0;
  148. for (int i = 0; i < centerPointsAmount - 1; ++i) {
  149. Vector3f vector3f = controlPoints.get(currentControlPoint);
  150. array[lineIndex++] = vector3f.x;
  151. array[lineIndex++] = vector3f.y;
  152. array[lineIndex++] = vector3f.z;
  153. for (int j = 1; j < nbSubSegments; ++j) {
  154. spline.interpolate((float) j / nbSubSegments, currentControlPoint, temp);
  155. array[lineIndex++] = temp.getX();
  156. array[lineIndex++] = temp.getY();
  157. array[lineIndex++] = temp.getZ();
  158. }
  159. currentControlPoint += 3;
  160. }
  161. Vector3f vector3f = controlPoints.get(currentControlPoint);
  162. array[lineIndex++] = vector3f.x;
  163. array[lineIndex++] = vector3f.y;
  164. array[lineIndex++] = vector3f.z;
  165. //calculating indexes
  166. int i = 0, k = 0;
  167. short[] indices = new short[(centerPointsAmount - 1) * nbSubSegments << 1];
  168. for (int j = 0; j < (centerPointsAmount - 1) * nbSubSegments; ++j) {
  169. k = j;
  170. indices[i++] = (short) k;
  171. ++k;
  172. indices[i++] = (short) k;
  173. }
  174. this.setMode(Mesh.Mode.Lines);
  175. this.setBuffer(VertexBuffer.Type.Position, 3, array);
  176. this.setBuffer(VertexBuffer.Type.Index, 2, indices);
  177. this.updateBound();
  178. this.updateCounts();
  179. }
  180. /**
  181. * This method creates the Nurb path for this curve.
  182. * @param nbSubSegments
  183. * amount of subsegments between position control points
  184. */
  185. private void createNurbMesh(int nbSubSegments) {
  186. float minKnot = spline.getMinNurbKnot();
  187. float maxKnot = spline.getMaxNurbKnot();
  188. float deltaU = (maxKnot - minKnot)/nbSubSegments;
  189. float[] array = new float[(nbSubSegments + 1) * 3];
  190. float u = minKnot;
  191. Vector3f interpolationResult = new Vector3f();
  192. for(int i=0;i<array.length;i+=3) {
  193. spline.interpolate(u, 0, interpolationResult);
  194. array[i] = interpolationResult.x;
  195. array[i + 1] = interpolationResult.y;
  196. array[i + 2] = interpolationResult.z;
  197. u += deltaU;
  198. }
  199. //calculating indexes
  200. int i = 0;
  201. short[] indices = new short[nbSubSegments << 1];
  202. for (int j = 0; j < nbSubSegments; ++j) {
  203. indices[i++] = (short) j;
  204. indices[i++] = (short) (j + 1);
  205. }
  206. this.setMode(Mesh.Mode.Lines);
  207. this.setBuffer(VertexBuffer.Type.Position, 3, array);
  208. this.setBuffer(VertexBuffer.Type.Index, 2, indices);
  209. this.updateBound();
  210. this.updateCounts();
  211. }
  212. private void createLinearMesh() {
  213. float[] array = new float[spline.getControlPoints().size() * 3];
  214. short[] indices = new short[(spline.getControlPoints().size() - 1) * 2];
  215. int i = 0;
  216. int cpt = 0;
  217. int k = 0;
  218. int j = 0;
  219. for (Iterator<Vector3f> it = spline.getControlPoints().iterator(); it.hasNext();) {
  220. Vector3f vector3f = it.next();
  221. array[i] = vector3f.getX();
  222. i++;
  223. array[i] = vector3f.getY();
  224. i++;
  225. array[i] = vector3f.getZ();
  226. i++;
  227. if (it.hasNext()) {
  228. k = j;
  229. indices[cpt] = (short) k;
  230. cpt++;
  231. k++;
  232. indices[cpt] = (short) k;
  233. cpt++;
  234. j++;
  235. }
  236. }
  237. this.setMode(Mesh.Mode.Lines);
  238. this.setBuffer(VertexBuffer.Type.Position, 3, array);
  239. this.setBuffer(VertexBuffer.Type.Index, 2, indices);
  240. this.updateBound();
  241. this.updateCounts();
  242. }
  243. /**
  244. * This method returns the length of the curve.
  245. * @return the length of the curve
  246. */
  247. public float getLength() {
  248. return spline.getTotalLength();
  249. }
  250. }