commit 9e04bee9fe659eb7aea361271d8dfa815b1a5319 parent 7613c22cbfe66784723c801f82a618891c701691 Author: Martin Kloeckner <mjkloeckner@gmail.com> Date: Thu, 14 Aug 2025 14:10:50 -0300 added `ej/parametric_surface` Diffstat:
17 files changed, 1480 insertions(+), 0 deletions(-) diff --git a/ej/parametric_surface/LICENSE b/ej/parametric_surface/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Martin J. Klöckner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ej/parametric_surface/index.html b/ej/parametric_surface/index.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <title>Trabajo Practico Sistemas Graficos | Martin Klöckner</title> + <link rel="icon" href="data:,"> <!-- Do not request favicon --> + <style> + html, body, #mainContainer { + padding: 0; + margin: 0; + height: 100%; + font-family: Baskerville, "Times New Roman", serif; + pointer-events: auto; + display: block; + } + canvas { + pointer-events: auto; + display: block; + } + </style> + </head> + <body> + <div id="mainContainer"></div> + <script type="module" src="src/main.js"></script> + </body> +</html> diff --git a/ej/parametric_surface/package-lock.json b/ej/parametric_surface/package-lock.json @@ -0,0 +1,929 @@ +{ + "name": "Trabajo Práctico", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "Trabajo Práctico", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "dat.gui": "^0.7.9", + "three": "^0.162.0" + }, + "devDependencies": { + "vite": "^5.1.4" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/dat.gui": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/dat.gui/-/dat.gui-0.7.9.tgz", + "integrity": "sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==", + "license": "Apache-2.0" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/three": { + "version": "0.162.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.162.0.tgz", + "integrity": "sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==", + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + } +} diff --git a/ej/parametric_surface/package.json b/ej/parametric_surface/package.json @@ -0,0 +1,19 @@ +{ + "name": "Trabajo Práctico", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "vite build", + "preview": "vite preview" + }, + "author": "", + "license": "MIT", + "dependencies": { + "dat.gui": "^0.7.9", + "three": "^0.162.0" + }, + "devDependencies": { + "vite": "^5.1.4" + } +} diff --git a/ej/parametric_surface/src/assets/durmientes.jpg b/ej/parametric_surface/src/assets/durmientes.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/elevation_map_wider_river.png b/ej/parametric_surface/src/assets/elevation_map_wider_river.png Binary files differ. diff --git a/ej/parametric_surface/src/assets/madera.jpg b/ej/parametric_surface/src/assets/madera.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/pared_de_ladrillo.jpg b/ej/parametric_surface/src/assets/pared_de_ladrillo.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/pasto.jpg b/ej/parametric_surface/src/assets/pasto.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/roca.jpg b/ej/parametric_surface/src/assets/roca.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/sky_day_void.jpg b/ej/parametric_surface/src/assets/sky_day_void.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/sky_night.jpg b/ej/parametric_surface/src/assets/sky_night.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/tierra.jpg b/ej/parametric_surface/src/assets/tierra.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/tierra_seca.jpg b/ej/parametric_surface/src/assets/tierra_seca.jpg Binary files differ. diff --git a/ej/parametric_surface/src/assets/tree_forbidden_zone_map_wider_path.png b/ej/parametric_surface/src/assets/tree_forbidden_zone_map_wider_path.png Binary files differ. diff --git a/ej/parametric_surface/src/main.js b/ej/parametric_surface/src/main.js @@ -0,0 +1,464 @@ +import * as THREE from 'three'; +import * as dat from 'dat.gui'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + +import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; +import { ParametricGeometries } from 'three/examples/jsm/geometries/ParametricGeometries.js'; +import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js'; + +let scene, camera, renderer, container, terrainMaterial, instancedTrees; +let spherePath; +let railsPath; +let railsFoundationShape; + +let controls; +let shapeBase, shapeNarrow; + +import tierraUrl from '/src/assets/tierra.jpg' +import rocaUrl from '/src/assets/roca.jpg' +import pastoUrl from '/src/assets/pasto.jpg' +import durmientesUrl from '/src/assets/durmientes.jpg' + +const textures = { + tierra: { url: tierraUrl, object: null }, + roca: { url: rocaUrl, object: null }, + pasto: { url: pastoUrl, object: null }, + durmientes: { url: durmientesUrl, object: null }, +}; + +function onResize() { + camera.aspect = container.offsetWidth / container.offsetHeight; + const rotMatrix = new THREE.Matrix4(); + renderer.setSize(container.offsetWidth, container.offsetHeight); +} + +function setupThreeJs() { + scene = new THREE.Scene(); + container = document.getElementById('mainContainer'); + + renderer = new THREE.WebGLRenderer(); + renderer.setClearColor(0x606060); + container.appendChild(renderer.domElement); + + camera = new THREE.PerspectiveCamera( + 35, window.innerWidth / window.innerHeight, 0.1, 1000); + + camera.position.set(10, 20, 10); + camera.lookAt(0, 0, 0); + + controls = new OrbitControls(camera, renderer.domElement); + controls.update(); + + const ambientLight = new THREE.AmbientLight(0xffffff); + scene.add(ambientLight); + + const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x000000, 0.25); + scene.add(hemisphereLight); + + const directionalLight = new THREE.DirectionalLight(0xffffff, 1); + directionalLight.position.set(100, 100, 100); + scene.add(directionalLight); + + const gridHelper = new THREE.GridHelper(50, 50); + scene.add(gridHelper); + + const axesHelper = new THREE.AxesHelper(1); + scene.add(axesHelper); + + window.addEventListener('resize', onResize); + onResize(); +} + +function onTextureLoaded(key, texture) { + texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + textures[key].object = texture; + console.log('Texture `' + key + '` loaded'); +} + +function loadTextures(callback) { + const loadingManager = new THREE.LoadingManager(); + + loadingManager.onLoad = () => { + console.log('All textures loaded'); + callback(); + }; + + for (const key in textures) { + console.log("Loading textures"); + const loader = new THREE.TextureLoader(loadingManager); + const texture = textures[key]; + texture.object = loader.load( + texture.url, + onTextureLoaded.bind(this, key), + null, + (error) => { + console.error(error); + } + ); + } +} + +function parametricRailsFoundationFunction(u, v, target) { + const rotMatrix = new THREE.Matrix4(); + const translationMatrix = new THREE.Matrix4(); + const levelMatrix = new THREE.Matrix4(); + + let railsPathPos = railsPath.getPointAt(v); + let railsFoundationShapePos = railsFoundationShape.getPointAt(u); + // TODO: make `railsFoundationShape` smaller and remove this multiplication + railsFoundationShapePos.multiplyScalar(0.5); + + let tangente = new THREE.Vector3(); + let binormal = new THREE.Vector3(); + let normal = new THREE.Vector3(); + + tangente = railsPath.getTangent(v); + + tangente.normalize(); + binormal = new THREE.Vector3(0, 1, 0); + normal.crossVectors(tangente, binormal); + + translationMatrix.makeTranslation(railsPathPos); + + rotMatrix.identity(); + levelMatrix.identity(); + + levelMatrix.makeTranslation(railsPathPos); + rotMatrix.makeBasis(normal, tangente, binormal); + levelMatrix.multiply(rotMatrix); + railsFoundationShapePos.applyMatrix4(levelMatrix); + + const x = railsFoundationShapePos.x; + const y = railsFoundationShapePos.y; + const z = railsFoundationShapePos.z; + target.set(x, y, z); +} + + +export function buildRailsFoundation() { + railsFoundationShape = new THREE.CatmullRomCurve3([ + new THREE.Vector3( -2.00, 0.00, 0.00), + new THREE.Vector3( -1.00, 0.00, 0.50), + new THREE.Vector3( 0.00, 0.00, 0.55), + new THREE.Vector3( 1.00, 0.00, 0.50), + new THREE.Vector3( 2.00, 0.00, 0.00), + ], false); + + // show rails foundation shape + const points = railsFoundationShape.getPoints(50); + const geometry = new THREE.BufferGeometry().setFromPoints(points); + const lineMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); + const curveObject = new THREE.Line(geometry, lineMaterial); + scene.add(curveObject); + + const pGeometry = new ParametricGeometry( + parametricRailsFoundationFunction, 4, 50); // paso de discretizacion u y v + + textures.durmientes.object.wrapS = THREE.RepeatWrapping; + textures.durmientes.object.wrapT = THREE.RepeatWrapping; + textures.durmientes.object.repeat.set(1, 60); + textures.durmientes.object.anisotropy = 16; + + // load into `map` the example texture + const map = new THREE.TextureLoader().load('https://threejs.org/examples/textures/uv_grid_opengl.jpg'); + map.wrapS = map.wrapT = THREE.RepeatWrapping; + map.repeat.set(1, 30); + map.anisotropy = 16; + // map.rotation = Math.PI/2; + + const pMaterial = new THREE.MeshPhongMaterial({ + side: THREE.DoubleSide, + transparent: false, + opacity: 1.0, + shininess: 10, + // map: textures.durmientes.object + map: map + }); + const pMesh = new THREE.Mesh(pGeometry, pMaterial); + pMesh.receiveShadow = true; + pMesh.castShadow = true; + scene.add(pMesh); +} + +// `position` es de tipo `THREE.Vector3` y representa la translacion de la +// forma del rail con respecto al origen del sist. de coordenadas de modelado +function getParametricRailsFunction(radius, position) { + return function parametricRails(u, v, target) { + const rotMatrix = new THREE.Matrix4(); + const translationMatrix = new THREE.Matrix4(); + const levelMatrix = new THREE.Matrix4(); + + let railsShape = new THREE.Vector3(); + + let railsPathPos = railsPath.getPointAt(v); + + // railsShapePos es un cilindro + let railsShapePos = new THREE.Vector3( + Math.cos(u*6.28) + position.x, + position.y, + Math.sin(u*6.28) + position.z); + + railsShapePos.multiplyScalar(0.1*railsRadius); + + let tangente = new THREE.Vector3(); + let binormal = new THREE.Vector3(); + let normal = new THREE.Vector3(); + + // https://threejs.org/docs/index.html?q=curve#api/en/extras/core/Curve.getTangent + tangente = railsPath.getTangentAt(v); + binormal = new THREE.Vector3(0, 1, 0); + normal.crossVectors(tangente, binormal); + + translationMatrix.makeTranslation(railsPathPos); + + rotMatrix.identity(); + levelMatrix.identity(); + + levelMatrix.makeTranslation(railsPathPos); + rotMatrix.makeBasis(normal, tangente, binormal); + + levelMatrix.multiply(rotMatrix); + railsShapePos.applyMatrix4(levelMatrix); + + const x = railsShapePos.x; + const y = railsShapePos.y; + const z = railsShapePos.z; + target.set(x, y, z); + } +} + +const railsRadius = 0.35; +function buildRails() { + let railsGeometries = []; + + const leftRailGeometryFunction = getParametricRailsFunction(railsRadius, + new THREE.Vector3( 6, 0, railsRadius+8)); + + const rightRailGeometryFunction = getParametricRailsFunction(railsRadius, + new THREE.Vector3(-6, 0, railsRadius+8)); + + const leftRailGeometry = new ParametricGeometry(leftRailGeometryFunction, 100, 500); + const rightRailGeometry = new ParametricGeometry(rightRailGeometryFunction, 100, 500); + + railsGeometries.push(leftRailGeometry); + railsGeometries.push(rightRailGeometry); + + const railsMaterial = new THREE.MeshPhongMaterial({ + side: THREE.DoubleSide, + transparent: false, + opacity: 1.0, + shininess: 10, + color: 0xFFFFFF + }); + + const railsGeometry = mergeGeometries(railsGeometries); + const rails = new THREE.Mesh(railsGeometry, railsMaterial); + rails.castShadow = true; + scene.add(rails); +} + +function buildRailsPath() { + railsPath = new THREE.CatmullRomCurve3([ + new THREE.Vector3(-10, 0, 10), + new THREE.Vector3( 10, 0, 10), + new THREE.Vector3( 10, 0, -10), + new THREE.Vector3(-10, 0, -10), + ], true, 'catmullrom', 1.0); + + // muestra la curva utilizada para el camino de `rails` + const railsPathPoints = railsPath.getPoints(50); + const railsPathGeometry = new THREE.BufferGeometry().setFromPoints(railsPathPoints); + const railsPathMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); + const railsPathMesh = new THREE.Line(railsPathGeometry, railsPathMaterial); + scene.add(railsPathMesh); +} + +function shapeExample() { + const arcRadius = 1; + + shapeBase = new THREE.Shape() + .moveTo(-1, -1.5) + .lineTo(1, -1.5) + .lineTo(1, -1) + .arc(0, arcRadius, arcRadius, -Math.PI/2, Math.PI/2, false) + .lineTo(1, 1.5) + .lineTo(-1, 1.5) + .lineTo(-1, 1) + .arc(0, -arcRadius, arcRadius, Math.PI/2, -Math.PI/2, false) + .lineTo(-1, -1.5); + + shapeNarrow = new THREE.Shape() + .moveTo(-1.0, -1.0) + .lineTo(-1.0, -0.5) + .lineTo( 1.0, -0.5) + .lineTo( 1.0, -1.0) + .arc(0, arcRadius, arcRadius, -Math.PI/2, Math.PI/2, false) + .lineTo( 1.0, 0.5) + .lineTo(-1.0, 0.5) + .lineTo(-1.0, 1.0) + .arc(0, -arcRadius, arcRadius, Math.PI/2, -Math.PI/2, false); + + const pointsBase = shapeBase.getPoints(); + const geometryBase = new THREE.BufferGeometry().setFromPoints(pointsBase); + const materialBase = new THREE.LineBasicMaterial({ color: 0xff0000 }); + const lineBase = new THREE.Line(geometryBase, materialBase); + // lineBase.rotation.x = Math.PI / 2; // de XY a XZ + + const pointsNarrow = shapeNarrow.getPoints(); + const geometryNarrow = new THREE.BufferGeometry().setFromPoints(pointsNarrow); + const materialNarrow = new THREE.LineBasicMaterial({ color: 0x0000FF }); + const lineNarrow = new THREE.Line(geometryNarrow, materialNarrow); + // lineNarrow.rotation.x = Math.PI / 2; // de XY a XZ + + // scene.add(lineBase); + // scene.add(lineNarrow); +} + +function shapeExtrude(shape, color) { + const extrudeSettings = { + steps: 10, + depth: 5, + bevelEnabled: false, + }; + + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings ); + const material = new THREE.MeshPhongMaterial( { color: color } ); + const mesh = new THREE.Mesh( geometry, material ) ; + scene.add(mesh); + mesh.rotation.x =-Math.PI/2; +} + +/* +if (v <= 0.2 || v >= 0.8) { + point = pointNarrow; +} else if (v <= 0.3) { + const interpolationFactor = (v - 0.3)/0.1; + + point.x = THREE.MathUtils.lerp(pointNarrow.x, pointBase.x, interpolationFactor); + point.y = THREE.MathUtils.lerp(pointNarrow.y, pointBase.y, interpolationFactor); +} else if (v >= 0.7 && v <= 0.8) { + const interpolationFactor = (v - 0.7)/0.1; + + point.x = THREE.MathUtils.lerp(pointBase.x, pointNarrow.x, interpolationFactor); + point.y = THREE.MathUtils.lerp(pointBase.y, pointNarrow.y, interpolationFactor); +} else { + point = pointBase; +} +*/ +function parametricFunction(u, v, target) { + let point = new THREE.Vector2(0, 0); + const pointBase = shapeBase.getPointAt(u); + const pointNarrow = shapeNarrow.getPointAt(u); + // const pointNarrow = shapeBase.getPointAt(u); + + // if (v <= 0.40) { + // point = pointNarrow; + // } else if (v >= 0.60) { + // point = pointBase; + // } else { // v en [0.45 - 0.55] + // const interpolationFactor = (v - 0.40)/0.2; + // console.log(interpolationFactor); + // point.lerpVectors(pointNarrow, pointBase, interpolationFactor); + // } + + point = new THREE.Vector3(pointBase.x, pointBase.y, 10*v); + // point.applyAxisAngle(new THREE.Vector3(0, 0, 1), 2*Math.PI*v); + + const rotMatrix = new THREE.Matrix4(); + rotMatrix.makeRotationAxis(new THREE.Vector3(0, 0, 1), Math.PI*v); + // rotMatrix.makeBasis(normal, tangente, binormal); + + point.applyMatrix4(rotMatrix); + target.set(point.x, point.y, point.z); +} + +function generateTunnelGeometry( + tunnelHeight = 20, tunnelWidth = 14, + tunnelWallThickness = 0.5, tunnelLen = 26) { + + const path = new THREE.Path(); + path.moveTo(-tunnelWidth/2, 0); + path.lineTo(-tunnelWidth/2, tunnelHeight*1/3); + path.moveTo(-tunnelWidth/2, tunnelHeight*1/3); + path.quadraticCurveTo(0, tunnelHeight, tunnelWidth/2, tunnelHeight*1/3); + path.moveTo(tunnelWidth/2, 0); + path.lineTo(tunnelWidth/2, 0); + + + // cerramos la curva con otra de la misma forma con una diferencia de + // `tunnelWallThickness` + path.lineTo(tunnelWidth/2-tunnelWallThickness, 0); + path.moveTo(tunnelWidth/2-tunnelWallThickness, 0); + + path.lineTo(tunnelWidth/2-tunnelWallThickness, tunnelHeight*1/3); + path.moveTo(tunnelWidth/2-tunnelWallThickness, tunnelHeight*1/3); + + path.quadraticCurveTo( + 0, tunnelHeight-(tunnelWallThickness*2), + -tunnelWidth/2+tunnelWallThickness, tunnelHeight*1/3); + + path.lineTo(-tunnelWidth/2+tunnelWallThickness, 0); + path.moveTo(-tunnelWidth/2+tunnelWallThickness, 0); + + path.lineTo(-tunnelWidth/2, 0); + path.moveTo(-tunnelWidth/2, 0); + + const pathPoints = path.getPoints(50); + const pathGeometry = new THREE.BufferGeometry().setFromPoints(pathPoints); + const pathMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); + const pathObject = new THREE.Line(pathGeometry, pathMaterial); + scene.add(pathObject); + return; + + // const points = path.getPoints(); + // const shape = new THREE.Shape(points); + const extrudeSettings = { + curveSegments: 24, + steps: 50, + depth: tunnelLen, + }; + + const geometry = new THREE.ExtrudeGeometry(path, extrudeSettings); + + // el `1` en `x` es porque por algun motivo queda descentrado con respecto + // a la vía del tren + geometry.translate(1, 0, -tunnelLen/2); + return geometry; +} + +function generateTunnel() { + const geometry = generateTunnelGeometry(); + const material = new THREE.MeshPhongMaterial({ color: 0xFFFF00, side: THREE.DoubleSide }); + const mesh = new THREE.Mesh( geometry, material ); + scene.add(mesh); +} + +function shapeSweep(shape) { + const geometry = new ParametricGeometry(parametricFunction, 100, 100); + const material = new THREE.MeshPhongMaterial({ color: 0xFFFF00, side: THREE.DoubleSide }); + const mesh = new THREE.Mesh( geometry, material ); + mesh.rotation.x = -Math.PI/2; + scene.add(mesh); +} + +function mainLoop() { + requestAnimationFrame(mainLoop); + renderer.render(scene, camera); +} + +function main() { + shapeExample(); + // shapeExtrude(shapeBase, 0xCF4040); + // shapeExtrude(shapeNarrow, 0x5050FF); + shapeSweep(); + // generateTunnel(); + + // buildRailsPath(); + // buildRailsFoundation(); + // buildRails(); + + mainLoop(); +} + +setupThreeJs(); +loadTextures(main); diff --git a/ej/parametric_surface/vite.config.mjs b/ej/parametric_surface/vite.config.mjs @@ -0,0 +1,21 @@ +import { resolve } from 'path' +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + rollupOptions: { + input: { + main: resolve(__dirname, 'index.html'), + bridge: resolve(__dirname, 'bridge.html'), + rails: resolve(__dirname, 'rails.html'), + scene: resolve(__dirname, 'scene.html'), + terrain: resolve(__dirname, 'terrain.html'), + trackMap: resolve(__dirname, 'track-map.html'), + train: resolve(__dirname, 'train.html'), + trees: resolve(__dirname, 'trees.html'), + tunnel: resolve(__dirname, 'tunnel.html') + }, + }, + }, + base: "./", +})
