TA159

Notas, resueltos y trabajos practicos de la materia Sistemas Gráficos
Index Commits Files Refs Submodules README LICENSE
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:
Mtp/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() {