|
|
@@ -195,6 +195,10 @@ class RollerCoasterGeometry extends BufferGeometry {
|
|
|
|
|
|
const offset = new Vector3();
|
|
|
|
|
|
+ const sample1 = new Vector3();
|
|
|
+ const sample2 = new Vector3();
|
|
|
+ const rollQuaternion = new Quaternion();
|
|
|
+
|
|
|
for ( let i = 1; i <= divisions; i ++ ) {
|
|
|
|
|
|
point.copy( curve.getPointAt( i / divisions ) );
|
|
|
@@ -209,6 +213,20 @@ class RollerCoasterGeometry extends BufferGeometry {
|
|
|
|
|
|
quaternion.setFromAxisAngle( up, angle );
|
|
|
|
|
|
+ // banking
|
|
|
+
|
|
|
+ const bankDelta = 0.01;
|
|
|
+ const t = i / divisions;
|
|
|
+
|
|
|
+ sample1.copy( curve.getTangentAt( ( ( t - bankDelta ) % 1 + 1 ) % 1 ) );
|
|
|
+ sample2.copy( curve.getTangentAt( ( t + bankDelta ) % 1 ) );
|
|
|
+
|
|
|
+ let headingChange = Math.atan2( sample2.x, sample2.z ) - Math.atan2( sample1.x, sample1.z );
|
|
|
+ if ( headingChange > Math.PI ) headingChange -= Math.PI * 2;
|
|
|
+ if ( headingChange < -Math.PI ) headingChange += Math.PI * 2;
|
|
|
+
|
|
|
+ quaternion.premultiply( rollQuaternion.setFromAxisAngle( forward, - Math.atan( headingChange * 8 ) * 0.5 ) );
|
|
|
+
|
|
|
if ( i % 2 === 0 ) {
|
|
|
|
|
|
drawShape( step, color2 );
|
|
|
@@ -356,6 +374,11 @@ class RollerCoasterLiftersGeometry extends BufferGeometry {
|
|
|
const fromPoint = new Vector3();
|
|
|
const toPoint = new Vector3();
|
|
|
|
|
|
+ const sample1 = new Vector3();
|
|
|
+ const sample2 = new Vector3();
|
|
|
+ const bankedQuaternion = new Quaternion();
|
|
|
+ const rollQuaternion = new Quaternion();
|
|
|
+
|
|
|
for ( let i = 1; i <= divisions; i ++ ) {
|
|
|
|
|
|
point.copy( curve.getPointAt( i / divisions ) );
|
|
|
@@ -365,6 +388,22 @@ class RollerCoasterLiftersGeometry extends BufferGeometry {
|
|
|
|
|
|
quaternion.setFromAxisAngle( up, angle );
|
|
|
|
|
|
+ // banking
|
|
|
+
|
|
|
+ const bankDelta = 0.01;
|
|
|
+ const t = i / divisions;
|
|
|
+
|
|
|
+ sample1.copy( curve.getTangentAt( ( ( t - bankDelta ) % 1 + 1 ) % 1 ) );
|
|
|
+ sample2.copy( curve.getTangentAt( ( t + bankDelta ) % 1 ) );
|
|
|
+
|
|
|
+ let headingChange = Math.atan2( sample2.x, sample2.z ) - Math.atan2( sample1.x, sample1.z );
|
|
|
+ if ( headingChange > Math.PI ) headingChange -= Math.PI * 2;
|
|
|
+ if ( headingChange < -Math.PI ) headingChange += Math.PI * 2;
|
|
|
+
|
|
|
+ bankedQuaternion.copy( quaternion );
|
|
|
+ rollQuaternion.setFromAxisAngle( tangent, - Math.atan( headingChange * 8 ) * 0.5 );
|
|
|
+ bankedQuaternion.premultiply( rollQuaternion );
|
|
|
+
|
|
|
//
|
|
|
|
|
|
if ( point.y > 10 ) {
|
|
|
@@ -402,12 +441,11 @@ class RollerCoasterLiftersGeometry extends BufferGeometry {
|
|
|
} else {
|
|
|
|
|
|
fromPoint.set( 0, - 0.2, 0 );
|
|
|
- fromPoint.applyQuaternion( quaternion );
|
|
|
+ fromPoint.applyQuaternion( bankedQuaternion );
|
|
|
fromPoint.add( point );
|
|
|
|
|
|
- toPoint.set( 0, - point.y, 0 );
|
|
|
- toPoint.applyQuaternion( quaternion );
|
|
|
- toPoint.add( point );
|
|
|
+ toPoint.copy( fromPoint );
|
|
|
+ toPoint.y = 0;
|
|
|
|
|
|
extrudeShape( tube3, fromPoint, toPoint );
|
|
|
|