Normand Briere
2019-09-17 54adfcbf93eb477bedeec45409f36cf7e102b790
Navigation with intersection.
7 files modified
3 files added
733 ■■■■■ changed files
BBox.java 166 ●●●●● patch | view | raw | blame | history
Camera.java 2 ●●● patch | view | raw | blame | history
CameraPane.java 142 ●●●● patch | view | raw | blame | history
Globals.java 2 ●●●●● patch | view | raw | blame | history
GroupEditor.java 22 ●●●● patch | view | raw | blame | history
IntersectResult.java 48 ●●●●● patch | view | raw | blame | history
ObjEditor.java 4 ●●●● patch | view | raw | blame | history
Object3D.java 284 ●●●●● patch | view | raw | blame | history
Ray.java 55 ●●●●● patch | view | raw | blame | history
cMesh.java 8 ●●●●● patch | view | raw | blame | history
BBox.java
....@@ -0,0 +1,166 @@
1
+//package comp557.a5;
2
+
3
+import javax.vecmath.Point3d;
4
+
5
+public class BBox
6
+{
7
+
8
+ public Point3d max;
9
+ public Point3d min;
10
+
11
+ public BBox()
12
+ {
13
+ this.max = new Point3d(1, 1, 1);
14
+ this.min = new Point3d(-1, -1, -1);
15
+ }
16
+
17
+ public boolean intersect0(Ray ray, IntersectResult result)
18
+ {
19
+ // Reference: http://people.csail.mit.edu/amy/papers/box-jgt.pdf
20
+
21
+ double tmin, tmax, tymin, tymax, tzmin, tzmax;
22
+
23
+ double invDirX = 1 / ray.viewDirection.x;
24
+ double invDirY = 1 / ray.viewDirection.y;
25
+ double invDirZ = 1 / ray.viewDirection.z;
26
+
27
+ if (ray.viewDirection.x >= 1e-9)
28
+ {
29
+ tmin = (min.x - ray.eyePoint.x) * invDirX;
30
+ tmax = (max.x - ray.eyePoint.x) * invDirX;
31
+ } else
32
+ {
33
+ tmax = (min.x - ray.eyePoint.x) * invDirX;
34
+ tmin = (max.x - ray.eyePoint.x) * invDirX;
35
+ }
36
+
37
+ if (ray.viewDirection.y >= 1e-9)
38
+ {
39
+ tymin = (min.y - ray.eyePoint.y) * invDirY;
40
+ tymax = (max.y - ray.eyePoint.y) * invDirY;
41
+ } else
42
+ {
43
+ tymax = (min.y - ray.eyePoint.y) * invDirY;
44
+ tymin = (max.y - ray.eyePoint.y) * invDirY;
45
+ }
46
+
47
+ if ((tmin > tymax) || (tymin > tmax))
48
+ {
49
+ return false;
50
+ }
51
+
52
+ if (tymin > tmin)
53
+ {
54
+ tmin = tymin;
55
+ }
56
+
57
+ if (tymax < tmax)
58
+ {
59
+ tmax = tymax;
60
+ }
61
+
62
+ if (ray.viewDirection.z >= 1e-9)
63
+ {
64
+ tzmin = (min.z - ray.eyePoint.z) * invDirZ;
65
+ tzmax = (max.z - ray.eyePoint.z) * invDirZ;
66
+ } else
67
+ {
68
+ tzmax = (min.z - ray.eyePoint.z) * invDirZ;
69
+ tzmin = (max.z - ray.eyePoint.z) * invDirZ;
70
+ }
71
+
72
+ if ((tmin > tzmax) || (tzmin > tmax))
73
+ {
74
+ return false;
75
+ }
76
+
77
+// result.isIntersected = true;
78
+//
79
+// if (tzmin > tmin)
80
+// {
81
+// tmin = tzmin;
82
+// }
83
+//
84
+// if (tzmax < tmax)
85
+// {
86
+// tmax = tzmax;
87
+// }
88
+//
89
+// if (tmin > 1e-9)
90
+// {
91
+// result.t = tmin;
92
+// } else
93
+// {
94
+// result.t = tmax;
95
+// }
96
+
97
+ return true;
98
+ }
99
+
100
+ public boolean intersect(Ray ray, IntersectResult result)
101
+ {
102
+ double tmin = Double.NEGATIVE_INFINITY, tmax = Double.POSITIVE_INFINITY;
103
+
104
+ double t1 = (min.x - ray.eyePoint.x) / ray.viewDirection.x;
105
+ double t2 = (max.x - ray.eyePoint.x) / ray.viewDirection.x;
106
+
107
+ double mint = t1;
108
+ if (mint > t2) mint = t2;
109
+
110
+ double maxt = t1;
111
+ if (maxt < t2) maxt = t2;
112
+
113
+ if (ray.viewDirection.x == 0)
114
+ {
115
+ if (ray.eyePoint.x <= min.x || ray.eyePoint.x >= max.x)
116
+ return false;
117
+ }
118
+ else
119
+ {
120
+ if (tmin > mint) tmin = mint;
121
+ if (tmax < maxt) tmax = maxt;
122
+ }
123
+
124
+ t1 = (min.y - ray.eyePoint.y) / ray.viewDirection.y;
125
+ t2 = (max.y - ray.eyePoint.y) / ray.viewDirection.y;
126
+
127
+ mint = t1;
128
+ if (mint > t2) mint = t2;
129
+
130
+ maxt = t1;
131
+ if (maxt < t2) maxt = t2;
132
+
133
+ if (ray.viewDirection.y == 0)
134
+ {
135
+ if (ray.eyePoint.y <= min.y || ray.eyePoint.y >= max.y)
136
+ return false;
137
+ }
138
+ else
139
+ {
140
+ if (tmin > mint) tmin = mint;
141
+ if (tmax < maxt) tmax = maxt;
142
+ }
143
+
144
+ t1 = (min.z - ray.eyePoint.z) / ray.viewDirection.z;
145
+ t2 = (max.z - ray.eyePoint.z) / ray.viewDirection.z;
146
+
147
+ mint = t1;
148
+ if (mint > t2) mint = t2;
149
+
150
+ maxt = t1;
151
+ if (maxt < t2) maxt = t2;
152
+
153
+ if (ray.viewDirection.z == 0)
154
+ {
155
+ if (ray.eyePoint.z <= min.z || ray.eyePoint.z >= max.z)
156
+ return false;
157
+ }
158
+ else
159
+ {
160
+ if (tmin > mint) tmin = mint;
161
+ if (tmax < maxt) tmax = maxt;
162
+ }
163
+
164
+ return tmax > tmin && tmax > 0.0;
165
+ }
166
+}
Camera.java
....@@ -302,7 +302,7 @@
302302 }
303303 else
304304 if (//shaper_fovy < 180 && factor > 1 ||
305
- shaper_fovy * factor < 180)
305
+ shaper_fovy * factor < 150)
306306 {
307307 shaper_fovy *= factor;
308308 //System.out.println("fovy = " + shaper_fovy);
CameraPane.java
....@@ -134,7 +134,7 @@
134134 static boolean ZOOMBOXMODE = false;
135135 static boolean BOXMODE = false;
136136 static boolean IMAGEFLIP = false;
137
-static boolean SMOOTHFOCUS = false;
137
+static boolean SMOOTHFOCUS = true; // false;
138138 static boolean SPEAKERMOCAP = true; // jan 2014 false;
139139 static boolean SPEAKERCAMERA = false;
140140 static boolean SPEAKERFOCUS = false;
....@@ -2109,7 +2109,7 @@
21092109 // Start with free camera
21102110 SwitchCameras(true);
21112111
2112
- pingthread.jump = true; // optional?
2112
+// pingthread.jump = true; // optional?
21132113
21142114 if (TRACKONCE)
21152115 {
....@@ -2296,18 +2296,6 @@
22962296 public void ToggleTrack()
22972297 {
22982298 TRACK ^= true;
2299
- if (TRACK)
2300
- {
2301
- if (object.selection != null &&
2302
- object.selection.size() > 0 &&
2303
- object.selection.elementAt(0) != null &&
2304
- !(object.selection.elementAt(0) instanceof Camera) &&
2305
- !(object.selection.elementAt(0) instanceof ScriptNode))
2306
- {
2307
- trackedobject = object.selection.elementAt(0);
2308
- repaint();
2309
- }
2310
- }
23112299
23122300 repaint();
23132301 }
....@@ -10916,6 +10904,12 @@
1091610904 else
1091710905 speedkey[RIGHT_ARROW] = 0;
1091810906
10907
+ if (Globals.WALK && capsLocked)
10908
+ {
10909
+ Walk();
10910
+ keyon = true;
10911
+ }
10912
+
1091910913 if (keyon)
1092010914 {
1092110915 repaint();
....@@ -11870,7 +11864,7 @@
1187011864 repaint();
1187111865 }
1187211866
11873
- if (Globals.isLIVE() && DrawMode() == DEFAULT) // may 2013
11867
+ if (Globals.isLIVE() && DrawMode() == DEFAULT || pingthread.live) // may 2013
1187411868 repaint();
1187511869
1187611870 displaydone = true;
....@@ -11946,9 +11940,23 @@
1194611940 //GL gl = getGL();
1194711941 if ((TRACK || SHADOWTRACK) || zoomonce)
1194811942 {
11943
+ if (TRACK)
11944
+ {
11945
+ if (object.selection != null &&
11946
+ object.selection.size() > 0 &&
11947
+ object.selection.elementAt(0) != null &&
11948
+ !(object.selection.elementAt(0) instanceof Camera) &&
11949
+ !(object.selection.elementAt(0) instanceof ScriptNode))
11950
+ {
11951
+ trackedobject = object.selection.elementAt(0);
11952
+ //repaint();
11953
+ }
11954
+ else
11955
+ trackedobject = null;
11956
+ }
1194911957 if ((TRACK || SHADOWTRACK) && trackedobject != null && DrawMode() == SHADOW) // && !lightMode)
1195011958 object.GetWindow().ScreenFit(trackedobject, SHADOWTRACK && !TRACK);
11951
- pingthread.StepToTarget(true); // true);
11959
+ pingthread.StepToTarget(); // true);
1195211960 // zoomonce = false;
1195311961 }
1195411962
....@@ -14508,8 +14516,9 @@
1450814516 // fev 2014???
1450914517 if ((TRACK || SHADOWTRACK) && trackedobject != null) // && DrawMode() == SHADOW) // && !lightMode)
1451014518 object.GetWindow().ScreenFit(trackedobject, SHADOWTRACK && !TRACK);
14511
- pingthread.StepToTarget(true); // true);
14519
+ pingthread.StepToTarget(); // true);
1451214520 }
14521
+
1451314522 // if (!LIVE)
1451414523 super.repaint();
1451514524 }
....@@ -14629,9 +14638,15 @@
1462914638 return targetLookAt;
1463014639 }
1463114640
14641
+ javax.vecmath.Point3d eye = new javax.vecmath.Point3d();
14642
+ javax.vecmath.Point3d eye2 = new javax.vecmath.Point3d();
14643
+ javax.vecmath.Vector3d dir = new javax.vecmath.Vector3d();
14644
+
14645
+
1463214646 class PingThread extends Thread
1463314647 {
1463414648 boolean jump;
14649
+ boolean live;
1463514650
1463614651 boolean mute;
1463714652
....@@ -14651,6 +14666,70 @@
1465114666 {
1465214667 if (mute)
1465314668 return;
14669
+
14670
+ if (capsLocked)
14671
+ {
14672
+ eye.x = manipCamera.location.x;
14673
+ eye.y = manipCamera.location.y + 0.25;
14674
+ eye.z = manipCamera.location.z;
14675
+
14676
+ dir.y = -1;
14677
+
14678
+ Ray ray = new Ray(eye, dir);
14679
+
14680
+ IntersectResult res = new IntersectResult();
14681
+ res.t = Double.POSITIVE_INFINITY;
14682
+
14683
+ tmp.set(targetLookAt);
14684
+ tmp.sub(manipCamera.location);
14685
+
14686
+ double dist = tmp.length();
14687
+
14688
+ tmp.normalize();
14689
+
14690
+ eye2.x = manipCamera.location.x + tmp.x * 0.25;
14691
+ eye2.y = manipCamera.location.y + 0.25;
14692
+ eye2.z = manipCamera.location.z + tmp.z * 0.25;
14693
+
14694
+ Ray ray2 = new Ray(eye2, dir);
14695
+
14696
+ IntersectResult res2 = new IntersectResult();
14697
+ res2.t = Double.POSITIVE_INFINITY;
14698
+
14699
+ if (object.intersect(ray, res) && object.intersect(ray2, res2) && Math.abs(res.t - res2.t) < 0.25)
14700
+ {
14701
+ //tmp.set(manipCamera.location);
14702
+
14703
+ manipCamera.location.x = ray.eyePoint.x + ray.viewDirection.x * res.t;
14704
+ manipCamera.location.y = ray.eyePoint.y + ray.viewDirection.y * res.t + 0.5;
14705
+ manipCamera.location.z = ray.eyePoint.z + ray.viewDirection.z * res.t;
14706
+
14707
+ //tmp.sub(manipCamera.location);
14708
+
14709
+ targetLookAt.x = ray2.eyePoint.x + ray2.viewDirection.x * res2.t;
14710
+ targetLookAt.y = ray2.eyePoint.y + ray2.viewDirection.y * res2.t + 0.5;
14711
+ targetLookAt.z = ray2.eyePoint.z + ray2.viewDirection.z * res2.t;
14712
+
14713
+ targetLookAt.sub(manipCamera.location);
14714
+ targetLookAt.normalize();
14715
+ targetLookAt.mul(dist);
14716
+ targetLookAt.add(manipCamera.location);
14717
+
14718
+ //if (tmp.dot(tmp) > 0.000001)
14719
+ // System.out.println("INTERSECTION " + manipCamera.location);
14720
+
14721
+ manipCamera.lookAt.set(targetLookAt);
14722
+
14723
+ tmp.x = res.n.x;
14724
+ tmp.y = res.n.y;
14725
+ tmp.z = res.n.z;
14726
+ tmp.x += res2.n.x;
14727
+ tmp.y += res2.n.y;
14728
+ tmp.z += res2.n.z;
14729
+ tmp.normalize();
14730
+ manipCamera.UP.set(tmp);
14731
+ }
14732
+ }
1465414733
1465514734 tmp.set(targetLookAt);
1465614735 tmp.sub(manipCamera.lookAt); // june 2014
....@@ -14689,7 +14768,7 @@
1468914768
1469014769 if (tmp.dot(tmp) > 1) // may 2014. far away: jump to target
1469114770 {
14692
- jump = true; // step = 1;
14771
+ // sep 2019 jump = true; // step = 1;
1469314772 }
1469414773
1469514774 if (OEILONCE && OEIL)
....@@ -14724,7 +14803,10 @@
1472414803 if (tmp.dot(tmp) < 0.00001)
1472514804 {
1472614805 zoomonce = false;
14806
+ live = false;
1472714807 }
14808
+ else
14809
+ live = true;
1472814810
1472914811 tmp.mul(step > step2 ? step : step2);
1473014812 }
....@@ -14866,8 +14948,16 @@
1486614948 PingThread pingthread = new PingThread();
1486714949 int delta = 1;
1486814950 int speed = 1;
14951
+ int walk = 8;
1486914952 boolean autorepeat = false;
1487014953
14954
+ void Walk()
14955
+ {
14956
+ manipCamera.BackForth(0, walk, 1000);
14957
+
14958
+ targetLookAt.set(manipCamera.lookAt);
14959
+ }
14960
+
1487114961 void GoDown(int mod)
1487214962 {
1487314963 MODIFIERS |= COMMAND;
....@@ -15869,17 +15959,23 @@
1586915959 object.GetWindow().refreshContents(true);
1587015960 break;
1587115961 case '{':
15872
- manipCamera.shaper_fovy /= 1.1;
15962
+ double factor = 1.1;
15963
+ if (manipCamera.shaper_fovy / factor > 0.1)
15964
+ manipCamera.shaper_fovy /= factor;
1587315965 System.out.println("FOV = " + manipCamera.shaper_fovy);
1587415966 repaint();
1587515967 break;
1587615968 case '}':
15877
- manipCamera.shaper_fovy *= 1.1;
15969
+ factor = 1.1;
15970
+ if (manipCamera.shaper_fovy * factor < 150)
15971
+ manipCamera.shaper_fovy *= factor;
1587815972 System.out.println("FOV = " + manipCamera.shaper_fovy);
1587915973 repaint();
1588015974 break;
1588115975 case '[':
15882
- manipCamera.shaper_fovy /= 1.01;
15976
+ factor = 1.01;
15977
+ if (manipCamera.shaper_fovy / factor > 0.1)
15978
+ manipCamera.shaper_fovy /= factor;
1588315979 if (false) //manipCamera.hAspect == 0)
1588415980 {
1588515981 double x = Math.tan(manipCamera.shaper_fovy * Math.PI / 180 / 2);
....@@ -15895,7 +15991,9 @@
1589515991 break;
1589615992 case ']':
1589715993 //manipCamera.shaper_fovy += (180 - manipCamera.shaper_fovy)*0.1;
15898
- manipCamera.shaper_fovy *= 1.01;
15994
+ factor = 1.01;
15995
+ if (manipCamera.shaper_fovy * factor < 150)
15996
+ manipCamera.shaper_fovy *= factor;
1589915997 if (false) //manipCamera.hAspect == 0)
1590015998 {
1590115999 double x = Math.tan(manipCamera.shaper_fovy * Math.PI / 180 / 2);
Globals.java
....@@ -1,6 +1,8 @@
11
22 public class Globals
33 {
4
+ static boolean WALK = false;
5
+
46 static boolean SHOWINFO = true;
57
68 static boolean ADVANCED = false; // false;
GroupEditor.java
....@@ -1404,7 +1404,7 @@
14041404 // supportCB.setToolTipText("Enable rigging");
14051405 // supportCB.addItemListener(this);
14061406
1407
- panel.add(freezeCB = new cCheckBox("Freeze", Globals.FREEZEONMOVE)); //, constraints);
1407
+ panel.add(freezeCB = new cCheckBox("Fast cam", Globals.FREEZEONMOVE)); //, constraints);
14081408 freezeCB.setToolTipText("Fast moving camera");
14091409 freezeCB.addItemListener(this);
14101410
....@@ -1413,9 +1413,12 @@
14131413
14141414 panel.Return();
14151415
1416
+ if (Globals.ADVANCED)
1417
+ {
14161418 panel.add(crowdCB = new cCheckBox("Crowd", Globals.CROWD)); //, constraints);
14171419 crowdCB.setToolTipText("Used for crowds");
14181420 crowdCB.addItemListener(this);
1421
+ }
14191422
14201423 panel.add(smoothCB = new cCheckBox("Inertia", CameraPane.INERTIA)); //, constraints);
14211424 smoothCB.setToolTipText("Snapping delay");
....@@ -1428,30 +1431,26 @@
14281431 minshaderCB.setToolTipText("Minimal fast shader");
14291432 minshaderCB.addItemListener(this);
14301433
1431
-// constraints.gridy += 1;
14321434 // panel.add(speakerMocapCB = new cCheckBox("Mocap", CameraPane.SPEAKERMOCAP), constraints);
14331435 // speakerMocapCB.addItemListener(this);
14341436
1435
- panel.Return();
1436
-
14371437 if (false)
14381438 {
14391439 // handled in scripts
1440
- //constraints.gridy += 1;
14411440 panel.add(speakerCameraCB = new cCheckBox("Cam", CameraPane.SPEAKERCAMERA)); //, constraints);
14421441 speakerCameraCB.addItemListener(this);
14431442
1444
- //constraints.gridy += 1;
14451443 panel.add(speakerFocusCB = new cCheckBox("Focus", CameraPane.SPEAKERFOCUS)); //, constraints);
14461444 speakerFocusCB.addItemListener(this);
14471445
1448
- //constraints.gridy += 1;
1449
- panel.add(smoothfocusCB = new cCheckBox("Smooth", CameraPane.SMOOTHFOCUS)); //, constraints);
1450
- smoothfocusCB.addItemListener(this);
14511446 panel.Return();
14521447 }
14531448
1454
-//constraints.gridx += 1;
1449
+ panel.add(smoothfocusCB = new cCheckBox("Smooth", CameraPane.SMOOTHFOCUS)); //, constraints);
1450
+ smoothfocusCB.addItemListener(this);
1451
+
1452
+ panel.Return();
1453
+
14551454 //panel.add(debugCB = new cCheckBox("Debug", CameraPane.DEBUG), constraints);
14561455 // debugCB.addItemListener(this);
14571456
....@@ -2090,7 +2089,7 @@
20902089 Object3D obj = (Object3D)group.selection.elementAt(0);
20912090 objEditor.ScreenFit(obj, false);
20922091
2093
- cameraView.pingthread.StepToTarget(true);
2092
+ cameraView.pingthread.StepToTarget(); //true);
20942093 refreshContents();
20952094 }
20962095
....@@ -4874,6 +4873,7 @@
48744873 LA.matTranslateInv(obj.fromParent, -i * scale, 0, 0);
48754874 }
48764875
4876
+ Globals.lighttouched = true;
48774877 refreshContents();
48784878 }
48794879
IntersectResult.java
....@@ -0,0 +1,48 @@
1
+//package comp557.a5;
2
+
3
+import javax.vecmath.Point3d;
4
+import javax.vecmath.Vector3d;
5
+
6
+/**
7
+ * Use this class to store the result of an intersection.
8
+ */
9
+public class IntersectResult
10
+{
11
+
12
+ /** The normal at the intersection */
13
+ public Vector3d n = new Vector3d();
14
+
15
+ /** Intersection position */
16
+ //public Point3d p = new Point3d();
17
+
18
+ /** The object of the intersection */
19
+ public Object3D object = null;
20
+
21
+ /** Parameter on the ray giving the position of the intersection */
22
+ public double t = Double.POSITIVE_INFINITY;
23
+
24
+ //public boolean isIntersected = false;
25
+ //public int id = -1;
26
+
27
+ // UV Coordinates of the object
28
+ public double u = Double.NaN;
29
+ public double v = Double.NaN;
30
+
31
+ /**
32
+ * Default constructor.
33
+ */
34
+ IntersectResult()
35
+ {
36
+ // do nothing
37
+ }
38
+
39
+ /**
40
+ * Copy constructor.
41
+ */
42
+ IntersectResult(IntersectResult other)
43
+ {
44
+ n.set(other.n);
45
+ //p.set(other.p);
46
+ t = other.t;
47
+ }
48
+}
ObjEditor.java
....@@ -5715,7 +5715,7 @@
57155715 interest.y = k * interest.y + (1 - k) * height;
57165716 }
57175717
5718
- CameraPane.zoomonce = true;
5718
+ // CameraPane.zoomonce = true;
57195719
57205720 // june 2014
57215721 Camera parentcam = cameraView.manipCamera;
....@@ -5789,7 +5789,7 @@
57895789
57905790 objEditor.ScreenFit(obj, false);
57915791
5792
- cameraView.pingthread.StepToTarget(true); // aout 2013
5792
+ cameraView.pingthread.StepToTarget(); //true); // aout 2013
57935793 refreshContents();
57945794 }
57955795
Object3D.java
....@@ -662,7 +662,7 @@
662662 {
663663 sorted = true;
664664
665
- for (int i=0; i<size()-1; i++)
665
+ for (int i=0; i<Size()-1; i++)
666666 {
667667 Object3D obji = get(i);
668668 Object3D objj = get(i+1);
....@@ -686,7 +686,7 @@
686686 {
687687 sorted = true;
688688
689
- for (int i=0; i<size()-1; i++)
689
+ for (int i=0; i<Size()-1; i++)
690690 {
691691 Object3D obji = get(i);
692692 Object3D objj = get(i+1);
....@@ -4048,6 +4048,7 @@
40484048
40494049 void RevertMeshes()
40504050 {
4051
+ // BLOCKLOOP
40514052 if (this instanceof cMesh)
40524053 {
40534054 ((cMesh)this).Revert();
....@@ -4078,11 +4079,6 @@
40784079 Touch();
40794080 }
40804081
4081
- ResetRecur();
4082
- }
4083
-
4084
- void ResetRecur()
4085
- {
40864082 for (int i = 0; i < size(); i++)
40874083 {
40884084 Object3D child = (Object3D) get(i); // reserve(i);
....@@ -4296,8 +4292,8 @@
42964292 Touch();
42974293 }
42984294
4299
- transient cVector min = new cVector();
4300
- transient cVector max = new cVector();
4295
+ transient cVector min;
4296
+ transient cVector max;
43014297
43024298 void getBounds(cVector minima, cVector maxima, boolean xform)
43034299 {
....@@ -4313,7 +4309,7 @@
43134309 if (blockloop)
43144310 return;
43154311
4316
- if (min == null) // ???
4312
+ if (min == null)
43174313 {
43184314 min = new cVector();
43194315 max = new cVector();
....@@ -4354,7 +4350,7 @@
43544350
43554351 if (bRep != null)
43564352 {
4357
- bRep.getBounds(minima,maxima,this);
4353
+ bRep.getBounds(minima, maxima, xform?this:null);
43584354 }
43594355
43604356 if (false) // xform)
....@@ -8571,8 +8567,8 @@
85718567 private static cVector2 qq2 = new cVector2();
85728568 private static cVector2 rr2 = new cVector2();
85738569 private static cVector2 ss2 = new cVector2();
8574
- private static cVector edge1 = new cVector();
8575
- private static cVector edge2 = new cVector();
8570
+// private static cVector edge1 = new cVector();
8571
+// private static cVector edge2 = new cVector();
85768572 //private static cVector norm = new cVector();
85778573 /*transient private*/ int hitSomething;
85788574 static final int hitCenter = 1;
....@@ -8770,7 +8766,269 @@
87708766
87718767 Touch();
87728768 }
8769
+
8770
+ static Vertex s1 = new Vertex();
8771
+ static Vertex s2 = new Vertex();
8772
+ static Vertex s3 = new Vertex();
87738773
8774
+ boolean intersectMesh(Ray ray, IntersectResult result)
8775
+ {
8776
+ boolean success = false;
8777
+
8778
+ if (bRep.stripified)
8779
+ {
8780
+ int[] strips = bRep.getRawIndices();
8781
+
8782
+ // TRIANGLE STRIP ARRAY
8783
+ if (bRep.trimmed)
8784
+ {
8785
+ float[] v = bRep.getRawVertices();
8786
+
8787
+ int count3 = 0;
8788
+
8789
+ if (v.length > 0)
8790
+ {
8791
+ for (int i = 0; i < strips.length; i++)
8792
+ {
8793
+ s1.set(v[count3], v[count3 + 1], v[count3 + 2]);
8794
+ count3 += 3;
8795
+
8796
+ s2.set(v[count3], v[count3 + 1], v[count3 + 2]);
8797
+ count3 += 3;
8798
+
8799
+ for (int j = 0; j < strips[i] - 2; j++)
8800
+ {
8801
+ s3.set(v[count3], v[count3 + 1], v[count3 + 2]);
8802
+ count3 += 3;
8803
+
8804
+ if (j%2 == 0)
8805
+ success |= intersectTriangle(ray, result, s1, s2, s3);
8806
+ else
8807
+ success |= intersectTriangle(ray, result, s1, s3, s2);
8808
+
8809
+ s1.set(s2);
8810
+ s2.set(s3);
8811
+ }
8812
+ }
8813
+ }
8814
+
8815
+ assert count3 == v.length;
8816
+ }
8817
+ else // !trimmed
8818
+ {
8819
+ int count = 0;
8820
+ for (int i = 0; i < strips.length; i++)
8821
+ {
8822
+ Vertex p = bRep.GetVertex(bRep.indices[count++]);
8823
+ Vertex q = bRep.GetVertex(bRep.indices[count++]);
8824
+
8825
+ for (int j = 0; j < strips[i] - 2; j++)
8826
+ {
8827
+ Vertex r = bRep.GetVertex(bRep.indices[count++]);
8828
+
8829
+ if (j%2 == 0)
8830
+ success |= intersectTriangle(ray, result, p, q, r);
8831
+ else
8832
+ success |= intersectTriangle(ray, result, p, r, q);
8833
+
8834
+ p = q;
8835
+ q = r;
8836
+ }
8837
+ }
8838
+ }
8839
+ } else // catch (Error e)
8840
+ {
8841
+ int facecount = bRep.FaceCount();
8842
+ for (int i = 0; i < facecount; i++)
8843
+ {
8844
+ Face face = bRep.GetFace(i);
8845
+
8846
+ Vertex p = bRep.GetVertex(face.p);
8847
+ Vertex q = bRep.GetVertex(face.q);
8848
+ Vertex r = bRep.GetVertex(face.r);
8849
+
8850
+ success |= intersectTriangle(ray, result, p, q, r);
8851
+ }
8852
+ }
8853
+
8854
+ return success;
8855
+ }
8856
+
8857
+ static cVector eye = new cVector();
8858
+ static cVector dir = new cVector();
8859
+
8860
+ transient BBox bbox = null;
8861
+
8862
+ boolean intersect(Ray ray, IntersectResult result)
8863
+ {
8864
+ double eyex = ray.eyePoint.x;
8865
+ double eyey = ray.eyePoint.y;
8866
+ double eyez = ray.eyePoint.z;
8867
+
8868
+ double dirx = ray.viewDirection.x;
8869
+ double diry = ray.viewDirection.y;
8870
+ double dirz = ray.viewDirection.z;
8871
+
8872
+ if (this.fromParent != null)
8873
+ {
8874
+ eye.x = eyex;
8875
+ eye.y = eyey;
8876
+ eye.z = eyez;
8877
+ dir.x = dirx;
8878
+ dir.y = diry;
8879
+ dir.z = dirz;
8880
+
8881
+ LA.xformPos(eye, this.fromParent, eye);
8882
+ LA.xformDir(dir, this.fromParent, dir);
8883
+
8884
+ ray.eyePoint.x = eye.x;
8885
+ ray.eyePoint.y = eye.y;
8886
+ ray.eyePoint.z = eye.z;
8887
+
8888
+ ray.viewDirection.x = dir.x;
8889
+ ray.viewDirection.y = dir.y;
8890
+ ray.viewDirection.z = dir.z;
8891
+ }
8892
+
8893
+ boolean success = false;
8894
+
8895
+ boolean touch = false;
8896
+
8897
+ if (bRep != null)
8898
+ {
8899
+ if (bbox == null)
8900
+ {
8901
+ bbox = new BBox();
8902
+
8903
+ cVector min = new cVector();
8904
+ cVector max = new cVector();
8905
+
8906
+ this.getBounds(min, max, false);
8907
+
8908
+ bbox.min.x = min.x;
8909
+ bbox.min.y = min.y;
8910
+ bbox.min.z = min.z;
8911
+
8912
+ bbox.max.x = max.x;
8913
+ bbox.max.y = max.y;
8914
+ bbox.max.z = max.z;
8915
+ }
8916
+
8917
+ if (bbox.intersect(ray, result))
8918
+ {
8919
+ success |= intersectMesh(ray, result);
8920
+ }
8921
+ else
8922
+ {
8923
+ //this.hide = true;
8924
+ touch = true;
8925
+ }
8926
+ }
8927
+
8928
+ for (int i=0; i<size(); i++)
8929
+ {
8930
+ Object3D child = (Object3D) reserve(i);
8931
+
8932
+ if (child == null)
8933
+ continue;
8934
+
8935
+ success |= child.intersect(ray, result);
8936
+ release(i);
8937
+ }
8938
+
8939
+ ray.eyePoint.x = eyex;
8940
+ ray.eyePoint.y = eyey;
8941
+ ray.eyePoint.z = eyez;
8942
+
8943
+ ray.viewDirection.x = dirx;
8944
+ ray.viewDirection.y = diry;
8945
+ ray.viewDirection.z = dirz;
8946
+
8947
+// if (touch)
8948
+// this.Touch(); // refresh display list
8949
+
8950
+ return success;
8951
+ }
8952
+
8953
+ static Vector3d edge1 = new Vector3d();
8954
+ static Vector3d edge2 = new Vector3d();
8955
+ static Vector3d P = new Vector3d();
8956
+ static Vector3d T = new Vector3d();
8957
+ static Vector3d Q = new Vector3d();
8958
+
8959
+ private boolean intersectTriangle(Ray ray, IntersectResult result, Vertex v1, Vertex v2, Vertex v3)
8960
+ {
8961
+ /*
8962
+ Fast, Minimum Storage Ray/Triangle Intersection, Moller et al.
8963
+
8964
+ Reference: http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
8965
+ */
8966
+
8967
+ // Calculate edges of the triangle
8968
+ edge1.set(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z);
8969
+ edge2.set(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z);
8970
+
8971
+ // Calculate the determinant (U parameter)
8972
+ P.cross(ray.viewDirection, edge2);
8973
+ double det = edge1.dot(P);
8974
+
8975
+ if (det > -1e-9 && det < 1e-9)
8976
+ {
8977
+ return false;
8978
+ } // Ray lies in plane of triangle
8979
+
8980
+ double invDet = 1 / det;
8981
+
8982
+ // Calculate distance from vertex1 to ray origin
8983
+ T.set(ray.eyePoint.x - v1.x, ray.eyePoint.y - v1.y, ray.eyePoint.z - v1.z);
8984
+
8985
+ double U = (T.dot(P)) * invDet; // Calculate U parameter
8986
+
8987
+ if (U < 0.f || U > 1.f)
8988
+ {
8989
+ return false;
8990
+ } // Intersection lies outside of the triangle
8991
+
8992
+ // Calculate V parameter
8993
+ Q.cross(T, edge1);
8994
+
8995
+ double V = ray.viewDirection.dot(Q) * invDet;
8996
+
8997
+ if (V < 0.f || (U + V) > 1.f)
8998
+ {
8999
+ return false;
9000
+ } // Intersection lies outside of the triangle
9001
+
9002
+ double t = edge2.dot(Q) * invDet;
9003
+
9004
+ if (t > 1e-9) // Triangle and ray intersects
9005
+ {
9006
+ //result.isIntersected = true;
9007
+ //result.id = id;
9008
+
9009
+ if (false) // isShadow)
9010
+ {
9011
+ result.t = t;
9012
+ return true;
9013
+ } else if (t < result.t)
9014
+ {
9015
+ result.object = this;
9016
+
9017
+ result.t = t;
9018
+
9019
+ //result.p.x = ray.eyePoint.x + ray.viewDirection.x * t;
9020
+ //result.p.y = ray.eyePoint.y + ray.viewDirection.y * t;
9021
+ //result.p.z = ray.eyePoint.z + ray.viewDirection.z * t;
9022
+
9023
+ result.n.cross(edge1, edge2);
9024
+ result.n.normalize();
9025
+ }
9026
+
9027
+ return true;
9028
+ }
9029
+
9030
+ return false;
9031
+ }
87749032
87759033 public int Size()
87769034 {
Ray.java
....@@ -0,0 +1,55 @@
1
+//package comp557.a5;
2
+
3
+import javax.vecmath.Point3d;
4
+import javax.vecmath.Vector3d;
5
+
6
+public class Ray
7
+{
8
+
9
+ /** Originating point for the ray */
10
+ public Point3d eyePoint = new Point3d(0, 0, 0);
11
+ /** The direction of the ray */
12
+ public Vector3d viewDirection = new Vector3d(0, 0, -1);
13
+
14
+ /**
15
+ * Default constructor. Be careful not to use the ray before
16
+ * setting the eye point and view direction!
17
+ */
18
+ public Ray()
19
+ {
20
+ // do nothing
21
+ }
22
+
23
+ /**
24
+ * Creates a new ray with the given eye point and view direction
25
+ * @param eyePoint
26
+ * @param viewDirection
27
+ */
28
+ public Ray(Point3d eyePoint, Vector3d viewDirection)
29
+ {
30
+ this.eyePoint.set(eyePoint);
31
+ this.viewDirection.set(viewDirection);
32
+ }
33
+
34
+ /**
35
+ * Setup the ray.
36
+ * @param eyePoint
37
+ * @param viewDirection
38
+ */
39
+ public void set(Point3d eyePoint, Vector3d viewDirection)
40
+ {
41
+ this.eyePoint.set(eyePoint);
42
+ this.viewDirection.set(viewDirection);
43
+ }
44
+
45
+ /**
46
+ * Computes the location of a point along the ray using parameter t.
47
+ * @param t
48
+ * @param p
49
+ */
50
+ public void getPoint(double t, Point3d p) // After the intersection, you will call this method to get the intersection point
51
+ {
52
+ p.scale(t, viewDirection);
53
+ p.add(eyePoint);
54
+ }
55
+}
cMesh.java
....@@ -417,12 +417,14 @@
417417 ref.count = 1;
418418
419419 Object3D obj = ref.GetObject();
420
+ Object3D par = obj.parent;
421
+ obj.parent = null;
420422
421423 // may 2014: side-effect with UVs!!
422
- obj = (Object3D) Grafreed.clone(obj);
423
-
424
- merge(obj);
424
+ merge((Object3D) Grafreed.clone(obj));
425425
426
+ obj.parent = par;
427
+
426428 ref.count = keepcount;
427429
428430 System.out.println("RESULT " + ref + "; #vertices = " + bRep.VertexCount() + "; #faces = " + bRep.FaceCount());