Skip to main content

Java3d GeometryArry by reference updateData and setTransform problem

Please note these java.net forums are being decommissioned and use the new and improved forums at https://community.oracle.com/community/java.
No replies
geminit2011
Offline
Joined: 2011-08-24
Points: 0

first, so sorry to put this question to this forum,but java3d forum is (read only archive).
I use java3d in my project, I also use 3D model : ms3d for skeleton animation, the ms3d loader is com.jlindamood.MS3D.MilkLoader.
This loader Used MilkAnimation achieve skeletal animation, and it use GeometryUpdater to update skeleton animation.
this is all work fine in my project. but when I put this reference to a TransformGroup , when the model show a walk animation , the TransfromGroup also use setTransfrom3D to change to TransformGroup's position. the model will be twinkling.

I also see the java3d API for the GeometryArrys' s desc:
By Reference: A new set of methods in Java 3D version 1.2 allows data to be accessed by reference, directly from the user's arrays. To use this feature, set the BY_REFERENCE bit in the vertexFormat field of the constructor for this GeometryArray. In this mode, the various set methods for coordinates, normals, colors, texture coordinates, and vertex attributes are not used. Instead, new methods are used to set a reference to user-supplied coordinate, color, normal, texture coordinate, and vertex attribute arrays (such as setCoordRefFloat, setColorRefFloat, etc.). Data in any array that is referenced by a live or compiled GeometryArray object may only be modified via the updateData method (subject to the ALLOW_REF_DATA_WRITE capability bit). Applications must exercise care not to violate this rule. If any referenced geometry data is modified outside of the updateData method, the results are undefined.

but I really need to show the model's animation and change the model's postion, Just like a person to move.
I also change movementFile.myGroups[i].groupGeometry.updateData(toUpdate); to Direct call updateData() method, the model is not twinkling, but it Show cracks.
how can i solve this problem?
forgive my poor english!

the milkanimation source code:
public class MilkAnimation extends Behavior
{
private SyncedGeometryUpdate toUpdate;

private Quat4f unSyncbeginAngle = new Quat4f();
private Vector3f unSyncbeginPos = new Vector3f();
MilkFile movementFile;
int startFrame;
int endFrame;
private int maxFrame;
long duration;
Transform3D[] jointMovements;
Alpha changeTimer;
WakeupCondition whenToWake;
int currentFrame;
float changeAmnt;
Transform3D tempUnSyncd = new Transform3D();
MilkJoint[] milkJoints;

MilkAnimation(MilkFile movementFile, int startFrame, int endFrame, int duration)
{
this.maxFrame = endFrame;
whenToWake = new WakeupOnElapsedFrames(5);

milkJoints = movementFile.myJoints;

this.setUserData("Exact MS aniamtion");
this.movementFile = movementFile;
this.startFrame = startFrame;
this.endFrame = endFrame;
this.duration = duration;
jointMovements = new Transform3D[movementFile.nNumJoints];

for (int i = 0; i < jointMovements.length; i++)
jointMovements[i] = new Transform3D();

changeTimer = new Alpha(1, duration);
whenToWake = new WakeupOnElapsedFrames(0);
toUpdate = new SyncedGeometryUpdate();
this.setUserData("Exact Animation");
this.setEnable(true);
}

public Transform3D[] getJointMovements()
{
return jointMovements;
}

public void initialize()
{
changeTimer.setStartTime(System.currentTimeMillis());
this.wakeupOn(whenToWake);
currentFrame = startFrame;
}

public void processStimulus(Enumeration enumeration)
{
if (changeTimer.finished())
{
changeTimer.setStartTime(System.currentTimeMillis());
currentFrame++;
if (currentFrame == endFrame)
currentFrame = startFrame;
}
changeAmnt = changeTimer.value();
// currentFrame=2;
// changeAmnt=0;
createJointTransforms(changeAmnt);

/*
* System.out.println("Keyframe: " + currentFrame); for (int i=0;i for (int i=0;i System.out.println("DONE"); System.exit(0);
*/
combineWithInverse();

for (int i = 0; i < movementFile.nNumGroups; i++)
{
toUpdate.setMesh(movementFile.myGroups[i]);
movementFile.myGroups[i].groupGeometry.updateData(toUpdate);
}
this.wakeupOn(whenToWake);
}

private void combineWithInverse()
{
for (int i = 0; i < jointMovements.length; i++)
{
jointMovements[i].mul(movementFile.myJoints[i].inverseChainMatrix);
}
}

private void createJointTransforms(float changeAmnt)
{
for (int index = 0; index < jointMovements.length; index++)
{
int theParentIndex = movementFile.myJoints

.parentIndex;

unSyncbeginAngle.set(movementFile.myJoints

.keyframeRot[currentFrame]);
unSyncbeginPos.set(movementFile.myJoints
.keyframePos[currentFrame]);

unSyncbeginAngle.interpolate(movementFile.myJoints

.keyframeRot[currentFrame + 1], changeAmnt);
unSyncbeginPos.interpolate(movementFile.myJoints
.keyframePos[currentFrame + 1], changeAmnt);
tempUnSyncd.set(unSyncbeginAngle, unSyncbeginPos, 1);
jointMovements
.set(movementFile.myJoints
.localRefMatrix);
jointMovements
.mul(tempUnSyncd);
if (theParentIndex != -1)
{
tempUnSyncd.set(jointMovements
);
jointMovements
.set(jointMovements[theParentIndex]);
jointMovements
.mul(tempUnSyncd);
}
}
}

/**
* Changes the time (in Milliseconds) from one keyframe to the next
*
* @param duration
* new duration
*/
public void setDuration(long duration)
{
this.duration = duration;
changeTimer.setIncreasingAlphaDuration(duration);
}

/**
* Returns the animation files current duration between frames
*
* @return the animation file's duration
*/
public long getDuration()
{
return this.duration;
}

public MilkJoint[] getMilkJoints()
{
return milkJoints;
}

public void setMilkJoints(MilkJoint[] milkJoints)
{
this.milkJoints = milkJoints;
}

/**
* Sets the starting and ending frames for the animation to those given
*
* @param start
* Starting frame
* @param end
* Ending frame
*/
public void setFrames(int start, int end)
{
if (start < 0 || start > end || end > maxFrame)
return;
startFrame = start;
endFrame = end;
}

class SyncedGeometryUpdate implements GeometryUpdater
{
MilkshapeGroup updatingGroup;
Point3f myCurPoint = new Point3f();
Vector3f myCurNorm = new Vector3f();

void setMesh(MilkshapeGroup toMesh)
{
updatingGroup = toMesh;
}

public void updateData(Geometry geometry)
{

int currentBoneIndex;
for (int j = 0; j < updatingGroup.numTriangles; j++)
{
for (int s = 0; s < 3; s++)
{ // Each tri has 3 co-ords

int coordIndex = movementFile.myTri[updatingGroup.triangleIndices[j]].vertexIndices[s];
currentBoneIndex = movementFile.boneID[coordIndex];
myCurPoint.set(movementFile.vertexes[coordIndex]);
if (currentBoneIndex >= 0 && currentBoneIndex < jointMovements.length)
{
jointMovements[currentBoneIndex].transform(myCurPoint);
}
updatingGroup.myCurrentCoords[j * 9 + s * 3 + 0] = myCurPoint.x;
updatingGroup.myCurrentCoords[j * 9 + s * 3 + 1] = myCurPoint.y;
updatingGroup.myCurrentCoords[j * 9 + s * 3 + 2] = myCurPoint.z;

myCurNorm.set(movementFile.myTri[updatingGroup.triangleIndices[j]].vertexNormals[s]);
if (currentBoneIndex >= 0 && currentBoneIndex < jointMovements.length)
{
jointMovements[currentBoneIndex].transform(myCurNorm);
}
updatingGroup.myCurrentNorms[j * 9 + s * 3 + 0] = myCurNorm.x;
updatingGroup.myCurrentNorms[j * 9 + s * 3 + 1] = myCurNorm.y;
updatingGroup.myCurrentNorms[j * 9 + s * 3 + 2] = myCurNorm.z;
}
}
}
}
}