159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.util;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.ColorRGBA;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Quaternion;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector2f;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.lang.reflect.InvocationTargetException;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.lang.reflect.Method;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.*;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Collections;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Map;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.WeakHashMap;
45a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport java.util.concurrent.atomic.AtomicBoolean;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>BufferUtils</code> is a helper class for generating nio buffers from
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * jME data classes such as Vectors and ColorRGBA.
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Joshua Slack
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @version $Id: BufferUtils.java,v 1.16 2007/10/29 16:56:18 nca Exp $
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic final class BufferUtils {
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Map<Buffer, Object> trackingHash = Collections.synchronizedMap(new WeakHashMap<Buffer, Object>());
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Object ref = new Object();
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // Note: a WeakHashMap is really bad here since the hashCode() and
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       equals() behavior of buffers will vary based on their contents.
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       As it stands, put()'ing an empty buffer will wipe out the last
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       empty buffer with the same size.  So any tracked memory calculations
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       could be lying.
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       Besides, the hashmap behavior isn't even being used here and
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       yet the expense is still incurred.  For example, a newly allocated
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       10,000 byte buffer will iterate through the whole buffer of 0's
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       to calculate the hashCode and then potentially do it again to
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       calculate the equals()... which by the way is guaranteed for
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       every empty buffer of an existing size since they will always produce
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       the same hashCode().
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       It would be better to just keep a straight list of weak references
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       and clean out the dead every time a new buffer is allocated.
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       WeakHashMap is doing that anyway... so there is no extra expense
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       incurred.
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       Recommend a ConcurrentLinkedQueue of WeakReferences since it
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //       supports the threading semantics required with little extra overhead.
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final boolean trackDirectMemory = false;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a clone of the given buffer. The clone's capacity is
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * equal to the given buffer's limit.
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf The buffer to clone
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The cloned buffer
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Buffer clone(Buffer buf) {
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf instanceof FloatBuffer) {
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return clone((FloatBuffer) buf);
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (buf instanceof ShortBuffer) {
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return clone((ShortBuffer) buf);
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (buf instanceof ByteBuffer) {
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return clone((ByteBuffer) buf);
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (buf instanceof IntBuffer) {
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return clone((IntBuffer) buf);
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (buf instanceof DoubleBuffer) {
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return clone((DoubleBuffer) buf);
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException();
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static void onBufferAllocated(Buffer buffer){
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        StackTraceElement[] stackTrace = new Throwable().getStackTrace();
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int initialIndex = 0;
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < stackTrace.length; i++){
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!stackTrace[i].getClassName().equals(BufferUtils.class.getName())){
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                initialIndex = i;
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int allocated = buffer.capacity();
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int size = 0;
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buffer instanceof FloatBuffer){
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            size = 4;
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (buffer instanceof ShortBuffer){
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            size = 2;
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (buffer instanceof ByteBuffer){
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            size = 1;
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (buffer instanceof IntBuffer){
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            size = 4;
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (buffer instanceof DoubleBuffer){
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            size = 8;
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        allocated *= size;
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = initialIndex; i < stackTrace.length; i++){
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            StackTraceElement element = stackTrace[i];
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (element.getClassName().startsWith("java")){
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try {
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Class clazz = Class.forName(element.getClassName());
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (i == initialIndex){
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    System.out.println(clazz.getSimpleName()+"."+element.getMethodName()+"():" + element.getLineNumber() + " allocated " + allocated);
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }else{
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    System.out.println(" at " + clazz.getSimpleName()+"."+element.getMethodName()+"()");
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } catch (ClassNotFoundException ex) {
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }*/
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (trackDirectMemory){
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            trackingHash.put(buffer, ref);
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generate a new FloatBuffer using the given array of Vector3f objects.
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The FloatBuffer will be 3 * data.length long and contain the vector data
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * as data[0].x, data[0].y, data[0].z, data[1].x... etc.
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data array of Vector3f objects to place into a new FloatBuffer
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createFloatBuffer(Vector3f... data) {
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer buff = createFloatBuffer(3 * data.length);
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < data.length; x++) {
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (data[x] != null) {
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(data[x].x).put(data[x].y).put(data[x].z);
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(0).put(0).put(0);
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generate a new FloatBuffer using the given array of Quaternion objects.
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The FloatBuffer will be 4 * data.length long and contain the vector data.
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data array of Quaternion objects to place into a new FloatBuffer
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createFloatBuffer(Quaternion... data) {
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer buff = createFloatBuffer(4 * data.length);
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < data.length; x++) {
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (data[x] != null) {
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(data[x].getX()).put(data[x].getY()).put(data[x].getZ()).put(data[x].getW());
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(0).put(0).put(0);
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generate a new FloatBuffer using the given array of float primitives.
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data array of float primitives to place into a new FloatBuffer
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createFloatBuffer(float... data) {
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer buff = createFloatBuffer(data.length);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.put(data);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new FloatBuffer of an appropriate size to hold the specified
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of Vector3f object data.
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vertices
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of vertices that need to be held by the newly created
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new FloatBuffer
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createVector3Buffer(int vertices) {
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer vBuff = createFloatBuffer(3 * vertices);
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return vBuff;
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new FloatBuffer of an appropriate size to hold the specified
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of Vector3f object data only if the given buffer if not already
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the right size.
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vertices
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of vertices that need to be held by the newly created
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new FloatBuffer
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createVector3Buffer(FloatBuffer buf, int vertices) {
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == 3 * vertices) {
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createFloatBuffer(3 * vertices);
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets the data contained in the given color into the FloatBuffer at the
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * specified index.
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param color
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the data to insert
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to insert into
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the postion to place the data; in terms of colors not floats
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void setInBuffer(ColorRGBA color, FloatBuffer buf,
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int index) {
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(index * 4);
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(color.r);
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(color.g);
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(color.b);
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(color.a);
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets the data contained in the given quaternion into the FloatBuffer at the
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * specified index.
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param quat
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the {@link Quaternion} to insert
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to insert into
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the postion to place the data; in terms of quaternions not floats
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void setInBuffer(Quaternion quat, FloatBuffer buf,
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int index) {
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(index * 4);
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(quat.getX());
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(quat.getY());
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(quat.getZ());
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(quat.getW());
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets the data contained in the given Vector3F into the FloatBuffer at the
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * specified index.
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vector
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the data to insert
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to insert into
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the postion to place the data; in terms of vectors not floats
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void setInBuffer(Vector3f vector, FloatBuffer buf, int index) {
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vector == null) {
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put(index * 3, 0);
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put((index * 3) + 1, 0);
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put((index * 3) + 2, 0);
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put(index * 3, vector.x);
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put((index * 3) + 1, vector.y);
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.put((index * 3) + 2, vector.z);
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Updates the values of the given vector from the specified buffer at the
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * index provided.
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vector
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to set data on
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to read from
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) to read from
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buf
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void populateFromBuffer(Vector3f vector, FloatBuffer buf, int index) {
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vector.x = buf.get(index * 3);
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vector.y = buf.get(index * 3 + 1);
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vector.z = buf.get(index * 3 + 2);
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generates a Vector3f array from the given FloatBuffer.
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buff
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the FloatBuffer to read from
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a newly generated array of Vector3f objects
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f[] getVector3Array(FloatBuffer buff) {
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f[] verts = new Vector3f[buff.limit() / 3];
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < verts.length; x++) {
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f v = new Vector3f(buff.get(), buff.get(), buff.get());
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            verts[x] = v;
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return verts;
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copies a Vector3f from one position in the buffer to another. The index
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * values are in terms of vector number (eg, vector number 0 is postions 0-2
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * in the FloatBuffer.)
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to copy from/to
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fromPos
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the index of the vector to copy
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toPos
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the index to copy the vector to
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void copyInternalVector3(FloatBuffer buf, int fromPos, int toPos) {
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copyInternal(buf, fromPos * 3, toPos * 3, 3);
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Normalize a Vector3f in-buffer.
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector3f within
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to normalize
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void normalizeVector3(FloatBuffer buf, int index) {
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempVec3 = vars.vect1;
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec3, buf, index);
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec3.normalizeLocal();
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec3, buf, index);
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add to a Vector3f in-buffer.
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toAdd
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to add from
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector3f within
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to add to
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void addInBuffer(Vector3f toAdd, FloatBuffer buf, int index) {
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempVec3 = vars.vect1;
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec3, buf, index);
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec3.addLocal(toAdd);
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec3, buf, index);
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Multiply and store a Vector3f in-buffer.
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toMult
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to multiply against
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector3f within
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to multiply
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void multInBuffer(Vector3f toMult, FloatBuffer buf, int index) {
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempVec3 = vars.vect1;
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec3, buf, index);
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec3.multLocal(toMult);
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec3, buf, index);
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Checks to see if the given Vector3f is equals to the data stored in the
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * buffer at the given data index.
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param check
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to check against - null will return false.
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to compare data with
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            in the buffer to check against
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static boolean equals(Vector3f check, FloatBuffer buf, int index) {
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempVec3 = vars.vect1;
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec3, buf, index);
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean eq = tempVec3.equals(check);
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return eq;
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // // -- VECTOR2F METHODS -- ////
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generate a new FloatBuffer using the given array of Vector2f objects.
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The FloatBuffer will be 2 * data.length long and contain the vector data
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * as data[0].x, data[0].y, data[1].x... etc.
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data array of Vector2f objects to place into a new FloatBuffer
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createFloatBuffer(Vector2f... data) {
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer buff = createFloatBuffer(2 * data.length);
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < data.length; x++) {
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (data[x] != null) {
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(data[x].x).put(data[x].y);
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buff.put(0).put(0);
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new FloatBuffer of an appropriate size to hold the specified
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of Vector2f object data.
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vertices
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of vertices that need to be held by the newly created
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new FloatBuffer
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createVector2Buffer(int vertices) {
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer vBuff = createFloatBuffer(2 * vertices);
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return vBuff;
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new FloatBuffer of an appropriate size to hold the specified
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of Vector2f object data only if the given buffer if not already
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the right size.
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vertices
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of vertices that need to be held by the newly created
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new FloatBuffer
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createVector2Buffer(FloatBuffer buf, int vertices) {
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == 2 * vertices) {
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createFloatBuffer(2 * vertices);
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets the data contained in the given Vector2F into the FloatBuffer at the
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * specified index.
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vector
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the data to insert
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to insert into
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the postion to place the data; in terms of vectors not floats
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void setInBuffer(Vector2f vector, FloatBuffer buf, int index) {
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(index * 2, vector.x);
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put((index * 2) + 1, vector.y);
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Updates the values of the given vector from the specified buffer at the
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * index provided.
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vector
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to set data on
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to read from
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) to read from
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buf
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void populateFromBuffer(Vector2f vector, FloatBuffer buf, int index) {
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vector.x = buf.get(index * 2);
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vector.y = buf.get(index * 2 + 1);
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generates a Vector2f array from the given FloatBuffer.
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buff
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the FloatBuffer to read from
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a newly generated array of Vector2f objects
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector2f[] getVector2Array(FloatBuffer buff) {
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector2f[] verts = new Vector2f[buff.limit() / 2];
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < verts.length; x++) {
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector2f v = new Vector2f(buff.get(), buff.get());
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            verts[x] = v;
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return verts;
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copies a Vector2f from one position in the buffer to another. The index
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * values are in terms of vector number (eg, vector number 0 is postions 0-1
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * in the FloatBuffer.)
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to copy from/to
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fromPos
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the index of the vector to copy
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toPos
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the index to copy the vector to
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void copyInternalVector2(FloatBuffer buf, int fromPos, int toPos) {
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copyInternal(buf, fromPos * 2, toPos * 2, 2);
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Normalize a Vector2f in-buffer.
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector2f within
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to normalize
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void normalizeVector2(FloatBuffer buf, int index) {
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector2f tempVec2 = vars.vect2d;
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec2, buf, index);
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec2.normalizeLocal();
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec2, buf, index);
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add to a Vector2f in-buffer.
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toAdd
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to add from
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector2f within
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to add to
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void addInBuffer(Vector2f toAdd, FloatBuffer buf, int index) {
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector2f tempVec2 = vars.vect2d;
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec2, buf, index);
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec2.addLocal(toAdd);
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec2, buf, index);
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Multiply and store a Vector2f in-buffer.
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toMult
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to multiply against
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to find the Vector2f within
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            to multiply
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void multInBuffer(Vector2f toMult, FloatBuffer buf, int index) {
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector2f tempVec2 = vars.vect2d;
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec2, buf, index);
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tempVec2.multLocal(toMult);
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setInBuffer(tempVec2, buf, index);
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Checks to see if the given Vector2f is equals to the data stored in the
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * buffer at the given data index.
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param check
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to check against - null will return false.
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to compare data with
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param index
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the position (in terms of vectors, not floats) of the vector
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            in the buffer to check against
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static boolean equals(Vector2f check, FloatBuffer buf, int index) {
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector2f tempVec2 = vars.vect2d;
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        populateFromBuffer(tempVec2, buf, index);
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean eq = tempVec2.equals(check);
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return eq;
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    ////  -- INT METHODS -- ////
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Generate a new IntBuffer using the given array of ints. The IntBuffer
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * will be data.length long and contain the int data as data[0], data[1]...
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * etc.
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            array of ints to place into a new IntBuffer
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static IntBuffer createIntBuffer(int... data) {
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IntBuffer buff = createIntBuffer(data.length);
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.put(data);
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new int[] array and populate it with the given IntBuffer's
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * contents.
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buff
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the IntBuffer to read from
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a new int array populated from the IntBuffer
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int[] getIntArray(IntBuffer buff) {
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buff == null) {
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int[] inds = new int[buff.limit()];
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < inds.length; x++) {
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inds[x] = buff.get();
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return inds;
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new float[] array and populate it with the given FloatBuffer's
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * contents.
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buff
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the FloatBuffer to read from
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a new float array populated from the FloatBuffer
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float[] getFloatArray(FloatBuffer buff) {
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buff == null) {
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float[] inds = new float[buff.limit()];
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x = 0; x < inds.length; x++) {
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inds[x] = buff.get();
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return inds;
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //// -- GENERAL DOUBLE ROUTINES -- ////
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new DoubleBuffer of the specified size.
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            required number of double to store.
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the new DoubleBuffer
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static DoubleBuffer createDoubleBuffer(int size) {
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DoubleBuffer buf = ByteBuffer.allocateDirect(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.clear();
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        onBufferAllocated(buf);
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new DoubleBuffer of an appropriate size to hold the specified
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of doubles only if the given buffer if not already the right size.
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of doubles that need to be held by the newly created
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new DoubleBuffer
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static DoubleBuffer createDoubleBuffer(DoubleBuffer buf, int size) {
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == size) {
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf = createDoubleBuffer(size);
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new DoubleBuffer with the same contents as the given
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * DoubleBuffer. The new DoubleBuffer is seperate from the old one and
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * changes are not reflected across. If you want to reflect changes,
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * consider using Buffer.duplicate().
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the DoubleBuffer to copy
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the copy
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static DoubleBuffer clone(DoubleBuffer buf) {
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.rewind();
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DoubleBuffer copy;
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf.isDirect()) {
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = createDoubleBuffer(buf.limit());
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = DoubleBuffer.allocate(buf.limit());
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copy.put(buf);
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return copy;
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //// -- GENERAL FLOAT ROUTINES -- ////
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new FloatBuffer of the specified size.
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            required number of floats to store.
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the new FloatBuffer
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer createFloatBuffer(int size) {
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.clear();
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        onBufferAllocated(buf);
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copies floats from one position in the buffer to another.
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to copy from/to
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fromPos
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the starting point to copy from
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param toPos
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the starting point to copy to
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param length
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the number of floats to copy
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void copyInternal(FloatBuffer buf, int fromPos, int toPos, int length) {
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float[] data = new float[length];
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(fromPos);
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.get(data);
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.position(toPos);
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.put(data);
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new FloatBuffer with the same contents as the given
81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * FloatBuffer. The new FloatBuffer is seperate from the old one and changes
81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * are not reflected across. If you want to reflect changes, consider using
81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Buffer.duplicate().
81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the FloatBuffer to copy
81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the copy
81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer clone(FloatBuffer buf) {
82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.rewind();
82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer copy;
82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf.isDirect()) {
82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = createFloatBuffer(buf.limit());
82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = FloatBuffer.allocate(buf.limit());
83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copy.put(buf);
83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return copy;
83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //// -- GENERAL INT ROUTINES -- ////
83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new IntBuffer of the specified size.
84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            required number of ints to store.
84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the new IntBuffer
84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static IntBuffer createIntBuffer(int size) {
84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IntBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.clear();
84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        onBufferAllocated(buf);
84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new IntBuffer of an appropriate size to hold the specified
85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of ints only if the given buffer if not already the right size.
85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of ints that need to be held by the newly created
86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new IntBuffer
86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static IntBuffer createIntBuffer(IntBuffer buf, int size) {
86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == size) {
86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf = createIntBuffer(size);
87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new IntBuffer with the same contents as the given IntBuffer.
87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The new IntBuffer is seperate from the old one and changes are not
87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * reflected across. If you want to reflect changes, consider using
87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Buffer.duplicate().
87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the IntBuffer to copy
88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the copy
88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static IntBuffer clone(IntBuffer buf) {
88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.rewind();
88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IntBuffer copy;
89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf.isDirect()) {
89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = createIntBuffer(buf.limit());
89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = IntBuffer.allocate(buf.limit());
89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copy.put(buf);
89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return copy;
89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //// -- GENERAL BYTE ROUTINES -- ////
90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new ByteBuffer of the specified size.
90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            required number of ints to store.
90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the new IntBuffer
90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer createByteBuffer(int size) {
90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.clear();
91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        onBufferAllocated(buf);
91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new ByteBuffer of an appropriate size to hold the specified
91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of ints only if the given buffer if not already the right size.
91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of bytes that need to be held by the newly created
92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new IntBuffer
92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer createByteBuffer(ByteBuffer buf, int size) {
92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == size) {
92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf = createByteBuffer(size);
93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer createByteBuffer(byte... data) {
93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer bb = createByteBuffer(data.length);
93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        bb.put(data);
93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        bb.flip();
94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return bb;
94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer createByteBuffer(String data) {
94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        byte[] bytes = data.getBytes();
94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer bb = createByteBuffer(bytes.length);
94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        bb.put(bytes);
94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        bb.flip();
94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return bb;
94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new ByteBuffer with the same contents as the given ByteBuffer.
95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The new ByteBuffer is seperate from the old one and changes are not
95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * reflected across. If you want to reflect changes, consider using
95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Buffer.duplicate().
95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the ByteBuffer to copy
95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the copy
96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer clone(ByteBuffer buf) {
96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.rewind();
96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer copy;
96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf.isDirect()) {
96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = createByteBuffer(buf.limit());
97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = ByteBuffer.allocate(buf.limit());
97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copy.put(buf);
97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return copy;
97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //// -- GENERAL SHORT ROUTINES -- ////
97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new ShortBuffer of the specified size.
98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            required number of shorts to store.
98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the new ShortBuffer
98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ShortBuffer createShortBuffer(int size) {
98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ShortBuffer buf = ByteBuffer.allocateDirect(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
98859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.clear();
98959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        onBufferAllocated(buf);
99059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
99159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
99259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
99359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
99459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Create a new ShortBuffer of an appropriate size to hold the specified
99559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number of shorts only if the given buffer if not already the right size.
99659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
99759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
99859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to first check and rewind
99959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param size
100059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            number of shorts that need to be held by the newly created
100159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            buffer
100259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the requested new ShortBuffer
100359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
100459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ShortBuffer createShortBuffer(ShortBuffer buf, int size) {
100559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf != null && buf.limit() == size) {
100659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buf.rewind();
100759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return buf;
100859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
100959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf = createShortBuffer(size);
101159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buf;
101259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
101359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ShortBuffer createShortBuffer(short... data) {
101559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
101659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
101759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
101859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ShortBuffer buff = createShortBuffer(data.length);
101959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.clear();
102059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.put(data);
102159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buff.flip();
102259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buff;
102359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
102459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
102659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new ShortBuffer with the same contents as the given ShortBuffer.
102759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The new ShortBuffer is seperate from the old one and changes are not
102859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * reflected across. If you want to reflect changes, consider using
102959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Buffer.duplicate().
103059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
103159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buf
103259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the ShortBuffer to copy
103359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the copy
103459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
103559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ShortBuffer clone(ShortBuffer buf) {
103659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf == null) {
103759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
103859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
103959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        buf.rewind();
104059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
104159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ShortBuffer copy;
104259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buf.isDirect()) {
104359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = createShortBuffer(buf.limit());
104459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
104559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            copy = ShortBuffer.allocate(buf.limit());
104659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
104759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copy.put(buf);
104859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
104959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return copy;
105059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
105159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
105259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
105359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Ensures there is at least the <code>required</code> number of entries left after the current position of the
105459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * buffer. If the buffer is too small a larger one is created and the old one copied to the new buffer.
105559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param buffer buffer that should be checked/copied (may be null)
105659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param required minimum number of elements that should be remaining in the returned buffer
105759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a buffer large enough to receive at least the <code>required</code> number of entries, same position as
105859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the input buffer, not null
105959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
106059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static FloatBuffer ensureLargeEnough(FloatBuffer buffer, int required) {
106159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buffer == null || (buffer.remaining() < required)) {
106259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int position = (buffer != null ? buffer.position() : 0);
106359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            FloatBuffer newVerts = createFloatBuffer(position + required);
106459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (buffer != null) {
106559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buffer.rewind();
106659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.put(buffer);
106759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.position(position);
106859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
106959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buffer = newVerts;
107059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
107159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buffer;
107259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
107359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
107459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ShortBuffer ensureLargeEnough(ShortBuffer buffer, int required) {
107559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buffer == null || (buffer.remaining() < required)) {
107659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int position = (buffer != null ? buffer.position() : 0);
107759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ShortBuffer newVerts = createShortBuffer(position + required);
107859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (buffer != null) {
107959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buffer.rewind();
108059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.put(buffer);
108159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.position(position);
108259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
108359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buffer = newVerts;
108459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
108559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buffer;
108659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
108759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
108859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static ByteBuffer ensureLargeEnough(ByteBuffer buffer, int required) {
108959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (buffer == null || (buffer.remaining() < required)) {
109059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int position = (buffer != null ? buffer.position() : 0);
109159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ByteBuffer newVerts = createByteBuffer(position + required);
109259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (buffer != null) {
109359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                buffer.rewind();
109459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.put(buffer);
109559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                newVerts.position(position);
109659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
109759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            buffer = newVerts;
109859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
109959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return buffer;
110059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
110159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
110259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void printCurrentDirectMemory(StringBuilder store) {
110359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        long totalHeld = 0;
110459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // make a new set to hold the keys to prevent concurrency issues.
110559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ArrayList<Buffer> bufs = new ArrayList<Buffer>(trackingHash.keySet());
110659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int fBufs = 0, bBufs = 0, iBufs = 0, sBufs = 0, dBufs = 0;
110759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int fBufsM = 0, bBufsM = 0, iBufsM = 0, sBufsM = 0, dBufsM = 0;
110859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (Buffer b : bufs) {
110959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (b instanceof ByteBuffer) {
111059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                totalHeld += b.capacity();
111159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bBufsM += b.capacity();
111259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bBufs++;
111359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (b instanceof FloatBuffer) {
111459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                totalHeld += b.capacity() * 4;
111559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fBufsM += b.capacity() * 4;
111659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fBufs++;
111759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (b instanceof IntBuffer) {
111859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                totalHeld += b.capacity() * 4;
111959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iBufsM += b.capacity() * 4;
112059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iBufs++;
112159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (b instanceof ShortBuffer) {
112259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                totalHeld += b.capacity() * 2;
112359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sBufsM += b.capacity() * 2;
112459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sBufs++;
112559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (b instanceof DoubleBuffer) {
112659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                totalHeld += b.capacity() * 8;
112759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                dBufsM += b.capacity() * 8;
112859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                dBufs++;
112959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
113059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
113159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        long heapMem = Runtime.getRuntime().totalMemory()
113259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                - Runtime.getRuntime().freeMemory();
113359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
113459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean printStout = store == null;
113559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
113659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new StringBuilder();
113759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
113859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.append("Existing buffers: ").append(bufs.size()).append("\n");
113959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.append("(b: ").append(bBufs).append("  f: ").append(fBufs).append("  i: ").append(iBufs).append("  s: ").append(sBufs).append("  d: ").append(dBufs).append(")").append("\n");
114059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.append("Total   heap memory held: ").append(heapMem / 1024).append("kb\n");
114159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.append("Total direct memory held: ").append(totalHeld / 1024).append("kb\n");
114259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.append("(b: ").append(bBufsM / 1024).append("kb  f: ").append(fBufsM / 1024).append("kb  i: ").append(iBufsM / 1024).append("kb  s: ").append(sBufsM / 1024).append("kb  d: ").append(dBufsM / 1024).append("kb)").append("\n");
114359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (printStout) {
114459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            System.out.println(store.toString());
114559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
114659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
114759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1148a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static final AtomicBoolean loadedMethods = new AtomicBoolean(false);
1149a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static Method cleanerMethod = null;
1150a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static Method cleanMethod = null;
1151a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static Method viewedBufferMethod = null;
1152a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static Method freeMethod = null;
1153a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
1154a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static Method loadMethod(String className, String methodName){
1155a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        try {
1156a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            Method method = Class.forName(className).getMethod(methodName);
1157a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            method.setAccessible(true);
1158a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            return method;
1159a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        } catch (NoSuchMethodException ex) {
1160a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            return null; // the method was not found
1161a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        } catch (SecurityException ex) {
1162a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            return null; // setAccessible not allowed by security policy
1163a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        } catch (ClassNotFoundException ex) {
1164a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            return null; // the direct buffer implementation was not found
1165a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        }
1166a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    }
1167a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
1168a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    private static void loadCleanerMethods() {
1169a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        // If its already true, exit, if not, set it to true.
1170a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        if (loadedMethods.getAndSet(true)) {
1171a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            return;
1172a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        }
1173a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        // This could potentially be called many times if used from multiple
1174a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        // threads
1175a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        synchronized (loadedMethods) {
1176a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            // Oracle JRE / OpenJDK
1177a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
1178a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
1179a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
1180a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
1181a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            // Apache Harmony
1182a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            freeMethod = loadMethod("org.apache.harmony.nio.internal.DirectBuffer", "free");
1183a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
1184a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            // GUN Classpath (not likely)
1185a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            //finalizeMethod = loadMethod("java.nio.DirectByteBufferImpl", "finalize");
1186a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        }
1187a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    }
1188a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
118959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
119059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * Direct buffers are garbage collected by using a phantom reference and a
119159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * reference queue. Every once a while, the JVM checks the reference queue and
119259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * cleans the direct buffers. However, as this doesn't happen
119359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * immediately after discarding all references to a direct buffer, it's
119459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * easy to OutOfMemoryError yourself using direct buffers. This function
119559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * explicitly calls the Cleaner method of a direct buffer.
119659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    *
119759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    * @param toBeDestroyed
119859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    *          The direct buffer that will be "cleaned". Utilizes reflection.
119959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    *
120059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    */
120159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void destroyDirectBuffer(Buffer toBeDestroyed) {
120259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!toBeDestroyed.isDirect()) {
120359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
120459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
1205a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
1206a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        loadCleanerMethods();
1207a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
120859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try {
1209a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            if (freeMethod != null) {
1210a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                freeMethod.invoke(toBeDestroyed);
121159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
1212a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                Object cleaner = cleanerMethod.invoke(toBeDestroyed);
1213a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                if (cleaner != null) {
1214a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    cleanMethod.invoke(cleaner);
121559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
1216a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    // Try the alternate approach of getting the viewed buffer first
1217a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    Object viewedBuffer = viewedBufferMethod.invoke(toBeDestroyed);
1218a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    if (viewedBuffer != null) {
1219a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        destroyDirectBuffer((Buffer) viewedBuffer);
1220a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    } else {
1221a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "Buffer cannot be destroyed: {0}", toBeDestroyed);
1222a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    }
122359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
122459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
122559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (IllegalAccessException ex) {
122659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
122759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (IllegalArgumentException ex) {
122859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
122959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (InvocationTargetException ex) {
123059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
123159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (SecurityException ex) {
123259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
123359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
123459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
123559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
1236