If you think the Android project Schooner-3D listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
Java Source Code
/*
* Copyright 2012 Dan Mercer/*fromwww.java2s.com*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/package com.supermercerbros.gameengine.objects;
import android.util.Log;
import com.supermercerbros.gameengine.armature.Action;
import com.supermercerbros.gameengine.armature.ActionData;
import com.supermercerbros.gameengine.armature.BinarySkeletalVertexModifier;
import com.supermercerbros.gameengine.armature.SkeletalVertexModifier;
import com.supermercerbros.gameengine.armature.Skeleton;
import com.supermercerbros.gameengine.engine.shaders.Material;
import com.supermercerbros.gameengine.parsers.PreObjectData;
publicclass BonedObject extends GameObject {
publicstaticfinalint BONES_PER_VERTEX = 4;
publicfinalfloat[] boneWeights;
publicfinalbyte[] boneIndices;
privatefinal Skeleton skeleton;
private Action currentAction;
privatefinal ActionData actionData;
privatefinalint boneCount;
public BonedObject(PreObjectData data, Material material, Skeleton skeleton) {
super(data, material);
this.skeleton = skeleton;
finalint vertCount = info.count;
boneCount = skeleton.boneCount();
actionData = new ActionData(boneCount);
// Localize arrays
finalbyte[][] localIndices = data.boneIndices;
finalfloat[][] localWeights = data.boneWeights;
// Get largest number of bone weights per vertex
int vertexWeightCount = 0;
for (int i = 0; i < vertCount; i++) {
int weightCount = localWeights[i].length;
if (weightCount > vertexWeightCount) {
vertexWeightCount = weightCount;
}
}
Log.d(TAG, "vertexWeightCount = " + vertexWeightCount);
if (vertexWeightCount == 1) { // Single, binary weights
// Init boneIndices and boneWeights
this.boneIndices = newbyte[vertCount];
this.boneWeights = null;
// Fill boneIndices (boneWeights is unused)
for (int i = 0; i < vertCount; i++) {
this.boneIndices[i] = localIndices[i][0];
}
// Init VertexModifier and ActionData
material.setVertexModifier(new BinarySkeletalVertexModifier(boneCount));
} else { // Multiple weights.
if (vertexWeightCount > BONES_PER_VERTEX) {
Log.e(TAG, "At least one vertex has more than " + BONES_PER_VERTEX
+ " bones parented to it. Only " + BONES_PER_VERTEX
+ " are supported.");
vertexWeightCount = BONES_PER_VERTEX;
}
// Init boneIndices and boneWeights
this.boneIndices = newbyte[BONES_PER_VERTEX * vertCount];
this.boneWeights = newfloat[BONES_PER_VERTEX * vertCount];
// Fill boneIndices and boneWeights
for (int vert = 0; vert < vertCount; vert++) {
finalbyte[] vertIndices = localIndices[vert];
finalfloat[] vertWeights = localWeights[vert];
finalint boneCount = vertIndices.length;
finalint vertOffset = vert * 4;
for (int j = 0; j < vertexWeightCount && j < boneCount; j++) {
int offset = vertOffset + j;
boneIndices[offset] = vertIndices[j];
boneWeights[offset] = vertWeights[j];
}
}
// Init VertexModifier and ActionData
material.setVertexModifier(new SkeletalVertexModifier(BONES_PER_VERTEX,
boneCount));
}
}
/**
* Sets the Action of this BonedObject to the given Action
*
* @param action
* The Action to start.
* @param duration
* The duration of the Action, in milliseconds.
*/publicvoid setAction(Action action, long duration) {
if (action != null) {
finallong time = System.currentTimeMillis();
currentAction = action;
actionData.writeState(time, time, duration, skeleton);
// TODO: time, time? (add delay support to this method and to
// movements)
super.startMovement(action.movement, time, duration);
} else {
thrownew IllegalArgumentException("action == null");
}
}
@Override
publicvoid drawVerts(long time) {
if (currentAction != null) {
currentAction.update(actionData, skeleton, time);
}
}
@Override
publicint getExtraMatrixCount() {
return boneCount;
}
@Override
publicvoid writeMatrices(float[] matrixArray) {
super.writeMatrices(matrixArray);
skeleton.writeMatrices(matrixArray, 16);
}
}