/src/org/mt4j/util/math/ToolsBuffers.java

http://mt4j.googlecode.com/ · Java · 543 lines · 244 code · 51 blank · 248 comment · 37 complexity · 005e0346543124d409be68b9a4392eb0 MD5 · raw file

  1. /***********************************************************************
  2. * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. ***********************************************************************/
  18. package org.mt4j.util.math;
  19. import java.nio.ByteBuffer;
  20. import java.nio.ByteOrder;
  21. import java.nio.FloatBuffer;
  22. import java.nio.IntBuffer;
  23. /**
  24. * Methods to build Buffers for use with vertex/texture/color arrays in opengl
  25. * Some methods are adapted from the JME.
  26. *
  27. * @author C.Ruff
  28. */
  29. public class ToolsBuffers {
  30. ////////////////////////////////////////////////////////////
  31. // Methods to build Buffers for use with vertex/texture/color arrays in opengl
  32. //////////////////////////////////////////////////////
  33. /**
  34. * Generate vertex buffer.
  35. *
  36. * @param vertices the vertices
  37. *
  38. * @return the float buffer
  39. */
  40. public static FloatBuffer generateVertexBuffer(Vector3D[] vertices){
  41. float[] xyz;
  42. int vertixCount = vertices.length;
  43. xyz = new float[vertixCount*3];
  44. for (int i = 0; i < vertixCount; i++) {
  45. xyz[i*3] = vertices[i].getX();
  46. xyz[i*3+1]= vertices[i].getY();
  47. xyz[i*3+2]= vertices[i].getZ();
  48. }
  49. FloatBuffer vertBuff = createFloatBuffer(xyz.length);
  50. vertBuff.put(xyz);
  51. vertBuff.rewind();
  52. return vertBuff;
  53. }
  54. /**
  55. * Generate color buffer.
  56. *
  57. * @param vertices the vertices
  58. *
  59. * @return the float buffer
  60. */
  61. public static FloatBuffer generateColorBuffer(Vertex[] vertices){
  62. float[] rgb;
  63. int vertexCount = vertices.length;
  64. rgb = new float[vertexCount*4];
  65. for (int i = 0; i < vertexCount; i++) {
  66. rgb[i*4]= vertices[i].getR()/255f;
  67. rgb[i*4+1]= vertices[i].getG()/255f;
  68. rgb[i*4+2]= vertices[i].getB()/255f;
  69. rgb[i*4+3]= vertices[i].getA()/255f;
  70. }
  71. FloatBuffer colorBuff = createFloatBuffer(rgb.length);
  72. colorBuff.put(rgb);
  73. colorBuff.rewind();
  74. return colorBuff;
  75. }
  76. /**
  77. * Update color buffer.
  78. *
  79. * @param v the v
  80. * @param buf the buf
  81. */
  82. public static void updateColorBuffer(Vertex[] v, FloatBuffer buf){
  83. buf.rewind();
  84. for (int i = 0; i < v.length; i++) {
  85. buf.put(i * 4 , v[i].getR()/255f);
  86. buf.put((i * 4) + 1, v[i].getG()/255f);
  87. buf.put((i * 4) + 2, v[i].getB()/255f);
  88. buf.put((i * 4) + 3, v[i].getA()/255f);
  89. }
  90. buf.clear();
  91. }
  92. /**
  93. * Generate stroke color buffer.
  94. *
  95. * @param vertexCount the vertex count
  96. * @param r the r
  97. * @param g the g
  98. * @param b the b
  99. * @param a the a
  100. *
  101. * @return the float buffer
  102. */
  103. public static FloatBuffer generateStrokeColorBuffer(int vertexCount, float r, float g, float b, float a){
  104. float[] rgb;
  105. rgb = new float[vertexCount*4];
  106. for (int i = 0; i < vertexCount; i++) {
  107. rgb[i*4]= r/255;
  108. rgb[i*4+1]= g/255;
  109. rgb[i*4+2]= b/255;
  110. rgb[i*4+3]= a/255;
  111. }
  112. FloatBuffer strokeColBuff = createFloatBuffer(rgb.length);
  113. strokeColBuff.put(rgb);
  114. strokeColBuff.rewind();
  115. return strokeColBuff;
  116. }
  117. /**
  118. * Update stroke color buffer.
  119. *
  120. * @param buf the buf
  121. * @param r the r
  122. * @param g the g
  123. * @param b the b
  124. * @param a the a
  125. */
  126. public static void updateStrokeColorBuffer(FloatBuffer buf, float r, float g, float b, float a){
  127. float rr = r/255f;
  128. float gg = g/255f;
  129. float bb = b/255f;
  130. float aa = a/255f;
  131. buf.rewind();
  132. while(buf.hasRemaining()){
  133. buf.put(rr);
  134. buf.put(gg);
  135. buf.put(bb);
  136. buf.put(aa);
  137. }
  138. buf.clear();
  139. }
  140. /**
  141. * Generate texture buffer.
  142. *
  143. * @param vertices the vertices
  144. *
  145. * @return the float buffer
  146. */
  147. public static FloatBuffer generateTextureBuffer(Vertex[] vertices){
  148. float[] textureCoords;
  149. int vertixCount = vertices.length;
  150. textureCoords = new float[vertixCount*2];
  151. for (int i = 0; i < vertixCount; i++) {
  152. Vertex vertex = vertices[i];
  153. textureCoords[i*2]= vertex.getTexCoordU();
  154. textureCoords[i*2+1]= vertex.getTexCoordV();
  155. }
  156. FloatBuffer tBuffer = createFloatBuffer(textureCoords.length);
  157. tBuffer.put(textureCoords);
  158. tBuffer.rewind();
  159. return tBuffer;
  160. }
  161. /**
  162. * Generate normals buffer.
  163. *
  164. * @param normals the normals
  165. *
  166. * @return the float buffer
  167. */
  168. public static FloatBuffer generateNormalsBuffer(Vector3D[] normals){
  169. return generateVertexBuffer(normals);
  170. /*
  171. float[] xyz;
  172. int normalsCount = normals.length;
  173. xyz = new float[normalsCount*3];
  174. for (int i = 0; i < normalsCount; i++) {
  175. xyz[i*3] = normals[i].getX();
  176. xyz[i*3+1]= normals[i].getY();
  177. xyz[i*3+2]= normals[i].getZ();
  178. }
  179. FloatBuffer normalsBuff = createFloatBuffer(xyz.length);
  180. normalsBuff.put(xyz);
  181. normalsBuff.rewind();
  182. return normalsBuff;
  183. */
  184. }
  185. /**
  186. * Generate indices buffer.
  187. *
  188. * @param indicesArray the indices array
  189. *
  190. * @return the int buffer
  191. */
  192. public static IntBuffer generateIndicesBuffer(int[] indicesArray){
  193. IntBuffer indexBuff = createIntBuffer(indicesArray.length);
  194. indexBuff.put(indicesArray);
  195. indexBuff.rewind();
  196. return indexBuff;
  197. }
  198. /**
  199. * Sets the data contained in the given Vector3D into the FloatBuffer at the
  200. * specified index. Should work with vector and vertex.
  201. *
  202. * @param vector the data to insert
  203. * @param buf the buffer to insert into
  204. * @param index the postion to place the data; in terms of vectors not floats
  205. */
  206. public static void setInBuffer(Vector3D vector, FloatBuffer buf, int index) {
  207. if (buf == null) {
  208. return;
  209. }
  210. if (vector == null) {
  211. buf.put(index * 3, 0);
  212. buf.put((index * 3) + 1, 0);
  213. buf.put((index * 3) + 2, 0);
  214. } else {
  215. buf.put(index * 3, vector.x);
  216. buf.put((index * 3) + 1, vector.y);
  217. buf.put((index * 3) + 2, vector.z);
  218. }
  219. }
  220. public static void setInBuffer(float x, float y, float z, FloatBuffer buf, int index) {
  221. if (buf == null) {
  222. return;
  223. }
  224. buf.put(index * 3, x);
  225. buf.put((index * 3) + 1, y);
  226. buf.put((index * 3) + 2, z);
  227. }
  228. /**
  229. * Sets the data contained in the given Vector into the FloatBuffer at the
  230. * specified index. Should work with vector and vertex.
  231. *
  232. * @param vector the data to insert
  233. * @param buf the buffer to insert into
  234. * @param index the postion to place the data; in terms of vectors not floats
  235. */
  236. public static void setInBuffer(float[] vector, FloatBuffer buf, int index) {
  237. if (buf == null) {
  238. return;
  239. }
  240. buf.put(index * 3, vector[0]);
  241. buf.put((index * 3) + 1, vector[1]);
  242. buf.put((index * 3) + 2, vector[2]);
  243. }
  244. /**
  245. * Generates a Vector3D array from the given FloatBuffer.
  246. *
  247. * @param buff the FloatBuffer to read from
  248. *
  249. * @return a newly generated array of Vector3D objects
  250. */
  251. public static Vector3D[] getVector3DArray(FloatBuffer buff) {
  252. buff.clear(); //this doesent delete its contents!
  253. Vector3D[] verts = new Vector3D[buff.limit() / 3];
  254. for (int x = 0; x < verts.length; x++) {
  255. Vector3D v = new Vector3D(buff.get(), buff.get(), buff.get());
  256. verts[x] = v;
  257. }
  258. buff.clear(); //Reset position to 0 again
  259. return verts;
  260. }
  261. /**
  262. * Generates a Vector3D array from the given FloatBuffer.
  263. *
  264. * @param buff the FloatBuffer to read from
  265. *
  266. * @return a newly generated array of Vector3D objects
  267. */
  268. public static float[][] getRGBAColorArray(FloatBuffer buff) {
  269. buff.rewind(); //this doesent delete its contents!
  270. float[][] colorArray = new float[buff.limit() / 4][4];
  271. for (int x = 0; x < colorArray.length; x++) {
  272. colorArray[x][0] = buff.get();
  273. colorArray[x][1] = buff.get();
  274. colorArray[x][2] = buff.get();
  275. colorArray[x][3] = buff.get();
  276. }
  277. buff.clear(); //Reset position to 0 again
  278. return colorArray;
  279. }
  280. /**
  281. * Generates a Vector3f array from the given FloatBuffer.
  282. *
  283. * @param buff the FloatBuffer to read from
  284. *
  285. * @return a newly generated array of Vector3D objects
  286. */
  287. public static Vertex[] getVertexArray(FloatBuffer buff) {
  288. buff.clear(); //Dosent delete its contents!
  289. Vertex[] verts = new Vertex[buff.limit() / 3];
  290. for (int x = 0; x < verts.length; x++) {
  291. Vertex v = new Vertex(buff.get(), buff.get(), buff.get());
  292. verts[x] = v;
  293. }
  294. buff.clear(); //Reset position to 0 again
  295. return verts;
  296. }
  297. /**
  298. * Create a new int[] array and populates
  299. * it with the given IntBuffer's contents.
  300. *
  301. * @param buff the IntBuffer to read from
  302. *
  303. * @return a new int array populated from the IntBuffer
  304. */
  305. public static int[] getIntArray(IntBuffer buff) {
  306. if (buff == null) return null;
  307. buff.clear();
  308. int[] inds = new int[buff.limit()];
  309. for (int x = 0; x < inds.length; x++) {
  310. inds[x] = buff.get();
  311. }
  312. buff.clear(); //Reset position to 0 again
  313. return inds;
  314. }
  315. /**
  316. * Create a new float[] array and populate it with the given FloatBuffer's
  317. * contents.
  318. *
  319. * @param buff the FloatBuffer to read from
  320. *
  321. * @return a new float array populated from the FloatBuffer
  322. */
  323. public static float[] getFloatArray(FloatBuffer buff) {
  324. if (buff == null) return null;
  325. buff.clear();
  326. float[] inds = new float[buff.limit()];
  327. for (int x = 0; x < inds.length; x++) {
  328. inds[x] = buff.get();
  329. }
  330. buff.clear(); //Reset position to 0 again
  331. return inds;
  332. }
  333. /**
  334. * Creates a new FloatBuffer with the same contents as the given
  335. * FloatBuffer. The new FloatBuffer is seperate from the old one and changes
  336. * are not reflected across. If you want to reflect changes, consider using
  337. * Buffer.duplicate().
  338. *
  339. * @param buf the FloatBuffer to copy
  340. *
  341. * @return the copy
  342. */
  343. public static FloatBuffer clone(FloatBuffer buf) {
  344. if (buf == null) return null;
  345. buf.rewind();
  346. FloatBuffer copy = createFloatBuffer(buf.limit());
  347. copy.put(buf);
  348. return copy;
  349. }
  350. /**
  351. * Creates a new IntBuffer with the same contents as the given IntBuffer.
  352. * The new IntBuffer is seperate from the old one and changes are not
  353. * reflected across. If you want to reflect changes, consider using
  354. * Buffer.duplicate().
  355. *
  356. * @param buf the IntBuffer to copy
  357. *
  358. * @return the copy
  359. */
  360. public static IntBuffer clone(IntBuffer buf) {
  361. if (buf == null) return null;
  362. buf.rewind();
  363. IntBuffer copy = createIntBuffer(buf.limit());
  364. copy.put(buf);
  365. return copy;
  366. }
  367. /**
  368. * Ensures there is at least the <code>required</code> number of entries left after the current position of the
  369. * buffer. If the buffer is too small a larger one is created and the old one copied to the new buffer.
  370. *
  371. * @param buffer buffer that should be checked/copied (may be null)
  372. * @param required minimum number of elements that should be remaining in the returned buffer
  373. *
  374. * @return a buffer large enough to receive at least the <code>required</code> number of entries, same position as
  375. * the input buffer, not null
  376. */
  377. public static FloatBuffer ensureLargeEnough( FloatBuffer buffer, int required ) {
  378. if ( buffer == null || ( buffer.remaining() < required ) ) {
  379. int position = ( buffer != null ? buffer.position() : 0 );
  380. FloatBuffer newVerts = createFloatBuffer( position + required );
  381. if ( buffer != null ) {
  382. buffer.rewind();
  383. newVerts.put( buffer );
  384. newVerts.position( position );
  385. }
  386. buffer = newVerts;
  387. }
  388. return buffer;
  389. }
  390. /**
  391. * Create a new ByteBuffer of an appropriate size to hold the specified
  392. * number of ints only if the given buffer if not already the right size.
  393. *
  394. * @param buf the buffer to first check and rewind
  395. * @param size number of bytes that need to be held by the newly created
  396. * buffer
  397. *
  398. * @return the requested new IntBuffer
  399. */
  400. public static ByteBuffer createByteBuffer(ByteBuffer buf, int size) {
  401. if (buf != null && buf.limit() == size) {
  402. buf.rewind();
  403. return buf;
  404. }
  405. buf = createByteBuffer(size);
  406. return buf;
  407. }
  408. /**
  409. * Create a new empty FloatBuffer of the specified size.
  410. *
  411. * @param size required number of floats to store.
  412. *
  413. * @return the new FloatBuffer
  414. */
  415. public static FloatBuffer createFloatBuffer(int size) {
  416. FloatBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
  417. buf.clear();
  418. return buf;
  419. }
  420. /**
  421. * Create a new FloatBuffer of an appropriate size to hold the specified
  422. * number of Vector3D object data.
  423. *
  424. * @param vertices
  425. * number of vertices that need to be held by the newly created
  426. * buffer
  427. * @return the requested new FloatBuffer
  428. */
  429. public static FloatBuffer createVector3Buffer(int vertices) {
  430. return createFloatBuffer(3 * vertices);
  431. }
  432. /**
  433. * Create a new IntBuffer of the specified size.
  434. *
  435. * @param size required number of ints to store.
  436. *
  437. * @return the new IntBuffer
  438. */
  439. public static IntBuffer createIntBuffer(int size) {
  440. IntBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
  441. buf.clear();
  442. return buf;
  443. }
  444. /**
  445. * Create a new ByteBuffer of the specified size.
  446. *
  447. * @param size required number of ints to store.
  448. *
  449. * @return the new IntBuffer
  450. */
  451. public static ByteBuffer createByteBuffer(int size) {
  452. ByteBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
  453. buf.clear();
  454. return buf;
  455. }
  456. /**
  457. * Updates the values of the given vector from the specified buffer at the
  458. * index provided.
  459. *
  460. * @param vector
  461. * the vector to set data on
  462. * @param buf
  463. * the buffer to read from
  464. * @param index
  465. * the position (in terms of vectors, not floats) to read from
  466. * the buf
  467. */
  468. public static void populateFromBuffer(Vector3D vector, FloatBuffer buf, int index) {
  469. vector.x = buf.get(index*3);
  470. vector.y = buf.get(index*3+1);
  471. vector.z = buf.get(index*3+2);
  472. }
  473. /**
  474. * Copies floats from one position in the buffer to another.
  475. *
  476. * @param buf
  477. * the buffer to copy from/to
  478. * @param fromPos
  479. * the starting point to copy from
  480. * @param toPos
  481. * the starting point to copy to
  482. * @param length
  483. * the number of floats to copy
  484. */
  485. public static void copyInternal(FloatBuffer buf, int fromPos, int toPos, int length) {
  486. float[] data = new float[length];
  487. buf.position(fromPos);
  488. buf.get(data);
  489. buf.position(toPos);
  490. buf.put(data);
  491. }
  492. }