commit cdc75f5260e86a8a95e1037948328c98e267d760
parent 102da97388447fe038df42358c42261d0642143f
Author: Martin Klöckner <mjkloeckner@gmail.com>
Date: Wed, 26 Jun 2024 18:38:31 -0300
add stone base and surrounding tubing geometry
Diffstat:
M | tp/src/bridge.js | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 146 insertions(+), 7 deletions(-)
diff --git a/tp/src/bridge.js b/tp/src/bridge.js
@@ -6,9 +6,8 @@ import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
let scene, camera, renderer, container;
const textures = {
- madera: { url: '/assets/madera.jpg', object: null },
+ tierra: { url: '/assets/tierraSeca.jpg', object: null },
ladrillos: { url: '/assets/pared-de-ladrillos.jpg', object: null },
- ladrillos2: { url: '/assets/pared-de-ladrillos.jpg', object: null },
};
function onResize() {
@@ -32,7 +31,7 @@ function setupThreeJs() {
const controls = new OrbitControls(camera, renderer.domElement);
- const ambientLight = new THREE.AmbientLight(0xffffff);
+ const ambientLight = new THREE.AmbientLight(0xaaaaaa);
scene.add(ambientLight);
const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x000000, 0.25);
@@ -87,7 +86,7 @@ const arcRadius = arcWidth/2;
const columnHeight = 5;
const columnWidth = 1.50;
const topPadding = 0.50;
-const startPadding = 2;
+const startPadding = 10;
const endPadding = startPadding;
const bridgeWallThickness = 2.5;
const bridgeLen = arcCount*(columnWidth+arcWidth)+columnWidth+startPadding+endPadding;
@@ -136,6 +135,98 @@ function generateBridgeWall() {
return bridgeWallGeometry;
}
+const squareTubeRadius = 0.15;
+function generateBridgeCage(squaresCount = 3) {
+ const squaresSideLen = 10;
+ const bridgeCageLen = squaresCount * squaresSideLen;
+
+ let geometries = []
+
+ let cylinderBase, cylinderCorner, cylinderCrossbar;
+ for(let square = 0; square < squaresCount; ++square) {
+ // 0 -> 00
+ // 1 -> 01
+ // 2 -> 10
+ // 3 -> 11
+ for(let i = 0; i < 4; ++i) {
+ cylinderBase = new THREE.CylinderGeometry(
+ squareTubeRadius, squareTubeRadius, squaresSideLen);
+
+ cylinderCorner = cylinderBase.clone();
+
+ const squareHypotenuse = Math.sqrt(2*squaresSideLen*squaresSideLen);
+ cylinderCrossbar = new THREE.CylinderGeometry(
+ squareTubeRadius, squareTubeRadius, squareHypotenuse);
+
+ if((i % 2) == 0) {
+ cylinderBase.rotateZ(Math.PI/2);
+ cylinderBase.translate(
+ 0,
+ square*(squaresSideLen),
+ ((-1)**(i>>1))*squaresSideLen/2);
+
+ cylinderCrossbar.rotateZ((-1)**((i>>1))*Math.PI/4);
+ cylinderCrossbar.translate(
+ 0,
+ square*(squaresSideLen)+(squaresSideLen/2),
+ ((-1)**(i>>1))*squaresSideLen/2);
+
+ cylinderCorner.translate(
+ ((-1)**(i>>1))*squaresSideLen/2,
+ square*(squaresSideLen)+(squaresSideLen/2),
+ ((-1)**(i&1))*squaresSideLen/2);
+ } else {
+ cylinderBase.rotateX(Math.PI/2);
+ cylinderBase.translate(
+ ((-1)**(i>>1))*squaresSideLen/2,
+ square*(squaresSideLen),
+ 0);
+
+ cylinderCrossbar.rotateX((-1)**((i>>1))*Math.PI/4);
+ cylinderCrossbar.translate(
+ ((-1)**(i>>1))*squaresSideLen/2,
+ square*(squaresSideLen)+(squaresSideLen/2),
+ 0);
+
+ cylinderCorner.translate(
+ ((-1)**(i>>1))*squaresSideLen/2,
+ square*(squaresSideLen)+(squaresSideLen/2),
+ ((-1)**(i&1))*squaresSideLen/2);
+ }
+ geometries.push(cylinderBase);
+ geometries.push(cylinderCrossbar);
+ geometries.push(cylinderCorner);
+ }
+
+ // agregamos un cuadrado mas para 'cerrar' la 'jaula'
+ if((square + 1) == squaresCount) {
+ for(let i = 0; i < 4; ++i) {
+ cylinderBase = new THREE.CylinderGeometry(
+ squareTubeRadius, squareTubeRadius, squaresSideLen);
+
+ if((i % 2) == 0) {
+ cylinderBase.rotateZ(Math.PI/2);
+ cylinderBase.translate(
+ 0,
+ (square+1)*(squaresSideLen),
+ ((-1)**(i>>1))*squaresSideLen/2);
+ } else {
+ cylinderBase.rotateX(Math.PI/2);
+ cylinderBase.translate(
+ ((-1)**(i>>1))*squaresSideLen/2,
+ (square+1)*(squaresSideLen), 0);
+ }
+ geometries.push(cylinderBase);
+ }
+ }
+ }
+
+ const bridgeCage = mergeGeometries(geometries);
+ bridgeCage.rotateZ(Math.PI/2);
+ bridgeCage.translate(bridgeCageLen/2, squaresSideLen/2, 0);
+ return bridgeCage;
+}
+
function generateBridge() {
const bridgeWidth = 10;
const roadwayHeight = 2;
@@ -164,10 +255,9 @@ function generateBridge() {
opacity: 1.0,
shininess: 10,
map: textures.ladrillos.object
- // color: 0xFF0000
});
-
+ /*
textures.ladrillos2.object.wrapS = THREE.RepeatWrapping;
textures.ladrillos2.object.wrapT = THREE.RepeatWrapping;
textures.ladrillos2.object.repeat.set(0.75*5, 0.75*0.75);
@@ -182,11 +272,60 @@ function generateBridge() {
// color: 0xFF0000
});
+ const bridgeRoadway = new THREE.Mesh(bridgeRoadwayGeometry, roadwayMaterial);
+ scene.add(bridgeRoadway);
+ */
+
const bridgeColumns = new THREE.Mesh(bridgeColumnsGeometry, bridgeMaterial);
scene.add(bridgeColumns);
- const bridgeRoadway = new THREE.Mesh(bridgeRoadwayGeometry, roadwayMaterial);
+ // para reutilizar la textura de ladrillos usada en los arcos se escalan las
+ // coordenadas uv de la geometria de la parte superior
+ let uvs = bridgeRoadwayGeometry.attributes.uv.array;
+ for (let i = 0, len = uvs.length; i < len; i++) {
+ uvs[i] = (i % 2) ? uvs[i]*2.50 : uvs[i]*30.0;
+ }
+
+ const bridgeRoadway = new THREE.Mesh(bridgeRoadwayGeometry, bridgeMaterial);
scene.add(bridgeRoadway);
+
+ const cageGeometry = generateBridgeCage()
+ cageGeometry.translate(0, bridgeHeight+roadwayHeight-squareTubeRadius*2, 0);
+
+ const cageMaterial = new THREE.MeshPhongMaterial({
+ side: THREE.DoubleSide,
+ transparent: false,
+ opacity: 1.0,
+ shininess: 10,
+ color: 0xFFFFFF
+ });
+
+ const bridgeCage = new THREE.Mesh(cageGeometry, cageMaterial);
+ scene.add(bridgeCage);
+
+ const roadwayFloorGeometry = new THREE.PlaneGeometry(
+ bridgeWidth+bridgeWallThickness,
+ bridgeLen);
+
+ roadwayFloorGeometry.rotateZ(Math.PI/2)
+ roadwayFloorGeometry.rotateX(Math.PI/2)
+ roadwayFloorGeometry.translate(0, bridgeHeight+roadwayHeight, 0)
+
+ textures.tierra.object.wrapS = THREE.MirroredRepeatWrapping;
+ textures.tierra.object.wrapT = THREE.MirroredRepeatWrapping;
+ textures.tierra.object.repeat.set(1, 5);
+ textures.tierra.object.anisotropy = 16;
+
+ const roadwayFloorMaterial = new THREE.MeshPhongMaterial({
+ side: THREE.DoubleSide,
+ transparent: false,
+ opacity: 1.0,
+ shininess: 10,
+ map: textures.tierra.object
+ });
+
+ const roadwayFloor = new THREE.Mesh(roadwayFloorGeometry, roadwayFloorMaterial);
+ scene.add(roadwayFloor)
}
function mainLoop() {