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.............
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.............