| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- /*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- package jme3tools.converters.model;
- import com.jme3.bounding.BoundingBox;
- import com.jme3.math.Transform;
- import com.jme3.math.Vector2f;
- import com.jme3.math.Vector3f;
- import com.jme3.scene.Geometry;
- import com.jme3.scene.Mesh;
- import com.jme3.scene.VertexBuffer;
- import com.jme3.scene.VertexBuffer.Format;
- import com.jme3.scene.VertexBuffer.Type;
- import com.jme3.scene.VertexBuffer.Usage;
- import com.jme3.scene.mesh.IndexBuffer;
- import com.jme3.util.BufferUtils;
- import java.nio.*;
- @Deprecated
- public class FloatToFixed {
- private static final float shortSize = Short.MAX_VALUE - Short.MIN_VALUE;
- private static final float shortOff = (Short.MAX_VALUE + Short.MIN_VALUE) * 0.5f;
- private static final float byteSize = Byte.MAX_VALUE - Byte.MIN_VALUE;
- private static final float byteOff = (Byte.MAX_VALUE + Byte.MIN_VALUE) * 0.5f;
- @Deprecated
- public static void convertToFixed(Geometry geom, Format posFmt, Format nmFmt, Format tcFmt){
- geom.updateModelBound();
- BoundingBox bbox = (BoundingBox) geom.getModelBound();
- Mesh mesh = geom.getMesh();
- VertexBuffer positions = mesh.getBuffer(Type.Position);
- VertexBuffer normals = mesh.getBuffer(Type.Normal);
- VertexBuffer texcoords = mesh.getBuffer(Type.TexCoord);
- VertexBuffer indices = mesh.getBuffer(Type.Index);
- // positions
- FloatBuffer fb = (FloatBuffer) positions.getData();
- if (posFmt != Format.Float){
- Buffer newBuf = VertexBuffer.createBuffer(posFmt, positions.getNumComponents(),
- mesh.getVertexCount());
- Transform t = convertPositions(fb, bbox, newBuf);
- t.combineWithParent(geom.getLocalTransform());
- geom.setLocalTransform(t);
- VertexBuffer newPosVb = new VertexBuffer(Type.Position);
- newPosVb.setupData(positions.getUsage(),
- positions.getNumComponents(),
- posFmt,
- newBuf);
- mesh.clearBuffer(Type.Position);
- mesh.setBuffer(newPosVb);
- }
- // normals, automatically convert to signed byte
- fb = (FloatBuffer) normals.getData();
- ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity());
- convertNormals(fb, bb);
- normals = new VertexBuffer(Type.Normal);
- normals.setupData(Usage.Static, 3, Format.Byte, bb);
- normals.setNormalized(true);
- mesh.clearBuffer(Type.Normal);
- mesh.setBuffer(normals);
- // texcoords
- fb = (FloatBuffer) texcoords.getData();
- if (tcFmt != Format.Float){
- Buffer newBuf = VertexBuffer.createBuffer(tcFmt,
- texcoords.getNumComponents(),
- mesh.getVertexCount());
- convertTexCoords2D(fb, newBuf);
- VertexBuffer newTcVb = new VertexBuffer(Type.TexCoord);
- newTcVb.setupData(texcoords.getUsage(),
- texcoords.getNumComponents(),
- tcFmt,
- newBuf);
- mesh.clearBuffer(Type.TexCoord);
- mesh.setBuffer(newTcVb);
- }
- }
- public static void compressIndexBuffer(Mesh mesh){
- int vertCount = mesh.getVertexCount();
- VertexBuffer vb = mesh.getBuffer(Type.Index);
- Format targetFmt;
- if (vb.getFormat() == Format.UnsignedInt && vertCount <= 0xffff){
- if (vertCount <= 256)
- targetFmt = Format.UnsignedByte;
- else
- targetFmt = Format.UnsignedShort;
- }else if (vb.getFormat() == Format.UnsignedShort && vertCount <= 0xff){
- targetFmt = Format.UnsignedByte;
- }else{
- return;
- }
- IndexBuffer src = mesh.getIndexBuffer();
- Buffer newBuf = VertexBuffer.createBuffer(targetFmt, vb.getNumComponents(), src.size());
- VertexBuffer newVb = new VertexBuffer(Type.Index);
- newVb.setupData(vb.getUsage(), vb.getNumComponents(), targetFmt, newBuf);
- mesh.clearBuffer(Type.Index);
- mesh.setBuffer(newVb);
- IndexBuffer dst = mesh.getIndexBuffer();
- for (int i = 0; i < src.size(); i++){
- dst.put(i, src.get(i));
- }
- }
- private static void convertToFixed(FloatBuffer input, IntBuffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- input.clear();
- output.clear();
- for (int i = 0; i < input.capacity(); i++){
- output.put( (int) (input.get() * (float)(1<<16)) );
- }
- output.flip();
- }
- private static void convertToFloat(IntBuffer input, FloatBuffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- input.clear();
- output.clear();
- for (int i = 0; i < input.capacity(); i++){
- output.put( ((float)input.get() / (float)(1<<16)) );
- }
- output.flip();
- }
- private static void convertToUByte(FloatBuffer input, ByteBuffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- input.clear();
- output.clear();
- for (int i = 0; i < input.capacity(); i++){
- output.put( (byte) (input.get() * 255f) );
- }
- output.flip();
- }
- public static VertexBuffer convertToUByte(VertexBuffer vb){
- FloatBuffer fb = (FloatBuffer) vb.getData();
- ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity());
- convertToUByte(fb, bb);
- VertexBuffer newVb = new VertexBuffer(vb.getBufferType());
- newVb.setupData(vb.getUsage(),
- vb.getNumComponents(),
- Format.UnsignedByte,
- bb);
- newVb.setNormalized(true);
- return newVb;
- }
- public static VertexBuffer convertToFixed(VertexBuffer vb){
- if (vb.getFormat() == Format.Int)
- return vb;
- FloatBuffer fb = (FloatBuffer) vb.getData();
- IntBuffer ib = BufferUtils.createIntBuffer(fb.capacity());
- convertToFixed(fb, ib);
- VertexBuffer newVb = new VertexBuffer(vb.getBufferType());
- newVb.setupData(vb.getUsage(),
- vb.getNumComponents(),
- Format.Int,
- ib);
- return newVb;
- }
- public static VertexBuffer convertToFloat(VertexBuffer vb){
- if (vb.getFormat() == Format.Float)
- return vb;
- IntBuffer ib = (IntBuffer) vb.getData();
- FloatBuffer fb = BufferUtils.createFloatBuffer(ib.capacity());
- convertToFloat(ib, fb);
- VertexBuffer newVb = new VertexBuffer(vb.getBufferType());
- newVb.setupData(vb.getUsage(),
- vb.getNumComponents(),
- Format.Float,
- fb);
- return newVb;
- }
- private static void convertNormals(FloatBuffer input, ByteBuffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- input.clear();
- output.clear();
- Vector3f temp = new Vector3f();
- int vertexCount = input.capacity() / 3;
- for (int i = 0; i < vertexCount; i++){
- BufferUtils.populateFromBuffer(temp, input, i);
- // offset and scale vector into -128 ... 127
- temp.multLocal(127).addLocal(0.5f, 0.5f, 0.5f);
- // quantize
- byte v1 = (byte) temp.getX();
- byte v2 = (byte) temp.getY();
- byte v3 = (byte) temp.getZ();
- // store
- output.put(v1).put(v2).put(v3);
- }
- }
- private static void convertTexCoords2D(FloatBuffer input, Buffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- input.clear();
- output.clear();
- Vector2f temp = new Vector2f();
- int vertexCount = input.capacity() / 2;
- ShortBuffer sb = null;
- IntBuffer ib = null;
- if (output instanceof ShortBuffer)
- sb = (ShortBuffer) output;
- else if (output instanceof IntBuffer)
- ib = (IntBuffer) output;
- else
- throw new UnsupportedOperationException();
- for (int i = 0; i < vertexCount; i++){
- BufferUtils.populateFromBuffer(temp, input, i);
- if (sb != null){
- sb.put( (short) (temp.getX()*Short.MAX_VALUE) );
- sb.put( (short) (temp.getY()*Short.MAX_VALUE) );
- }else{
- int v1 = (int) (temp.getX() * ((float)(1 << 16)));
- int v2 = (int) (temp.getY() * ((float)(1 << 16)));
- ib.put(v1).put(v2);
- }
- }
- }
- private static Transform convertPositions(FloatBuffer input, BoundingBox bbox, Buffer output){
- if (output.capacity() < input.capacity())
- throw new RuntimeException("Output must be at least as large as input!");
- Vector3f offset = bbox.getCenter().negate();
- Vector3f size = new Vector3f(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent());
- size.multLocal(2);
- ShortBuffer sb = null;
- ByteBuffer bb = null;
- float dataTypeSize;
- float dataTypeOffset;
- if (output instanceof ShortBuffer){
- sb = (ShortBuffer) output;
- dataTypeOffset = shortOff;
- dataTypeSize = shortSize;
- }else{
- bb = (ByteBuffer) output;
- dataTypeOffset = byteOff;
- dataTypeSize = byteSize;
- }
- Vector3f scale = new Vector3f();
- scale.set(dataTypeSize, dataTypeSize, dataTypeSize).divideLocal(size);
- Vector3f invScale = new Vector3f();
- invScale.set(size).divideLocal(dataTypeSize);
- offset.multLocal(scale);
- offset.addLocal(dataTypeOffset, dataTypeOffset, dataTypeOffset);
- // offset = (-modelOffset * shortSize)/modelSize + shortOff
- // scale = shortSize / modelSize
- input.clear();
- output.clear();
- Vector3f temp = new Vector3f();
- int vertexCount = input.capacity() / 3;
- for (int i = 0; i < vertexCount; i++){
- BufferUtils.populateFromBuffer(temp, input, i);
- // offset and scale vector into -32768 ... 32767
- // or into -128 ... 127 if using bytes
- temp.multLocal(scale);
- temp.addLocal(offset);
- // quantize and store
- if (sb != null){
- short v1 = (short) temp.getX();
- short v2 = (short) temp.getY();
- short v3 = (short) temp.getZ();
- sb.put(v1).put(v2).put(v3);
- }else{
- byte v1 = (byte) temp.getX();
- byte v2 = (byte) temp.getY();
- byte v3 = (byte) temp.getZ();
- bb.put(v1).put(v2).put(v3);
- }
- }
- Transform transform = new Transform();
- transform.setTranslation(offset.negate().multLocal(invScale));
- transform.setScale(invScale);
- return transform;
- }
- }
|