PageRenderTime 37ms CodeModel.GetById 10ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

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