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.armature;
import java.util.Locale;
import android.opengl.GLES20;
import com.supermercerbros.gameengine.engine.shaders.Material;
import com.supermercerbros.gameengine.engine.shaders.Program;
import com.supermercerbros.gameengine.engine.shaders.VertexModifier;
import com.supermercerbros.gameengine.objects.BonedObject;
import com.supermercerbros.gameengine.objects.GameObject;
publicclass SkeletalVertexModifier extends VertexModifier {
// METHODS
privatestaticfinal String METHOD_SKIN_POS =
"void skin_pos(in vec4 inPos, in float weight, in int index, inout vec3 outPos, inout float weight_sum) {\n" +
" outPos += (u_matrices[index] * inPos).xyz * weight;\n" +
" weight_sum += weight;\n" +
"}\n";
privatestaticfinal String METHOD_SKIN_NORMAL =
"void skin_normal(in vec4 inNormal, in float weight, in int index, inout vec3 outNormal, inout float weight_sum) {\n" +
" outNormal += (u_matrices[index] * inNormal).xyz * weight;\n" +
" weight_sum += weight;\n" +
"}\n";
// METHOD CALLS
privatestaticfinal String SKIN_POS = "skin_pos(a_pos4, m_weight, m_index, mod_pos, m_weight_sum);\n";
privatestaticfinal String SKIN_NORMAL = "skin_normal(a_normal4, m_weight, m_index, mod_normal, m_weight_sum);\n";
// VARIABLES
privatestaticfinal String VARS =
"uniform mat4 u_matrices[%d];\n" +
"attribute vec4 a_indices;\n" +
"attribute vec4 a_weights;\n";
// STRIDE
privatestaticfinalint STRIDE = 5;
privatefinalint bonesPerVertex;
privatefinalint boneCount;
privateint a_weights = -2;
privateint a_indices;
public SkeletalVertexModifier(int bonesPerVertex, int boneCount) {
this.boneCount = boneCount;
this.bonesPerVertex = bonesPerVertex;
}
@Override
publicvoid onLoadObject(Material mtl, GameObject object, float[] vbo) {
BonedObject bonedObject = (BonedObject) object;
mtl.loadArrayToVbo(bonedObject.boneWeights, vbo, bonesPerVertex, object.info.count);
mtl.loadArrayToVbo(bonedObject.boneIndices, vbo, bonesPerVertex, object.info.count);
}
@Override
publicvoid onAttachAttribs(Material mtl, Program program) {
if (a_weights == -2) {
a_weights = program.getAttribLocation("a_weights");
a_indices = program.getAttribLocation("a_indices");
}
mtl.attachAttrib(a_weights, bonesPerVertex);
mtl.attachAttrib(a_indices, bonesPerVertex, GLES20.GL_BYTE);
}
@Override
publicvoid getVars(StringBuilder sb) {
sb.append(String.format(Locale.US, VARS, boneCount));
}
@Override
publicvoid getCode(StringBuilder sb) {
finalboolean normal = containsNormalAttrib(sb);
final String SKIN;
if (normal) {
SKIN = SKIN_POS + SKIN_NORMAL;
} else {
SKIN = SKIN_POS;
}
// "initialization" code
sb.append(
"float m_weight;\n" +
"float m_weight_sum = 0.0;\n" +
"int m_index;\n" +
"vec4 a_pos4 = vec4(a_pos.xyz, 1.0);\n" +
"vec3 mod_pos = vec3(0.0);\n");
if (normal) {
sb.append(
"vec4 a_normal4 = vec4(a_normal, 0.0);\n" +
"vec3 mod_normal = vec3(0.0);\n");
}
// "skinning" code
sb.append(
"m_weight = a_weights[0];\n" +
"m_index = int(a_indices[0]);\n");
sb.append(SKIN);
sb.append(
"m_weight = a_weights[1];\n" +
"m_index = int(a_indices[1]);\n");
sb.append(SKIN);
sb.append(
"m_weight = a_weights[2];\n" +
"m_index = int(a_indices[2]);\n");
sb.append(SKIN);
sb.append(
"m_weight = a_weights[3];\n" +
"m_index = int(a_indices[3]);\n");
sb.append(SKIN);
// "finishing" code
sb.append("mod_pos /= m_weight_sum;\n");
if (normal) {
sb.append("mod_normal /= m_weight_sum;\n");
}
}
@Override
publicvoid getMethods(StringBuilder sb) {
sb.append(METHOD_SKIN_POS);
if (containsNormalAttrib(sb)) {
sb.append(METHOD_SKIN_NORMAL);
}
}
@Override
publicint getStride() {
return STRIDE;
}
}