UNPKG

@trap_stevo/legendarybuilderproreact-ui

Version:

The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton

356 lines 12.3 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; var _excluded = ["type"]; import React, { Suspense, useState, useEffect, useRef, useMemo } from "react"; import { EffectComposer, Bloom, ToneMapping, Exposure } from '@react-three/postprocessing'; import { Canvas, useFrame } from "@react-three/fiber"; import { OrbitControls } from "@react-three/drei"; import { GLTFLoader, FBXLoader, OBJLoader } from "three-stdlib"; import { extend, useLoader } from "@react-three/fiber"; import * as THREE from "three"; import HUDShaderMaterial from "./HUDShaderMaterial.js"; extend({ HUDShaderMaterial: HUDShaderMaterial }); var selectLoader = function selectLoader(type) { switch (type) { case "fbx": return FBXLoader; case "gltf": return GLTFLoader; case "obj": return OBJLoader; default: throw new Error("Unsupported model type: ", type); } }; var defaultLightPresets = { outdoors: [{ type: "ambient", intensity: 0.9, color: "#ffffff" }, { type: "directional", intensity: 2.0, position: [10, 15, 10], color: "#fdfbd3", castShadow: true }], fullMoon: [{ type: "ambient", intensity: 0.5, color: "#88aaff" }, { type: "directional", intensity: 1.0, position: [5, 10, 5], color: "#ccccff", castShadow: true }], studio: [{ type: "ambient", intensity: 1.0, color: "#ffffff" }, { type: "directional", intensity: 2.2, position: [7, 10, 5], color: "#ffffff", castShadow: true }], cinema: [{ type: "ambient", intensity: 0.2, color: "#111111" }, { type: "spot", intensity: 4.5, position: [0, 15, 10], color: "#ff8888", angle: Math.PI / 8, penumbra: 0.7, castShadow: true }, { type: "spot", intensity: 3.5, position: [-8, 5, -10], color: "#ff4444", angle: Math.PI / 5, penumbra: 1, castShadow: true }, { type: "point", intensity: 1.8, position: [5, 5, 10], color: "#6666ff", castShadow: true }], starship: [{ type: "ambient", intensity: 0.7, color: "#222288" }, { type: "point", intensity: 2.8, position: [0, 0, 0], color: "#ffffff", castShadow: true }, { type: "spot", intensity: 3.0, position: [8, 12, 5], color: "#88ccff", angle: Math.PI / 4, penumbra: 1, castShadow: true }, { type: "spot", intensity: 2.8, position: [-8, 12, -5], color: "#88ffff", angle: Math.PI / 5, penumbra: 1, castShadow: true }], garage: [{ type: "ambient", intensity: 0.7, color: "#555555" }, { type: "spot", intensity: 3.5, position: [5, 7, 5], color: "#ffffff", angle: Math.PI / 4, penumbra: 0.5, castShadow: true }, { type: "point", intensity: 2.0, position: [-5, -5, -5], color: "#bbbbbb", castShadow: true }, { type: "spot", intensity: 2.5, position: [3, 6, 2], color: "#ffaa00", angle: Math.PI / 5, penumbra: 0.7, castShadow: true }] }; var Model = function Model(_ref) { var url = _ref.url, textureConfiguration = _ref.textureConfiguration, modelPosition = _ref.modelPosition, modelRotation = _ref.modelRotation, modelScale = _ref.modelScale, type = _ref.type, useCustomShader = _ref.useCustomShader, rotate = _ref.rotate, _ref$rotationSpeed = _ref.rotationSpeed, rotationSpeed = _ref$rotationSpeed === void 0 ? 0.01 : _ref$rotationSpeed, onLoad = _ref.onLoad; var modelRef = useRef(); var Loader = useMemo(function () { return selectLoader(type); }, [type]); var model = useLoader(Loader, url); useFrame(function (state) { if (modelRef.current && rotate) { modelRef.current.rotation.y += rotationSpeed; } if (useCustomShader) { modelRef.current.traverse(function (child) { if (child.isMesh) { child.material.uniforms.uTime.value = state.clock.getElapsedTime(); } }); } }); var applyMaterials = function applyMaterials(child, partConfig) { if (useCustomShader) { child.material = new THREE.ShaderMaterial({ uniforms: { tintColor: { value: new THREE.Color(partConfig.tintColor || textureConfiguration.tintColor) }, color: { value: new THREE.Color(partConfig.color || textureConfiguration.color) }, specular: { value: partConfig.specular || textureConfiguration.specular }, roughness: { value: partConfig.roughness || textureConfiguration.roughness }, metallic: { value: partConfig.metallic || textureConfiguration.metallic }, sheen: { value: partConfig.sheen || textureConfiguration.sheen }, specularColor: { value: new THREE.Color(partConfig.specularColor || textureConfiguration.specularColor) }, sheenTint: { value: new THREE.Color(partConfig.sheenTint || textureConfiguration.sheenTint) }, emittance: { value: partConfig.emittance || textureConfiguration.emittance }, emittanceColor: { value: new THREE.Color(partConfig.emittanceColor || textureConfiguration.emittanceColor) }, uTime: { value: 0 } }, vertexShader: "varying vec2 vUv;\n void main()\n {\n vUv = uv;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }", fragmentShader: "uniform vec3 tintColor;\n uniform vec3 color;\n uniform float specular;\n uniform float roughness;\n uniform float metallic;\n uniform float sheen;\n uniform vec3 specularColor;\n uniform vec3 sheenTint;\n uniform float emittance;\n uniform vec3 emittanceColor;\n uniform float uTime;\n varying vec2 vUv;\n void main()\n {\n vec3 finalColor = mix(color, tintColor, 0.5);\n \n finalColor += emittance * emittanceColor;\n \n gl_FragColor = vec4(finalColor, 1.0);\n }" }); } else { child.material = new THREE.MeshStandardMaterial({ color: new THREE.Color(partConfig.color || textureConfiguration.color), metalness: partConfig.metallic || textureConfiguration.metallic, roughness: partConfig.roughness || textureConfiguration.roughness }); } child.material.needsUpdate = true; }; model.traverse(function (child) { if (child.isMesh && textureConfiguration && textureConfiguration.parts) { var _textureConfiguration; var partConfig = ((_textureConfiguration = textureConfiguration.parts) === null || _textureConfiguration === void 0 ? void 0 : _textureConfiguration[child.name]) || {}; applyMaterials(child, partConfig); } }); useEffect(function () { if (model && onLoad) { onLoad(model); } }, [model]); return /*#__PURE__*/React.createElement("primitive", { ref: modelRef, object: model.scene || model, position: modelPosition, rotation: modelRotation, scale: modelScale }); }; function HUDModel(_ref2) { var models = _ref2.models, _ref2$lightsPreset = _ref2.lightsPreset, lightsPreset = _ref2$lightsPreset === void 0 ? "studio" : _ref2$lightsPreset, _ref2$zoomLimits = _ref2.zoomLimits, zoomLimits = _ref2$zoomLimits === void 0 ? { min: 69, max: 269 } : _ref2$zoomLimits, _ref2$controlsEnabled = _ref2.controlsEnabled, controlsEnabled = _ref2$controlsEnabled === void 0 ? true : _ref2$controlsEnabled, _ref2$rotationSpeed = _ref2.rotationSpeed, rotationSpeed = _ref2$rotationSpeed === void 0 ? 0.00169 : _ref2$rotationSpeed, _ref2$cameraPosition = _ref2.cameraPosition, cameraPosition = _ref2$cameraPosition === void 0 ? [47, 187, 169] : _ref2$cameraPosition, _ref2$cameraTarget = _ref2.cameraTarget, cameraTarget = _ref2$cameraTarget === void 0 ? [0, 69, 0] : _ref2$cameraTarget, _ref2$cameraDistanceF = _ref2.cameraDistanceFactor, cameraDistanceFactor = _ref2$cameraDistanceF === void 0 ? 4 : _ref2$cameraDistanceF, _ref2$enableZoom = _ref2.enableZoom, enableZoom = _ref2$enableZoom === void 0 ? true : _ref2$enableZoom, _ref2$postEffects = _ref2.postEffects, postEffects = _ref2$postEffects === void 0 ? { bloom: { intensity: 1.269, threshold: 0.9, radius: 0.6 }, toneMapping: { exposure: 0.9 } } : _ref2$postEffects; var selectedLights = defaultLightPresets[lightsPreset] || defaultLightPresets.studio; var _useState = useState(cameraPosition), _useState2 = _slicedToArray(_useState, 2), dynamicCameraPosition = _useState2[0], setDynamicCameraPosition = _useState2[1]; var _useState3 = useState(cameraTarget), _useState4 = _slicedToArray(_useState3, 2), dynamicCameraTarget = _useState4[0], setDynamicCameraTarget = _useState4[1]; var calculateIdealCameraPosition = function calculateIdealCameraPosition(model) { if (!model) { return; } var box = new THREE.Box3().setFromObject(model); var center = box.getCenter(new THREE.Vector3()); var sphere = box.getBoundingSphere(new THREE.Sphere()); var distance = sphere.radius * cameraDistanceFactor; setDynamicCameraPosition([center.x, center.y + distance * 0.369, center.z + distance * 1.369]); setDynamicCameraTarget([center.x, center.y, center.z]); }; return /*#__PURE__*/React.createElement(Canvas, { shadows: true, camera: { position: dynamicCameraPosition } }, selectedLights.map(function (lightConfig, index) { var type = lightConfig.type, rest = _objectWithoutProperties(lightConfig, _excluded); if (type === "ambient") { return /*#__PURE__*/React.createElement("ambientLight", _extends({ key: index }, rest)); } else if (type === "directional") { return /*#__PURE__*/React.createElement("directionalLight", _extends({ key: index }, rest)); } else if (type === "point") { return /*#__PURE__*/React.createElement("pointLight", _extends({ key: index }, rest)); } else if (type === "spot") { return /*#__PURE__*/React.createElement("spotLight", _extends({ key: index }, rest)); } return null; }), /*#__PURE__*/React.createElement(Suspense, { fallback: null }, models.map(function (model, index) { return /*#__PURE__*/React.createElement(Model, { key: index, url: model.url, textureConfiguration: model.textureConfiguration, modelPosition: model.position, modelRotation: model.rotation, modelScale: model.scale, type: model.type, useCustomShader: model.useCustomShader, rotate: model.rotate, rotationSpeed: rotationSpeed, onLoad: function onLoad(loadedModel) { calculateIdealCameraPosition(loadedModel); return; } }); })), /*#__PURE__*/React.createElement(EffectComposer, null, postEffects.bloom && /*#__PURE__*/React.createElement(Bloom, { intensity: postEffects.bloom.intensity, threshold: postEffects.bloom.threshold, radius: postEffects.bloom.radius }), postEffects.toneMapping && /*#__PURE__*/React.createElement(ToneMapping, { exposure: postEffects.toneMapping.exposure })), controlsEnabled && /*#__PURE__*/React.createElement(OrbitControls, { minDistance: zoomLimits.min, maxDistance: zoomLimits.max, maxPolarAngle: Math.PI / 2, minPolarAngle: 0, target: dynamicCameraTarget, enableZoom: enableZoom })); } ; export default HUDModel;