1
2
3
4
5
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 }