/**
* Copyright (C) 2013 Gundog Studios LLC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.gundogstudios.models;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.FloatBuffer;
public class CombinedModel {
private static final int FLOAT_SIZE = 4;
private static final int CHAR_SIZE = 2;
private short[] indices;
private float[] uvs;
private float[][] idleVertices;
private float[][] moveVertices;
private float[][] attackVertices;
private float[][] deathVertices;
public CombinedModel(short[] indices, float[] uvs, float[][] idleVertices, float[][] moveVertices,
float[][] attackVertices, float[][] deathVertices) {
this.indices = indices;
this.uvs = uvs;
this.idleVertices = idleVertices;
this.moveVertices = moveVertices;
this.attackVertices = attackVertices;
this.deathVertices = deathVertices;
}
public void setIndices(short[] indices) {
this.indices = indices;
}
public void setIdleVertices(float[][] vertices) {
this.idleVertices = vertices;
}
public short[] getShortIndices() {
return indices;
}
public byte[] getByteIndices() {
if (indices == null)
return null;
byte[] bytes = new byte[indices.length * CHAR_SIZE];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
CharBuffer indexBuffer = byteBuffer.asCharBuffer();
for (int x = 0; x < indices.length; x++) {
indexBuffer.put((char) indices[x]);
}
indexBuffer.position(0);
return bytes;
}
public float[] getFloatUVs() {
return uvs;
}
public byte[] getByteUVs() {
if (uvs == null)
return null;
byte[] bytes = new byte[uvs.length * FLOAT_SIZE];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.put(uvs);
byteBuffer.position(0);
return bytes;
}
private byte[][] getByteVertices(float[][] floatVertices) {
if (floatVertices == null)
return null;
byte[][] byteVertices = new byte[floatVertices.length][];
for (int i = 0; i < byteVertices.length; i++) {
byteVertices[i] = new byte[floatVertices[i].length * FLOAT_SIZE];
ByteBuffer byteBuffer = ByteBuffer.wrap(byteVertices[i]).order(ByteOrder.LITTLE_ENDIAN);
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.put(floatVertices[i]);
byteBuffer.position(0);
}
return byteVertices;
}
public void flipZAxis() {
flipZAxis(idleVertices);
flipZAxis(moveVertices);
flipZAxis(deathVertices);
flipZAxis(attackVertices);
}
private void flipZAxis(float[][] vertices) {
if (vertices == null)
return;
for (float[] verts : vertices) {
for (int i = 0; i < verts.length; i += 3) {
verts[i] *= -1f;
}
}
}
public float[][] getFloatIdleVertices() {
return idleVertices;
}
public byte[][] getByteIdleVertices() {
return getByteVertices(idleVertices);
}
public float[][] getFloatMoveVertices() {
return moveVertices;
}
public byte[][] getByteMoveVertices() {
return getByteVertices(moveVertices);
}
public float[][] getFloatAttackVertices() {
return attackVertices;
}
public byte[][] getByteAttackVertices() {
return getByteVertices(attackVertices);
}
public float[][] getFloatDeathVertices() {
return deathVertices;
}
public byte[][] getByteDeathVertices() {
return getByteVertices(deathVertices);
}
public ReducedModel asReducedModel() {
char[] indices = convertIndices(getShortIndices());
// char[] uvs = convertUVs(getFloatUVs());
short[][] idleVertices = convertVertices(getFloatIdleVertices());
short[][] attackVertices = convertVertices(getFloatAttackVertices());
short[][] deathVertices = convertVertices(getFloatDeathVertices());
short[][] moveVertices = convertVertices(getFloatMoveVertices());
return new ReducedModel(indices, getFloatUVs(), idleVertices, moveVertices, attackVertices, deathVertices);
}
private char[] convertIndices(short[] indices) {
char[] newIndices = new char[indices.length];
for (int i = 0; i < indices.length; i++) {
newIndices[i] = (char) indices[i];
}
return newIndices;
}
// private char[] convertUVs(float[] uvs) {
// char[] newUVs = new char[uvs.length];
// for (int i = 0; i < uvs.length; i++) {
// newUVs[i] = (char) Math.round(uvs[i] * Short.MAX_VALUE);
// }
// return newUVs;
// }
private static float SCALE_MAX = 620.5913f;
private short[][] convertVertices(float[][] vertices) {
if (vertices == null) {
return null;
}
for (float[] arr : vertices) {
for (float f : arr) {
float tmp = Math.abs(f);
if (tmp > SCALE_MAX) {
System.err.println("Found new max scale: " + tmp);
}
}
}
short[][] newVertices = new short[vertices.length][];
for (int i = 0; i < vertices.length; i++) {
newVertices[i] = new short[vertices[i].length / 3 * 4];
int current = 0;
for (int j = 0; j < vertices[i].length; j++) {
newVertices[i][current] = (short) (vertices[i][j] / SCALE_MAX * Short.MAX_VALUE);
current++;
if (j % 3 == 2) {
// System.out.println(j);
newVertices[i][current] = 0;
current++;
}
// System.out.println(vertices[i][j]);
}
}
return newVertices;
}
}