View Javadoc
1   /*
2    * Created on 2005-01-07
3    *
4    * TODO To change the template for this generated file go to
5    * Window - Preferences - Java - Code Style - Code Templates
6    */
7   package org.sourceforge.jvb3d.Loader;
8   
9   import java.util.LinkedList;
10  import java.util.List;
11  import java.util.ListIterator;
12  
13  import javax.media.j3d.BranchGroup;
14  import javax.media.j3d.Shape3D;
15  import javax.vecmath.Point2f;
16  import javax.vecmath.Point3d;
17  import javax.vecmath.TexCoord2f;
18  import javax.vecmath.TexCoord4f;
19  import javax.vecmath.Vector2f;
20  import javax.vecmath.Vector3d;
21  
22  import com.sun.j3d.utils.geometry.GeometryInfo;
23  
24  /***
25   * @author Łukasz Krzyżak
26   *
27   * Klasa reprezentuje powierzchnię
28   */
29  public class Surface {
30  	List<SubSurface> subSurfaceList = new LinkedList<SubSurface>();
31  	String surfaceID = null;
32  	Point3d[] vertices = null;
33  	
34  	protected final static double epsilon = 0.001;
35  	
36  	/***
37  	 * konstruktor nowej powierzchni
38  	 * @param coords tablica współrzędnych powierzchni (4 punkty)
39  	 * @param ID string identyfikujący powierzchnię
40  	 */
41  	public Surface(Point3d[] coords, String ID) {
42  		vertices = coords;
43  		subSurfaceList.add(new SubSurface(coords));
44  		surfaceID = ID;
45  	}
46  	
47  	/***
48  	 * funkcja powoduje wycięcie otworu w powierzchni.
49  	 * powoduje odpowiednie podzielenie istniejących podpowierzchni na mniejsze.
50  	 * @param coords współrzędne otworu
51  	 */
52  	public void cutOpening(Point3d[] coords) {
53  		ListIterator<SubSurface> iterator = subSurfaceList.listIterator();
54  		
55  		SubSurface[] subsurfaces = null;
56  		int currentIndex = 0;
57  		
58  		while(iterator.hasNext()) {
59  			currentIndex = iterator.nextIndex();
60  			SubSurface current = iterator.next();
61  			if(current.isInside(coords[0])) {
62  				subsurfaces = current.cutOpening(coords);
63  				break;
64  			}
65  		}
66  		
67  		if(subsurfaces != null) {
68  			subSurfaceList.remove(currentIndex);
69  			for(int i=0; i<subsurfaces.length; i++)
70  				subSurfaceList.add(currentIndex+i, subsurfaces[i]);
71  		}
72  	}
73  	
74  	void createTextureCoords(TexCoord4f[] coordinates) {
75  		Point2f[] coords = new Point2f[4];
76  		
77  		int texNo = 0;
78  		for(TexCoord4f coordinate : coordinates) {
79  			coords[0] = new Point2f(coordinate.x, coordinate.y);
80  			coords[1] = new Point2f(coordinate.z, coordinate.y);
81  			coords[2] = new Point2f(coordinate.z, coordinate.w);
82  			coords[3] = new Point2f(coordinate.x, coordinate.w);
83  			
84  			createTextureCoords(coords, texNo++);
85  		}
86  	}
87  	
88  	void createTextureCoords() {
89  		TexCoord4f[] texCoords = AppearanceFactory.getInstance().getTextureCoordinates(surfaceID, 0);
90  		
91  		if(texCoords == null) return;
92  		
93  		int texCount = 0;
94  		for(TexCoord4f texture : texCoords) {
95  			calculateSubSurfaceTextures(texture, true, texCount);
96  			calculateSubSurfaceTextures(texture, false, texCount);
97  			texCount++;
98  		}
99  	}
100 	
101 	private TexCoord2f[] calculateSubSurfaceTextures(TexCoord4f textureBoxCoords, boolean frontFace, int texNo) {
102 		Point2f[] texCoords = new Point2f[4];
103 		texCoords[0] = new Point2f(textureBoxCoords.x, textureBoxCoords.y);
104 		texCoords[1] = new Point2f(textureBoxCoords.z, textureBoxCoords.y);
105 		texCoords[2] = new Point2f(textureBoxCoords.z, textureBoxCoords.w);
106 		texCoords[3] = new Point2f(textureBoxCoords.x, textureBoxCoords.w);
107 		
108 		Vector2f uScale = new Vector2f(), vScale = new Vector2f();
109 		uScale.sub(texCoords[1], texCoords[0]);
110 		vScale.sub(texCoords[3], texCoords[0]);
111 		
112 		Vector3d widthVector = new Vector3d(), heightVector = new Vector3d();
113 		widthVector.sub(vertices[1], vertices[0]);
114 		heightVector.sub(vertices[3], vertices[0]);
115 		
116 		for(SubSurface subSurface : subSurfaceList)
117 			for(int i = 0; i<4; i++) {
118 				Vector3d translationVector = new Vector3d();
119 				translationVector.sub(subSurface.getVertex(i), vertices[0]);
120 				double uDistance = translationVector.dot(widthVector) / widthVector.lengthSquared();
121 				double vDistance = translationVector.dot(heightVector) / heightVector.lengthSquared();
122 				
123 				Point2f uVector = new Point2f(uScale), vVector = new Point2f(vScale);
124 				if(!frontFace)
125 					uVector.negate();
126 				uVector.scale((float)uDistance);
127 				vVector.scale((float)vDistance);
128 				if(!frontFace)
129 					uVector.add(uScale);
130 				vVector.add(uVector);
131 				
132 				if(frontFace)
133 					subSurface.setTextureCoordinate(i, vVector, texNo);
134 				else
135 					subSurface.setTextureCoordinate(i+4, vVector, texNo);
136 			}
137 		
138 		return new TexCoord2f[3];
139 	}
140 	
141 	void createTextureCoords(Point2f[] texCoords, int texNo) {
142 		Vector2f uScale = new Vector2f(), vScale = new Vector2f();
143 		uScale.sub(texCoords[1], texCoords[0]);
144 		vScale.sub(texCoords[3], texCoords[0]);
145 		
146 		Vector3d widthVector = new Vector3d(), heightVector = new Vector3d();
147 		widthVector.sub(vertices[1], vertices[0]);
148 		heightVector.sub(vertices[3], vertices[0]);
149 		
150 		
151 		
152 		for(SubSurface subSurface : subSurfaceList) {
153 			for(int i = 0; i<4; i++) {
154 				Vector3d translationVector = new Vector3d();
155 				translationVector.sub(subSurface.getVertex(i), vertices[0]);
156 				double uDistance = translationVector.dot(widthVector) / widthVector.lengthSquared();
157 				double vDistance = translationVector.dot(heightVector) / heightVector.lengthSquared();
158 				Point2f uVector = new Point2f(uScale);
159 				uVector.scale((float)uDistance);
160 				Point2f vVector = new Point2f(vScale);
161 				vVector.scale((float)vDistance);
162 				vVector.add(uVector);
163 				subSurface.setTextureCoordinate(i, vVector, texNo);
164 				uVector = new Point2f(uScale);
165 				uVector.negate();
166 				uVector.scale((float)uDistance);
167 				uVector.add(uScale);
168 				vVector = new Point2f(vScale);
169 				vVector.scale((float)vDistance);
170 				vVector.add(uVector);
171 				subSurface.setTextureCoordinate(i+4, vVector, texNo);
172 			}
173 		}
174 	}
175 	
176 	BranchGroup createShape() {
177 		BranchGroup surface = new BranchGroup();
178 		
179 		try{
180 			int subNo = 0;
181 			for(SubSurface subSurface : subSurfaceList) {
182 				GeometryInfo[] subSurfaceGeometry = subSurface.createBox();
183 				BranchGroup subSurfaceGroup = new BranchGroup();
184 				for(int i=0; i<6; i++) {
185 					Shape3D shape = new Shape3D(subSurfaceGeometry[i].getGeometryArray(), AppearanceFactory.getInstance().newAppearance(surfaceID, i));
186 					shape.setUserData(surfaceID+" "+subNo+" "+i);
187 					subSurfaceGroup.addChild(shape);
188 				}
189 				
190 				surface.addChild(subSurfaceGroup);
191 				subNo++;
192 			}
193 		}
194 		catch (Exception e) {
195 			e.printStackTrace();
196 		}
197 		return surface;
198 	}
199 }