📄 colladaimporter.java
字号:
}
}
private void processPhysicsModel(physics_modelType physModel)
throws Exception {
// we only care about the shape (which for now will only reference a
// geometry), so simply store this geometry with the name of the rigid
// body as the key. Initially, this only supports a single shape per
// physics model. Will be enhanced first available chance.
if (physModel.hasrigid_body()) {
for (int i = 0; i < physModel.getrigid_bodyCount(); i++) {
rigid_bodyType rigidBody = physModel.getrigid_bodyAt(i);
String id = rigidBody.getsid().toString();
if (rigidBody.hastechnique_common()) {
if (rigidBody.gettechnique_common().hasshape()) {
for (int j = 0; j < rigidBody.gettechnique_common()
.getshapeCount(); j++) {
shapeType2 shape = rigidBody.gettechnique_common()
.getshapeAt(j);
if (shape.hasinstance_geometry()) {
String key = shape.getinstance_geometry()
.geturl().toString().substring(1);
Spatial s = (Spatial) resourceLibrary.get(key);
if (s != null) {
put(id, s);
}
}
}
}
}
}
}
}
/**
* processSource builds resource objects TIME, TRANSFORM and Name array for
* the interpolation type.
*
* @param source
* the source to process
* @throws Exception
* exception thrown if there is a problem with
*/
private void processSource(sourceType source) throws Exception {
if (source.hasfloat_array()) {
if (source.hastechnique_common()) {
float[] floatArray = processFloatArray(source.getfloat_array());
paramType3 p = source.gettechnique_common().getaccessor()
.getparam();
if ("TIME".equals(p.getname().toString())) {
put(source.getid().toString(), floatArray);
} else if ("float4x4".equals(p.gettype().toString())) {
Matrix4f[] transforms = new Matrix4f[floatArray.length / 16];
for (int i = 0; i < transforms.length; i++) {
transforms[i] = new Matrix4f();
float[] data = new float[16];
for (int x = 0; x < 16; x++) {
data[x] = floatArray[(16 * i) + x];
}
transforms[i].set(data, true); // collada matrices are
// in row order.
}
put(source.getid().toString(), transforms);
} else if ("ROTX.ANGLE".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] xRot = new float[floatArray.length];
System.arraycopy(floatArray, 0, xRot, 0, xRot.length);
put(source.getid().toString(), xRot);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else if ("ROTY.ANGLE".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] yRot = new float[floatArray.length];
System.arraycopy(floatArray, 0, yRot, 0, yRot.length);
put(source.getid().toString(), yRot);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else if ("ROTZ.ANGLE".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] zRot = new float[floatArray.length];
System.arraycopy(floatArray, 0, zRot, 0, zRot.length);
put(source.getid().toString(), zRot);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else if ("TRANS.X".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] xTrans = new float[floatArray.length];
System.arraycopy(floatArray, 0, xTrans, 0,
xTrans.length);
put(source.getid().toString(), xTrans);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else if ("TRANS.Y".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] yTrans = new float[floatArray.length];
System.arraycopy(floatArray, 0, yTrans, 0,
yTrans.length);
put(source.getid().toString(), yTrans);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else if ("TRANS.Z".equals(p.getname().toString())) {
if ("float".equals(p.gettype().toString())) {
float[] zTrans = new float[floatArray.length];
System.arraycopy(floatArray, 0, zTrans, 0,
zTrans.length);
put(source.getid().toString(), zTrans);
} else {
if (!squelch) {
logger.warning(p.gettype() + " not yet supported "
+ "for animation transforms.");
}
}
} else {
if (!squelch) {
logger.warning(p.getname() + " not yet supported "
+ "for animation source.");
}
}
}
} else if (source.hasName_array()) {
int[] interpolation = processInterpolationArray(source
.getName_array());
put(source.getid().toString(), interpolation);
}
}
/**
* processInterpolationArray builds a int array that corresponds to the
* interpolation types defined in BoneAnimationController.
*
* @param array
* the array to process.
* @return the int array.
* @throws Exception
* thrown if there is a problem processing this xml document.
*/
private int[] processInterpolationArray(Name_arrayType array)
throws Exception {
StringTokenizer st = new StringTokenizer(array.getValue().toString());
int[] out = new int[array.getcount().intValue()];
String token = null;
for (int i = 0; i < out.length; i++) {
token = st.nextToken();
if ("LINEAR".equals(token)) {
out[i] = BoneAnimation.LINEAR;
} else if ("BEZIER".equals(token)) {
out[i] = BoneAnimation.BEZIER;
}
}
return out;
}
/**
* processes a float array object. The floats are represented as a String
* with the values delimited by a space.
*
* @param array
* the array to parse.
* @return the float array to return.
* @throws Exception
* thrown if there is a problem processing the XML.
*/
private float[] processFloatArray(float_arrayType array) throws Exception {
StringTokenizer st = new StringTokenizer(array.getValue().toString());
float[] out = new float[array.getcount().intValue()];
for (int i = 0; i < out.length; i++) {
out[i] = Float.parseFloat(st.nextToken());
}
return out;
}
/**
* processAssetInformation will store the information about the collada file
* for future reference. This will include the author, the tool used, the
* revision, the unit information, and the defined up axis.
*
* @param asset
* the assetType for the root of the model.
*/
private void processAssetInformation(assetType asset) throws Exception {
if (asset.hascontributor()) {
if (asset.getcontributor().hasauthor()) {
modelAuthor = asset.getcontributor().getauthor().toString();
}
if (asset.getcontributor().hasauthoring_tool()) {
tool = asset.getcontributor().getauthoring_tool().toString();
}
}
if (asset.hasrevision()) {
revision = asset.getrevision().toString();
}
if (asset.hasunit()) {
unitName = asset.getunit().getname().toString();
unitMeter = asset.getunit().getmeter().floatValue();
}
if (asset.hasup_axis()) {
upAxis = asset.getup_axis().getValue();
}
}
/**
* processAnimationLibrary will store the individual
* BoneAnimationControllers in the resource library for future use.
* Animations at this level can be considered top level animations that
* should be called from this level. These animations may contain children
* animations the top level animation is responsible for calling.
*
* @param animLib
* the library of animations to parse.
*/
private void processAnimationLibrary(library_animationsType animLib)
throws Exception {
if (animLib.hasanimation()) {
if (controllerNames == null) {
controllerNames = new ArrayList<String>();
}
for (int i = 0; i < animLib.getanimationCount(); i++) {
BoneAnimation bac = processAnimation(animLib.getanimationAt(i));
bac.setInterpolate(false);
bac.optimize(true);
put(bac.getName(), bac);
controllerNames.add(bac.getName());
if (animLib.getanimationAt(i).hasextra()) {
for (int j = 0; j < animLib.getanimationAt(i)
.getextraCount(); j++) {
logger.info("Processing extra in animation library.");
ExtraPluginManager.processExtra(bac, animLib
.getanimationAt(i).getextraAt(j));
}
}
}
}
}
/**
* the animation element catgorizes an animation hierarchy with each
* controller defining the animation's keyframe and sampler functions. These
* interact on single bones, where a collection of controllers will build up
* a complete animation.
*
* @param animation
* the animation to parse.
* @throws Exception
* thrown if there is a problem processing the xml.
*/
private BoneAnimation processAnimation(animationType animation)
throws Exception {
BoneAnimation out = new BoneAnimation(animation.getid().toString());
BoneTransform bt = new BoneTransform();
out.setInterpolate(true);
if (animation.hassource()) {
for (int i = 0; i < animation.getsourceCount(); i++) {
processSource(animation.getsourceAt(i));
}
}
float[] rotx = null;
float[] roty = null;
float[] rotz = null;
float[] transx = null;
float[] transy = null;
float[] transz = null;
boolean transformsSet = false;
if (animation.hassampler()) {
for (int j = 0; j < animation.getsamplerCount(); j++) {
for (int i = 0; i < animation.getsamplerAt(j).getinputCount(); i++) {
if ("INPUT".equals(animation.getsamplerAt(j).getinputAt(i)
.getsemantic().toString())) {
String key = animation.getsamplerAt(j).getinputAt(i)
.getsource().toString().substring(1);
float[] times = (float[]) resourceLibrary.get(key);
if (times == null) {
logger.warning("Animation source invalid: " + key);
continue;
}
out.setTimes(times);
out.setStartFrame(0);
out.setEndFrame(times.length - 1);
} else if ("OUTPUT".equals(animation.getsamplerAt(j)
.getinputAt(i).getsemantic().toString())) {
String key = animation.getsamplerAt(j).getinputAt(i)
.getsource().toString().substring(1);
Object object = resourceLibrary.get(key);
if (object == null) {
logger.warning("Animation source invalid: " + key);
continue;
}
if (object instanceof Matrix4f[]) {
Matrix4f[] transforms = (Matrix4f[]) object;
bt.setTransforms(transforms);
transformsSet = true;
} else if (object instanceof float[]) {
// Another bit of a hack that should be improved:
// to put the float arrays into the BoneTransform,
// we need to know what angle it is changing,
// I see know way to determine other than looking
// at the source name.
if (animation.getsamplerAt(j).getinputAt(i)
.getsource().toString().contains(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -