1 import * as THREE from 'three'; 2 3 import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; 4 import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js'; 5 6 let railsPath; 7 8 export const railsFoundationShape = new THREE.CatmullRomCurve3([ 9 new THREE.Vector3( -2.00, 0.00, 0.00), 10 new THREE.Vector3( -1.00, 0.00, 0.50), 11 new THREE.Vector3( 0.00, 0.00, 0.55), 12 new THREE.Vector3( 1.00, 0.00, 0.50), 13 new THREE.Vector3( 2.00, 0.00, 0.00), 14 ], false); 15 16 export function getRailsPathPosAt(t) { 17 if(railsPath == undefined) { 18 console.log("railsPath is undefined"); 19 } 20 return [railsPath.getPointAt(t), railsPath.getTangentAt(t)]; 21 } 22 23 function parametricRailsFoundationFunction(u, v, target) { 24 const rotMatrix = new THREE.Matrix4(); 25 const translationMatrix = new THREE.Matrix4(); 26 const levelMatrix = new THREE.Matrix4(); 27 28 let railsPathPos = railsPath.getPointAt(v); 29 let railsFoundationShapePos = railsFoundationShape.getPointAt(u); 30 // TODO: make `railsFoundationShape` smaller and remove this multiplication 31 railsFoundationShapePos.multiplyScalar(0.5); 32 railsFoundationShapePos.x *= 1.25; 33 34 let tangente = new THREE.Vector3(); 35 let binormal = new THREE.Vector3(); 36 let normal = new THREE.Vector3(); 37 38 tangente = railsPath.getTangent(v); 39 40 tangente.normalize(); 41 binormal = new THREE.Vector3(0, 1, 0); 42 normal.crossVectors(tangente, binormal); 43 44 translationMatrix.makeTranslation(railsPathPos); 45 46 rotMatrix.identity(); 47 levelMatrix.identity(); 48 49 levelMatrix.makeTranslation(railsPathPos); 50 rotMatrix.makeBasis(normal, tangente, binormal); 51 levelMatrix.multiply(rotMatrix); 52 railsFoundationShapePos.applyMatrix4(levelMatrix); 53 54 const x = railsFoundationShapePos.x; 55 const y = railsFoundationShapePos.y; 56 const z = railsFoundationShapePos.z; 57 target.set(x, y, z); 58 } 59 60 // devuelve la geometria del terraplen de la via 61 export function buildRailsFoundationGeometry() { 62 /* 63 // show rails foundation shape 64 const points = railsFoundationShape.getPoints(50); 65 const geometry = new THREE.BufferGeometry().setFromPoints(points); 66 const lineMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); 67 const curveObject = new THREE.Line(geometry, lineMaterial); 68 scene.add(curveObject); 69 */ 70 71 const pGeometry = new ParametricGeometry( 72 parametricRailsFoundationFunction, 250, 250); 73 74 return pGeometry; 75 } 76 77 // `position` es de tipo `THREE.Vector3` y representa la translacion de la 78 // forma del rail con respecto al origen del sist. de coordenadas de modelado 79 function getParametricRailsFunction(railsRadius = 0.50, position) { 80 return function parametricRails(u, v, target) { 81 const rotMatrix = new THREE.Matrix4(); 82 const translationMatrix = new THREE.Matrix4(); 83 const levelMatrix = new THREE.Matrix4(); 84 85 let railsShape = new THREE.Vector3(); 86 87 let railsPathPos = railsPath.getPointAt(v); 88 let railsShapePos = new THREE.Vector3( 89 Math.cos(u*6.28) + position.x, 90 position.y, 91 Math.sin(u*6.28) + position.z); 92 93 railsShapePos.multiplyScalar(0.1*railsRadius); 94 95 let tangente = new THREE.Vector3(); 96 let binormal = new THREE.Vector3(); 97 let normal = new THREE.Vector3(); 98 99 // https://threejs.org/docs/index.html?q=curve#api/en/extras/core/Curve.getTangent 100 tangente = railsPath.getTangentAt(v); 101 binormal = new THREE.Vector3(0, 1, 0); 102 normal.crossVectors(tangente, binormal); 103 104 translationMatrix.makeTranslation(railsPathPos); 105 106 rotMatrix.identity(); 107 levelMatrix.identity(); 108 109 levelMatrix.makeTranslation(railsPathPos); 110 rotMatrix.makeBasis(normal, tangente, binormal); 111 levelMatrix.multiply(rotMatrix); 112 railsShapePos.applyMatrix4(levelMatrix); 113 114 const x = railsShapePos.x; 115 const y = railsShapePos.y; 116 const z = railsShapePos.z; 117 target.set(x, y, z); 118 } 119 } 120 121 // devuelve la geometria de los rieles 122 export function buildRailsGeometry(railsRadius = 0.35) { 123 let railsGeometries = []; 124 125 const leftRailGeometryFunction = getParametricRailsFunction(railsRadius, 126 new THREE.Vector3( 9.5, 0, railsRadius+8)); 127 128 const rightRailGeometryFunction = getParametricRailsFunction(railsRadius, 129 new THREE.Vector3(-9.5, 0, railsRadius+8)); 130 131 const leftRailGeometry = new ParametricGeometry(leftRailGeometryFunction, 100, 500); 132 const rightRailGeometry = new ParametricGeometry(rightRailGeometryFunction, 100, 500); 133 134 railsGeometries.push(leftRailGeometry); 135 railsGeometries.push(rightRailGeometry); 136 137 const railsGeometry = mergeGeometries(railsGeometries); 138 return railsGeometry; 139 } 140 141 function main() { 142 railsPath = new THREE.CatmullRomCurve3([ 143 // bridge1 side 144 new THREE.Vector3( 0, 0, 32), 145 new THREE.Vector3( 28, 0, 32), 146 147 new THREE.Vector3( 28, 0, 0), 148 149 // bridge2 side 150 new THREE.Vector3( 5, 0, -37), 151 new THREE.Vector3(-35, 0, -30), 152 // new THREE.Vector3(-20, 0, -10), 153 154 new THREE.Vector3(-10, 0, 0), 155 ], true, 'catmullrom', 0.75); 156 157 /* 158 // muestra la curva utilizada para el camino de `rails` 159 const railsPathPoints = railsPath.getPoints(50); 160 const railsPathGeometry = new THREE.BufferGeometry().setFromPoints(railsPathPoints); 161 const railsPathMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); 162 const railsPathMesh = new THREE.Line(railsPathGeometry, railsPathMaterial); 163 scene.add(railsPathMesh); 164 */ 165 166 // buildRailsFoundation(); 167 // buildRails(); 168 } 169 170 // setupThreeJs(); 171 main();