Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/trapezium/vrmlspace/SpaceStructureLoader.java


1   /*
2    * @(#)SpaceStructureLoader.java
3    *
4    * Copyright (c) 1998 by Trapezium Development LLC.  All Rights Reserved.
5    *
6    * The information in this file is the property of Trapezium Development LLC
7    * and may be used only in accordance with the terms of the license granted
8    * by Trapezium.
9    *
10   */
11  package com.trapezium.vrmlspace;
12  
13  import com.trapezium.space.*;
14  import com.trapezium.vrmlspace.*;
15  import com.trapezium.parse.TokenTypes;
16  import com.trapezium.vrml.VrmlElement;
17  import com.trapezium.vrml.Scene;
18  import com.trapezium.vrml.node.Node;
19  import com.trapezium.vrml.fields.*;
20  import com.trapezium.parse.TokenEnumerator;
21  
22  import java.util.Vector;
23  import java.util.Hashtable;
24  
25  /** The SpaceStructureLoader manages a set of SpaceStructures associated
26   *  with IndexedFaceSets in a file.  Two sets of SpaceStructures are kept --
27   *  one for each IFS in the file, accessed by index, and one for each
28   *  Coordinate node in the file, accessed by coord node.  These lists will
29   *  be different if the file uses DEF/USE of Coordinate nodes.
30   *
31   *  @author          Johannes N. Johannsen
32   *  @version         1.0, 8 Oct 1998
33   *
34   *  @since           1.0
35   */
36  
37  public class SpaceStructureLoader {
38  
39      Vector independentStructures;
40      Hashtable completeStructures;  // key coord node, value SpaceStructure
41      TokenEnumerator dataSource;
42  
43      /** Class constructor */
44      public SpaceStructureLoader() {
45          dataSource = null;
46          independentStructures = new Vector();
47          completeStructures = new Hashtable();
48      }
49  
50      // set dataSource if it isn't set
51      void setDataSource( Node n ) {
52          if ( dataSource == null ) {
53              Scene s = (Scene)n.getRoot();
54              dataSource = s.getTokenEnumerator();
55          }
56      }
57  
58      /** Access space structure by offset.
59       *
60       *  @param offset the offset of the SpaceStructure
61       *  @return the SpaceStructure at that offset, null if offset invalid
62       */
63      public SpaceStructure getSpaceStructure( int offset ) {
64          if (( offset < 0 ) || ( offset >= independentStructures.size() )) {
65              return( null );
66          } else {
67              return( (SpaceStructure)independentStructures.elementAt( offset ));
68          }
69      }
70  
71      /** Access space structure by coord node.
72       *
73       * @param coordNode the Coordinate Node associated with a SpaceStructure,
74       *    in this case, the SpaceStructure represents the union of all
75       *    IndexedFaceSets sharing that Coordinate Node.
76       * @return the SpaceStructure associated with the coordNode, null if none
77       */
78      public SpaceStructure getSpaceStructure( Node coordNode ) {
79          return( (SpaceStructure)completeStructures.get( coordNode ));
80      }
81  
82      /** Load a SpaceStructuare, save it in the independentStructures and
83       *  completeStructures list.  If the Coordinate node is used, then the
84       *  existing entry from the completeStructures list is used, and the
85       *  faces for the current SpaceStructure are appended onto that entry,
86       *  resulting in that entry being a union of all SpaceStructures associated
87       *  with a particular coordinate node.
88       *
89       * @param n the IndexedFaceSet node to be loaded
90       * @return a SpaceStructure containing the faces for the Node n (i.e.
91       *    the independentStructures entry, not the completeStructures entry)
92       */
93      public SpaceStructure loadSpaceStructure( Node n ) {
94          setDataSource( n );
95          Node coord = n.getNodeValue( "coord" );
96          if ( coord == null ) {
97              return( null );
98          }
99          Field coordIndex = n.getField( "coordIndex" );
100         Field texCoord = n.getField( "texCoord" );
101         Field texCoordIndex = n.getField( "texCoordIndex" );
102         Field color = n.getField( "color" );
103         Field colorIndex = n.getField( "colorIndex" );
104         Field normal = n.getField( "normal" );
105         Field normalIndex = n.getField( "normalIndex" );
106 
107         SpaceStructure s = (SpaceStructure)completeStructures.get( coord );
108         boolean coordNodeSSfound = !( s == null );
109         if ( !coordNodeSSfound ) {
110             s = new SpaceStructure();
111         }
112         SpaceStructure loaded = null;
113         if ( anyDEFUSE( coord, texCoord, color, normal )) {
114             loaded = new SpaceStructure();
115             loaded.setVertices( s.getVertices() );
116         } else {
117             loaded = s;
118         }
119         load3f( coord, loaded.getVertices() );
120 
121         if ( coordIndex != null ) {
122             loadIlist( coordIndex, loaded.getFaces(), s.getFaces() );
123         }
124         if ( !coordNodeSSfound ) {
125             completeStructures.put( coord, s );
126         }
127         independentStructures.addElement( s );
128         s.createTextures( texCoord, texCoordIndex );
129         load2f( texCoord, s.getTexCoord() );
130         loadIlist( texCoordIndex, s.getTexCoordIndex(), 
131             loaded.getTexCoordIndex() );
132         if ( loaded != s ) {
133             loaded.createTextures( texCoord, texCoordIndex );
134             load2f( texCoord, loaded.getTexCoord() );
135         }
136         s.createColors( color, colorIndex, n.getBoolValue( "colorPerVertex" ));
137         load3f( color, s.getColor() );
138         if ( loaded != s ) {
139             loaded.createColors( color, colorIndex, n.getBoolValue( "colorPerVertex" ));
140             load3f( color, loaded.getColor() );
141         }
142         loadIlist( colorIndex, s.getColorIndex(), loaded.getColorIndex() );
143         s.createNormals( normal, normalIndex, n.getBoolValue( "normalPerVertex" ));
144         load3f( normal, s.getNormal() );
145         if ( loaded != s ) {
146             loaded.createNormals( normal, normalIndex, n.getBoolValue( "normalPerVertex" ));
147             load3f( normal, loaded.getNormal() );
148         }
149         loadIlist( normalIndex, s.getNormalIndex(), loaded.getNormalIndex() );
150         return( loaded );
151     }
152 
153     /** Check if any of the fields refer to a DEFUSEnode */
154     boolean anyDEFUSE( Field f1, Field f2, Field f3, Field f4 ) {
155         if ( hasDEFUSE( f1 )) {
156             return( true );
157         }
158         if ( hasDEFUSE( f2 )) {
159             return( true );
160         }
161         if ( hasDEFUSE( f3 )) {
162             return( true );
163         }
164         return( hasDEFUSE( f4 ));
165     }
166     
167     /** Check if field refers to a DEFUSENode */
168     boolean hasDEFUSE( Field f ) {
169         if ( f != null ) {
170             FieldValue fv = f.getFieldValue();
171             if ( fv instanceof SFNodeValue ) {
172                 SFNodeValue sfnv = (SFNodeValue)fv;
173                 Node n = sfnv.getNode();
174                 if ( n != null ) {
175                     return( n.isDEForUSE() );
176                 }
177             }
178         }
179         return( false );
180     }
181     
182     /** Load the vertices into a SpaceStructure.
183      *
184      *  @param valueNode source of vertex data
185      *  @param target where to load the data
186      */
187     void load3f( VrmlElement valueNode, SpaceEntitySet target ) {
188         if ( valueNode != null ) {
189             float[] loc = new float[3];
190             dataSource.setState( valueNode.getFirstTokenOffset() );
191             int last = valueNode.getLastTokenOffset();
192             while ( dataSource.copy3f( loc, last )) {
193                 target.add3f( loc );
194             }
195         }
196     }
197 
198     /** Load the texCoords into a SpaceStructure.
199      *
200      *  @param valueNode source of vertex data
201      *  @param target where to load the data
202      */
203     void load2f( VrmlElement valueNode, SpaceEntitySet target ) {
204         if ( valueNode != null ) {
205             float[] loc = new float[2];
206             dataSource.setState( valueNode.getFirstTokenOffset() );
207             int last = valueNode.getLastTokenOffset();
208             while ( dataSource.copy2f( loc, last )) {
209                 target.add2f( loc );
210             }
211         }
212     }
213 
214     /** Load the index array into a SpaceStructure.
215      *
216      * @param ilist source of face data
217      * @param target1 first of two destinations of face data, this is the
218      *     one that only contains the single set of face data
219      * @param target2 second of two destinations of face data, this is the
220      *     one that contains the union of all faces with the same coord node
221      */
222     void loadIlist( VrmlElement ilist, SpaceEntitySet target1, SpaceEntitySet target2 ) {
223         if ( target1 == target2 ) {
224             target2 = null;
225         }
226         int scanner = ilist.getFirstTokenOffset();
227         dataSource.setState( scanner );
228         int last = ilist.getLastTokenOffset();
229         int val = -1;
230         while ( scanner < last ) {
231             dataSource.skipTo( TokenTypes.NumberToken );
232             scanner = dataSource.getState();
233             if (( scanner == -1 ) || ( scanner > last )) {
234                 break;
235             }
236             val = dataSource.getIntValue( scanner );
237             target1.add( val );
238             if ( target2 != null ) {
239                 target2.add( val );
240             }
241             scanner = dataSource.getNextToken();
242         }
243         if ( val != -1 ) {
244             target1.add( -1 );
245             if ( target2 != null ) {
246                 target2.add( -1 );
247             }
248         }
249     }
250 }