PDA

View Full Version : JME to java3D


gowrys
02-05-2008, 10:38 PM
Hello..
I am trying to display the Collada file in Java3D.I am using JME to converting the collada file to jme..I tried to read the vertices normals amnd texture coordinates from the file while loading.. but the coordinates can be read only if it were in the <triangles> or <polygons> tag..
I want to read the vertices from <polylist> tag that is a child of <mesh>..
What should I do for that???
I wrote a method simillar to handle the <polygons> tag.But it throws a NullPointer Exception while loading....

Method I wrote is :


/**
* processPolylist will process the polylist tag from the mesh section of the
* COLLADA file. A jME is returned that defines the vertices, normals,
* texture coordinates and colors.
*
* @param mesh
* the meshType to process for the lines.
* @param geom
* the geomType for the lines
* @return the jME tri mesh representing the COLLADA mesh.
*/

private TriMesh processPolylistMesh(meshType mesh, geometryType geom)
throws Exception {

HashMap<Integer, ArrayList<BatchVertPair>> vertMap = new HashMap<Integer, ArrayList<BatchVertPair>>();
put(geom.getid().toString() + "VertMap", vertMap);
TriMesh triMesh = new TriMesh(geom.getid().toString());
for (int batchIndex = 0; batchIndex < mesh.getpolylistCount(); batchIndex++) {
polylistType poly = mesh.getpolylistAt(batchIndex);
TriangleBatch triBatch = null;
if (batchIndex < triMesh.getBatchCount()) {
triBatch = triMesh.getBatch(batchIndex);
} else {
triBatch = new TriangleBatch();
triMesh.addBatch(triBatch);
}
if (poly.hasmaterial()) {
triBatch.setName(poly.getmaterial().toString());
}
// build the index buffer, this is going to be easy as it's only
// 0...N where N is the number of vertices in the model.
IntBuffer indexBuffer = BufferUtils.createIntBuffer(poly.getcount()
.intValue() * 3);
for (int i = 0; i < indexBuffer.capacity(); i++) {
indexBuffer.put(i);
}
triMesh.setIndexBuffer(batchIndex, indexBuffer);
// find the maximum offset to understand the stride
int maxOffset = -1;
for (int i = 0; i < poly.getinputCount(); i++) {
int temp = poly.getinputAt(i).getoffset().intValue();
if (maxOffset < temp) {
maxOffset = temp;
}
}
int stride = maxOffset + 1;
// next build the other buffers, based on the input semantic
for (int i = 0; i < poly.getinputCount(); i++) {
if ("VERTEX"
.equals(poly.getinputAt(i).getsemantic().toString( ))) {
// build the vertex buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}
if (data == null) {
logger.warning("Invalid source: " + key);
continue;
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = null;
int vertCount = poly.getcount().intValue() * stride;

System.out.println(" VERTEX COUNT "+vertCount);

FloatBuffer vertBuffer = BufferUtils
.createVector3Buffer(vertCount);


triBatch.setVertexCount(vertCount);
for (int j = 0; j < vertCount; j++) {
if (j % stride == 0) {
st = new StringTokenizer(poly.getpAt(j / stride).getValue());

}
// need to store the index in p to what j is for later
// processing the index to the vert for bones
int vertKey = Integer.parseInt(st.nextToken());
ArrayList<BatchVertPair> storage = vertMap.get(Integer
.valueOf(vertKey));
if (storage == null) {
storage = new ArrayList<BatchVertPair>();
storage.add(new BatchVertPair(batchIndex, j));
vertMap.put(Integer.valueOf(vertKey), storage);
} else {
storage.add(new BatchVertPair(batchIndex, j));
}
BufferUtils.setInBuffer(v[vertKey], vertBuffer, j);
for (int k = 0; k < maxOffset; k++) {
st.nextToken();
}
}
triMesh.setVertexBuffer(batchIndex, vertBuffer);
} else if ("NORMAL".equals(poly.getinputAt(i).getsemantic()
.toString())) {
// build the normal buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}
if (data == null) {
logger.warning("Invalid source: " + key);
continue;
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = null;
int normCount = poly.getcount().intValue() * stride;
FloatBuffer normBuffer = BufferUtils
.createVector3Buffer(normCount);
int offset = poly.getinputAt(i).getoffset().intValue();
for (int j = 0; j < offset; j++) {
if (j % stride == 0) {
st = new StringTokenizer(poly.getpAt(j / stride)
.getValue());
}
st.nextToken();
}
for (int j = 0; j < normCount; j++) {
if (j % stride == 0) {
st = new StringTokenizer(poly.getpAt(j / stride)
.getValue());
}
int index = Integer.parseInt(st.nextToken());
if (index < v.length)
BufferUtils.setInBuffer(v[index], normBuffer, j);
for (int k = 0; k < maxOffset; k++) {
if (st.hasMoreTokens()) {
st.nextToken();
}
}
}
triMesh.setNormalBuffer(batchIndex, normBuffer);
} else if ("TANGENT".equals(poly.getinputAt(i).getsemantic()
.toString())) {
// build the tangent buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}


if (data == null) {
logger.warning("Invalid source: " + key);
continue;
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = new StringTokenizer(poly.getp()
.getValue());
int normCount = poly.getcount().intValue() * 3;
FloatBuffer normBuffer = BufferUtils
.createVector3Buffer(normCount);
int offset = poly.getinputAt(i).getoffset().intValue();
for (int j = 0; j < offset; j++) {
st.nextToken();
}
for (int j = 0; j < normCount; j++) {
int index = Integer.parseInt(st.nextToken());
if (index < v.length)
BufferUtils.setInBuffer(v[index], normBuffer, j);
for (int k = 0; k < maxOffset; k++) {
if (st.hasMoreTokens()) {
st.nextToken();
}
}
}
triMesh.setTextureBuffer(batchIndex, normBuffer, 1);
logger.info("setting tangent buffer: " + normBuffer);
} else if ("BINORMAL".equals(poly.getinputAt(i).getsemantic()
.toString())) {
// build the tangent buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}
if (data == null) {
logger.warning("Invalid source: " + key);
continue;
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = new StringTokenizer(poly.getp()
.getValue());
int normCount = poly.getcount().intValue() * 3;
FloatBuffer normBuffer = BufferUtils
.createVector3Buffer(normCount);
int offset = poly.getinputAt(i).getoffset().intValue();
for (int j = 0; j < offset; j++) {
st.nextToken();
}
for (int j = 0; j < normCount; j++) {
int index = Integer.parseInt(st.nextToken());
if (index < v.length)
BufferUtils.setInBuffer(v[index], normBuffer, j);
for (int k = 0; k < maxOffset; k++) {
if (st.hasMoreTokens()) {
st.nextToken();
}
}
}
triMesh.setTextureBuffer(batchIndex, normBuffer, 2);
} else if ("TEXCOORD".equals(poly.getinputAt(i).getsemantic()
.toString())) {
// build the texture buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}
if (data == null) {
logger.warning("Invalid source: " + key);
continue;
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = new StringTokenizer(poly.getp()
.getValue());
int texCount = poly.getcount().intValue() * stride;
FloatBuffer texBuffer = BufferUtils
.createVector2Buffer(texCount);
int offset = poly.getinputAt(i).getoffset().intValue();
int set = poly.getinputAt(i).getset().intValue();
for (int j = 0; j < offset; j++) {
if (j % stride == 0) {
st = new StringTokenizer(poly.getpAt(j / stride)
.getValue());
}
st.nextToken();
}
// Keep a max to set the wrap mode (if it's 1, clamp, if
// it's > 1 wrap it)
float maxX = -1;
float maxY = -1;
Vector2f tempTexCoord = new Vector2f();
for (int j = 0; j < texCount; j++) {
if (j % stride == 0) {
st = new StringTokenizer(poly.getpAt(j / stride)
.getValue());
}
int index = Integer.parseInt(st.nextToken());
Vector3f value = v[index];
if (value.x > maxX) {
maxX = value.x;
}
if (value.y > maxY) {
maxY = value.y;
}
tempTexCoord.set(value.x, value.y);
BufferUtils.setInBuffer(tempTexCoord, texBuffer, j);
for (int k = 0; k < maxOffset; k++) {
if (st.hasMoreTokens()) {
st.nextToken();
}
}
}
int unit;
if (set == 0) {
unit = 0;
} else {
unit = set - 1;
}
triMesh.setTextureBuffer(batchIndex, texBuffer, unit);
// Set the wrap mode, check if the batch has a texture
// first, if not
// check the geometry.
// Then, based on the texture coordinates, we may need to
// change it from the
// default.
TextureState ts = (TextureState) triBatch
.getRenderState(RenderState.RS_TEXTURE);
if (ts == null) {
ts = (TextureState) triMesh
.getRenderState(RenderState.RS_TEXTURE);
}
if (ts != null) {
Texture t = ts.getTexture(unit);
if (t != null) {
if (maxX > 1) {
if (maxY > 1) {
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
} else {
t.setWrap(Texture.WM_WRAP_S_CLAMP_T);
}
} else if (maxY > 1) {
t.setWrap(Texture.WM_CLAMP_S_WRAP_T);
}
}
}
} else if ("COLOR".equals(poly.getinputAt(i).getsemantic()
.toString())) {
// build the texture buffer
String key = poly.getinputAt(i).getsource().getValue();
if (key.startsWith("#")) {
key = key.substring(1);
}
Object data = resourceLibrary.get(key);
while (data instanceof String) {
key = (String) data;
if (key.startsWith("#")) {
key = key.substring(1);
}
data = resourceLibrary.get(key);
}
Vector3f[] v = (Vector3f[]) data;
StringTokenizer st = new StringTokenizer(poly.getp()
.getValue());
int colorCount = poly.getcount().intValue() * 3;
FloatBuffer colorBuffer = BufferUtils
.createColorBuffer(colorCount);
int offset = poly.getinputAt(i).getoffset().intValue();
for (int j = 0; j < offset; j++) {
st.nextToken();
}
ColorRGBA tempColor = new ColorRGBA();
for (int j = 0; j < colorCount; j++) {
int index = Integer.parseInt(st.nextToken());
Vector3f value = v[index];
tempColor.set(value.x, value.y, value.z, 1);
BufferUtils.setInBuffer(tempColor, colorBuffer, j);
for (int k = 0; k < maxOffset; k++) {
if (st.hasMoreTokens()) {
st.nextToken();
}
}
}
triMesh.setColorBuffer(batchIndex, colorBuffer);
}
}
}


triMesh.setModelBound(new BoundingBox());
triMesh.updateModelBound();



return triMesh;


}


Thanks.............

Reedbeta
02-05-2008, 11:25 PM
1. Please use the ... tags to post code, so the formatting is preserved.

2. Try to avoid posting such large amounts of code. Minimal examples are much more likely to get you a useful response.

fireside
02-06-2008, 10:31 AM
Why don't you just use JME? Java3d is pretty slow, isn't it?

Nils Pipenbrinck
02-06-2008, 12:42 PM
Why don't you just use C or C++? Java is pretty slow, at least five times as slow as native code, isn't it?

Reedbeta
02-06-2008, 12:56 PM
Five *times* slower? Where did you get that figure Nils? Considering that modern JVMs JIT the bytecode into native code, I would be surprised if it was more than a few percent slower.

fireside
02-06-2008, 01:30 PM
Why don't you just use C or C++? Java is pretty slow, at least five times as slow as native code, isn't it?
It's slightly slower, but it's much easier to port other platforms. Android, the Google handset alliance, is going to be using Java and they show a version of Quake running on a prototype telephone. So, one version of a game written in Java could run on Windows, Mac, Linux, telephones, browsers, and who knows what else? Cutting edge graphic stuff will need c++, but who's going to be selling that type of game other than a few game companies?

gowrys
02-06-2008, 07:46 PM
Thanks for your reply..
I am just new to these forums and that was my first post...
My aim is to display a model from the collada file in an applet.. so am using Java3D...ofcourse its sloweer than other platforms you specified..
Thanks...

fireside
02-06-2008, 08:26 PM
You might be better off starting from scratch and parsing it yourself, then. I think there are some xml reader type software around for java. Collada is probably XML, I never looked, though. Anyway, if you play around with parsing it for a while, you'll probably figure out what JME did, or ask on the JME forums. The guy that wrote the parser might even be hanging around on the forum.
Are you sure JME didn't pick up that mesh vertex list? They use animated models from collada and it seems like they would need it to know which vertex goes with which bone.

gowrys
02-07-2008, 09:37 PM
Thank you...
I succesfully load the shape from the collada file using another loader..
Now am trying to display any appearance from that collada file...