@@ -89,7 +89,7 @@ private class ColladaDocument
8989 private Document doc ;
9090 private XPath xpath ;
9191 private Element visual_scene_node_template , oriented_shape_template , geometry_template , shape_template ,
92- visual_scene , library_nodes , library_geometries ,
92+ visual_scene , model_group , library_nodes , library_geometries ,
9393 material_template , library_materials , effect_template , library_effects ;
9494 private int instanceNum = 0 , shapeNum = 0 , colorNum = 0 , nodeNum = 0 ;
9595 private String embeddingMatrixText = null ;
@@ -105,7 +105,7 @@ private class ColladaDocument
105105 InputStream bytes = getClass () .getClassLoader () .getResourceAsStream ( templatePath );
106106
107107 DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance ();
108- // factory .setNamespaceAware(true);
108+ factory .setNamespaceAware (true );
109109 DocumentBuilder builder ;
110110 try {
111111 builder = factory .newDocumentBuilder ();
@@ -114,29 +114,55 @@ private class ColladaDocument
114114 // Create XPathFactory object
115115 XPathFactory xpathFactory = XPathFactory .newInstance ();
116116
117- // Create XPath object
117+ // Create XPath object with namespace awareness
118118 xpath = xpathFactory .newXPath ();
119+ xpath .setNamespaceContext (new javax .xml .namespace .NamespaceContext () {
120+ @ Override
121+ public String getNamespaceURI (String prefix ) {
122+ if (prefix == null ) throw new NullPointerException ("Null prefix" );
123+ if ("c" .equals (prefix )) return "http://www.collada.org/2005/11/COLLADASchema" ;
124+ return javax .xml .XMLConstants .NULL_NS_URI ;
125+ }
126+
127+ @ Override
128+ public String getPrefix (String uri ) {
129+ throw new UnsupportedOperationException ();
130+ }
119131
120- visual_scene_node_template = (Element ) xpath .evaluate ( "//node[@id='instance']" , doc .getDocumentElement (), XPathConstants .NODE );
132+ @ Override
133+ public java .util .Iterator <String > getPrefixes (String uri ) {
134+ throw new UnsupportedOperationException ();
135+ }
136+ });
137+
138+ // Get the instance template and the visual scene
139+ visual_scene_node_template = (Element ) xpath .evaluate ( "//c:node[@id='instance']" , doc .getDocumentElement (), XPathConstants .NODE );
121140 visual_scene = (Element ) visual_scene_node_template .getParentNode ();
122141 visual_scene .removeChild ( visual_scene_node_template );
123142
124- oriented_shape_template = (Element ) xpath .evaluate ( "//node[@id='oriented-shape']" , doc .getDocumentElement (), XPathConstants .NODE );
143+ // Create a group node for all model instances
144+ model_group = doc .createElementNS ("http://www.collada.org/2005/11/COLLADASchema" , "node" );
145+ model_group .setAttribute ("id" , "vZome-model-instances" );
146+ // Insert it after the last light node
147+ Element lastLight = (Element ) xpath .evaluate ( "//c:node[@id='light4']" , doc .getDocumentElement (), XPathConstants .NODE );
148+ lastLight .getParentNode ().insertBefore (model_group , lastLight .getNextSibling ());
149+
150+ oriented_shape_template = (Element ) xpath .evaluate ( "//c:node[@id='oriented-shape']" , doc .getDocumentElement (), XPathConstants .NODE );
125151 library_nodes = (Element ) oriented_shape_template .getParentNode ();
126152 library_nodes .removeChild ( oriented_shape_template );
127153
128- shape_template = (Element ) xpath .evaluate ( "//node[@id='shape-node']" , doc .getDocumentElement (), XPathConstants .NODE );
154+ shape_template = (Element ) xpath .evaluate ( "//c: node[@id='shape-node']" , doc .getDocumentElement (), XPathConstants .NODE );
129155 library_nodes .removeChild ( shape_template );
130156
131- geometry_template = (Element ) xpath .evaluate ( "//geometry[@id='shape-geom']" , doc .getDocumentElement (), XPathConstants .NODE );
157+ geometry_template = (Element ) xpath .evaluate ( "//c: geometry[@id='shape-geom']" , doc .getDocumentElement (), XPathConstants .NODE );
132158 library_geometries = (Element ) geometry_template .getParentNode ();
133159 library_geometries .removeChild ( geometry_template );
134160
135- material_template = (Element ) xpath .evaluate ( "//material[@id='color']" , doc .getDocumentElement (), XPathConstants .NODE );
161+ material_template = (Element ) xpath .evaluate ( "//c: material[@id='color']" , doc .getDocumentElement (), XPathConstants .NODE );
136162 library_materials = (Element ) material_template .getParentNode ();
137163 library_materials .removeChild ( material_template );
138164
139- effect_template = (Element ) xpath .evaluate ( "//effect[@id='color-fx']" , doc .getDocumentElement (), XPathConstants .NODE );
165+ effect_template = (Element ) xpath .evaluate ( "//c: effect[@id='color-fx']" , doc .getDocumentElement (), XPathConstants .NODE );
140166 library_effects = (Element ) effect_template .getParentNode ();
141167 library_effects .removeChild ( effect_template );
142168
@@ -206,12 +232,12 @@ String addColor( RenderedManifestation rm )
206232 effect .setAttribute ( "id" , effectId );
207233 library_effects .appendChild ( effect );
208234 try {
209- Element instance_effect = (Element ) xpath .evaluate ( "instance_effect" , material , XPathConstants .NODE );
235+ Element instance_effect = (Element ) xpath .evaluate ( "c: instance_effect" , material , XPathConstants .NODE );
210236 instance_effect .setAttribute ( "url" , "#" + effectId );
211- Element diffuse_color = (Element ) xpath .evaluate ( "profile_COMMON//diffuse/color" , effect , XPathConstants .NODE );
237+ Element diffuse_color = (Element ) xpath .evaluate ( "c: profile_COMMON//c: diffuse/c: color" , effect , XPathConstants .NODE );
212238 diffuse_color .setTextContent ( sb .toString () );
213239 if ( alphaComponent < 1.0f ) {
214- Element transparency_float = (Element ) xpath .evaluate ("profile_COMMON//transparency/float" , effect , XPathConstants .NODE );
240+ Element transparency_float = (Element ) xpath .evaluate ("c: profile_COMMON//c: transparency/c: float" , effect , XPathConstants .NODE );
215241 transparency_float .setTextContent (alphaComponent .toString ());
216242 }
217243 } catch ( XPathExpressionException e ) {
@@ -295,39 +321,39 @@ else if ( v1 == -1 )
295321 geometry .setAttribute ( "id" , geomId );
296322 library_geometries .appendChild ( geometry );
297323 try {
298- Element source = (Element ) xpath .evaluate ( "mesh/source[@name='position']" , geometry , XPathConstants .NODE );
324+ Element source = (Element ) xpath .evaluate ( "c: mesh/c: source[@name='position']" , geometry , XPathConstants .NODE );
299325 source .setAttribute ( "id" , positionsId );
300- Element float_array = (Element ) xpath .evaluate ( "float_array" , source , XPathConstants .NODE );
326+ Element float_array = (Element ) xpath .evaluate ( "c: float_array" , source , XPathConstants .NODE );
301327 float_array .setAttribute ( "id" , positionsArrayId );
302328 float_array .setAttribute ( "count" , "" + ( 3 * vertexCount ) );
303329 float_array .setTextContent ( vertices .toString () );
304- Element accessor = (Element ) xpath .evaluate ( "technique_common/accessor" , source , XPathConstants .NODE );
330+ Element accessor = (Element ) xpath .evaluate ( "c: technique_common/c: accessor" , source , XPathConstants .NODE );
305331 accessor .setAttribute ( "source" , "#" + positionsArrayId );
306332 accessor .setAttribute ( "count" , "" + vertexCount );
307333
308- source = (Element ) xpath .evaluate ( "mesh/source[@name='normal']" , geometry , XPathConstants .NODE );
334+ source = (Element ) xpath .evaluate ( "c: mesh/c: source[@name='normal']" , geometry , XPathConstants .NODE );
309335 source .setAttribute ( "id" , normalsId );
310- float_array = (Element ) xpath .evaluate ( "float_array" , source , XPathConstants .NODE );
336+ float_array = (Element ) xpath .evaluate ( "c: float_array" , source , XPathConstants .NODE );
311337 float_array .setAttribute ( "id" , normalsArrayId );
312338 float_array .setAttribute ( "count" , "" + ( 3 * normalCount ) );
313339 float_array .setTextContent ( normals .toString () );
314- accessor = (Element ) xpath .evaluate ( "technique_common/accessor" , source , XPathConstants .NODE );
340+ accessor = (Element ) xpath .evaluate ( "c: technique_common/c: accessor" , source , XPathConstants .NODE );
315341 accessor .setAttribute ( "source" , "#" + normalsArrayId );
316342 accessor .setAttribute ( "count" , "" + normalCount );
317343
318- Element vertices_node = (Element ) xpath .evaluate ( "mesh/vertices" , geometry , XPathConstants .NODE );
344+ Element vertices_node = (Element ) xpath .evaluate ( "c: mesh/c: vertices" , geometry , XPathConstants .NODE );
319345 vertices_node .setAttribute ( "id" , verticesId );
320- Element input = (Element ) xpath .evaluate ( "input[@semantic='POSITION']" , vertices_node , XPathConstants .NODE );
346+ Element input = (Element ) xpath .evaluate ( "c: input[@semantic='POSITION']" , vertices_node , XPathConstants .NODE );
321347 input .setAttribute ( "source" , "#" + positionsId );
322348
323- Element triangles_node = (Element ) xpath .evaluate ( "mesh/triangles" , geometry , XPathConstants .NODE );
349+ Element triangles_node = (Element ) xpath .evaluate ( "c: mesh/c: triangles" , geometry , XPathConstants .NODE );
324350 triangles_node .setAttribute ( "count" , triangleCount + "" );
325351 triangles_node .setAttribute ( "material" , materialId );
326- input = (Element ) xpath .evaluate ( "input[@semantic='VERTEX']" , triangles_node , XPathConstants .NODE );
352+ input = (Element ) xpath .evaluate ( "c: input[@semantic='VERTEX']" , triangles_node , XPathConstants .NODE );
327353 input .setAttribute ( "source" , "#" + verticesId );
328- input = (Element ) xpath .evaluate ( "input[@semantic='NORMAL']" , triangles_node , XPathConstants .NODE );
354+ input = (Element ) xpath .evaluate ( "c: input[@semantic='NORMAL']" , triangles_node , XPathConstants .NODE );
329355 input .setAttribute ( "source" , "#" + normalsId );
330- Element p = (Element ) xpath .evaluate ( "p" , triangles_node , XPathConstants .NODE );
356+ Element p = (Element ) xpath .evaluate ( "c: p" , triangles_node , XPathConstants .NODE );
331357 p .setTextContent ( triangles .toString () );
332358
333359 } catch ( XPathExpressionException e ) {
@@ -355,9 +381,9 @@ String addColoredShape( RenderedManifestation rm )
355381 shape_node .setAttribute ( "id" , nodeId );
356382 library_nodes .appendChild ( shape_node );
357383 try {
358- Element instance_geometry = (Element ) xpath .evaluate ( "instance_geometry" , shape_node , XPathConstants .NODE );
384+ Element instance_geometry = (Element ) xpath .evaluate ( "c: instance_geometry" , shape_node , XPathConstants .NODE );
359385 instance_geometry .setAttribute ( "url" , "#" + shapeId + "-geom" );
360- Element instance_material = (Element ) xpath .evaluate ( "bind_material//instance_material" , instance_geometry , XPathConstants .NODE );
386+ Element instance_material = (Element ) xpath .evaluate ( "c: bind_material//c: instance_material" , instance_geometry , XPathConstants .NODE );
361387 instance_material .setAttribute ( "symbol" , shapeId + "-material" );
362388 instance_material .setAttribute ( "target" , "#" + colorId );
363389
@@ -378,7 +404,7 @@ String addOrientedShape( RenderedManifestation rm )
378404 Element oriented_shape = (Element ) oriented_shape_template .cloneNode ( true );
379405 try {
380406 StringBuffer sb = new StringBuffer ();
381- Element matrix = (Element ) xpath .evaluate ( "matrix" , oriented_shape , XPathConstants .NODE );
407+ Element matrix = (Element ) xpath .evaluate ( "c: matrix" , oriented_shape , XPathConstants .NODE );
382408 AlgebraicMatrix transform = rm .getOrientation ();
383409 for (int i = 0 ; i < 3 ; i ++) {
384410 for (int j = 0 ; j < 3 ; j ++) {
@@ -389,7 +415,7 @@ String addOrientedShape( RenderedManifestation rm )
389415 }
390416 sb .append ( "0.0 0.0 0.0 1.0" );
391417 matrix .setTextContent ( sb .toString () );
392- Element instance_node = (Element ) xpath .evaluate ( "instance_node" , oriented_shape , XPathConstants .NODE );
418+ Element instance_node = (Element ) xpath .evaluate ( "c: instance_node" , oriented_shape , XPathConstants .NODE );
393419 instance_node .setAttribute ( "url" , "#" + nodeId );
394420 oriented_shape .setAttribute ( "id" , orientedShapeId );
395421 library_nodes .appendChild ( oriented_shape );
@@ -405,25 +431,25 @@ void addShapeInstance( RenderedManifestation rm, String shapeId )
405431 {
406432 Element visual_scene_node = (Element ) visual_scene_node_template .cloneNode ( true );
407433 try {
408- Element translate = (Element ) xpath .evaluate ( "translate" , visual_scene_node , XPathConstants .NODE );
434+ Element translate = (Element ) xpath .evaluate ( "c: translate" , visual_scene_node , XPathConstants .NODE );
409435 AlgebraicVector location = rm .getLocationAV (); // don't want embedding yet
410436 if ( location == null )
411437 visual_scene_node .removeChild ( translate );
412438 else
413439 translate .setTextContent ( location .toRealVector () .spacedString () );
414440
415441 // Apply the global embedding, if non-trivial.
416- Element matrix = (Element ) xpath .evaluate ( "matrix" , visual_scene_node , XPathConstants .NODE );
442+ Element matrix = (Element ) xpath .evaluate ( "c: matrix" , visual_scene_node , XPathConstants .NODE );
417443 if ( this .embeddingMatrixText == null )
418444 visual_scene_node .removeChild ( matrix );
419445 else {
420446 matrix .setTextContent ( embeddingMatrixText );
421447 }
422448
423- Element instance_node = (Element ) xpath .evaluate ( "instance_node" , visual_scene_node , XPathConstants .NODE );
449+ Element instance_node = (Element ) xpath .evaluate ( "c: instance_node" , visual_scene_node , XPathConstants .NODE );
424450 instance_node .setAttribute ( "url" , "#" + shapeId );
425451 visual_scene_node .setAttribute ( "id" , "instance" + Integer .toString ( instanceNum ++ ) );
426- visual_scene .appendChild ( visual_scene_node );
452+ model_group .appendChild ( visual_scene_node );
427453 } catch ( XPathExpressionException e ) {
428454 e .printStackTrace ();
429455 }
0 commit comments