Merge pull request #1 from denismhz/Deleting-everything
Deleting everything
15
.eslintrc.cjs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
module.exports = {
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react/jsx-runtime',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
],
|
||||||
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||||
|
settings: { react: { version: '18.2' } },
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': 'warn',
|
||||||
|
},
|
||||||
|
}
|
||||||
BIN
img/4k-ga95967816_1920.jpg
Normal file
|
After Width: | Height: | Size: 940 KiB |
BIN
img/back.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
img/bottom.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
img/cubemap.png
Normal file
|
After Width: | Height: | Size: 726 KiB |
BIN
img/earth/6k_earth_clouds.jpg
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
img/earth/6k_earth_daymap.jpg
Normal file
|
After Width: | Height: | Size: 7.9 MiB |
BIN
img/earth/6k_earth_nightmap.jpg
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
img/earth/6k_earth_normal_map.jpg
Normal file
|
After Width: | Height: | Size: 6.2 MiB |
BIN
img/earth/6k_earth_specular_map.jpg
Normal file
|
After Width: | Height: | Size: 6.1 MiB |
BIN
img/earth/8k_earth_clouds.jpg
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
img/earth/8k_earth_nightmap.jpg
Normal file
|
After Width: | Height: | Size: 3 MiB |
BIN
img/earth/8k_earth_normal_map.jpg
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
img/earth/8k_earth_normal_map.tif
Normal file
BIN
img/earth/8k_earth_specular_map.tif
Normal file
BIN
img/earth/color.jpg
Normal file
|
After Width: | Height: | Size: 4.4 MiB |
BIN
img/earth/earth_bump_1k.jpg
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
img/earth/earth_clouds_color_1k.jpg
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
img/earth/earth_clouds_trans_1k.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
img/earth/earth_night_uv_1k.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
img/earth/earth_spec_1k.jpg
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
img/earth/earth_uv.jpg
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
BIN
img/earth/earth_uv_10k.jpg
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
img/earth/earth_uv_1k.jpg
Normal file
|
After Width: | Height: | Size: 336 KiB |
BIN
img/front.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
img/jupiter/color.jpg
Normal file
|
After Width: | Height: | Size: 841 KiB |
BIN
img/jupiter/jupiter2_1k.jpg
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
img/jupiter/jupiter2_2k.jpg
Normal file
|
After Width: | Height: | Size: 308 KiB |
BIN
img/jupiter/jupiter2_6k.jp2
Normal file
BIN
img/left.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
img/mars/color.jpg
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
img/mars/mars_1k_normal.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
img/mars/mars_1k_topo.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
img/mercury/color.jpg
Normal file
|
After Width: | Height: | Size: 279 KiB |
BIN
img/mercury/mercurybump.jpg
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
img/moon/moonbump1k.jpg
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
img/moon/moonbump2k.jpg
Normal file
|
After Width: | Height: | Size: 997 KiB |
BIN
img/moon/moonbump4k.jpg
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
img/moon/moonmap1k.jpg
Normal file
|
After Width: | Height: | Size: 394 KiB |
BIN
img/moon/moonmap2k.jpg
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
img/moon/moonmap4k.jpg
Normal file
|
After Width: | Height: | Size: 5.7 MiB |
BIN
img/neptune/color.jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
,denis,arch,06.12.2022 09:42,file:///home/denis/.config/libreoffice/4;
|
||||||
BIN
img/pluto/8_Krankenhausmanagement_final_vertont.pptx
Normal file
BIN
img/pluto/color.jpg
Normal file
|
After Width: | Height: | Size: 1 MiB |
BIN
img/pluto/plutobump1k.jpg
Normal file
|
After Width: | Height: | Size: 222 KiB |
BIN
img/pluto/plutobump2k.jpg
Normal file
|
After Width: | Height: | Size: 573 KiB |
BIN
img/pluto/plutomap1k.jpg
Normal file
|
After Width: | Height: | Size: 318 KiB |
BIN
img/right.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
img/saturn/color.jpg
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
img/saturn/color_ring.jpg
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
img/saturn/saturnringpattern.gif
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
img/skybox.zip
Normal file
BIN
img/skybox/back.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
img/skybox/bottom.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
img/skybox/cubemap.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
img/skybox/front.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
img/skybox/left.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
img/skybox/right.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
img/skybox/top.png
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
img/sun/sun_uv.jpg
Normal file
|
After Width: | Height: | Size: 275 KiB |
BIN
img/top.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
img/uranus/color.jpg
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
img/uranus/uranus_rings.jpg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
img/uranus/uranusringtrans.gif
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
img/venus/color.jpg
Normal file
|
After Width: | Height: | Size: 249 KiB |
BIN
img/venus/venusbump.jpg
Normal file
|
After Width: | Height: | Size: 246 KiB |
16
index.html
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Sol</title>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/App.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
379
nbody.js
Normal file
|
|
@ -0,0 +1,379 @@
|
||||||
|
import * as THREE from "three";
|
||||||
|
import { earthMesh, earthGroup } from "./js/earth/earth_mesh.js";
|
||||||
|
import { sunMesh, sunGroup } from "./js/sun/sun_mesh.js";
|
||||||
|
import { venusMesh, venusGroup } from "./js/venus/venus.js";
|
||||||
|
import { mercuryMesh, mercuryGroup } from "./js/mercury/mercury.js";
|
||||||
|
import { marsMesh, marsGroup } from "./js/mars/mars.js";
|
||||||
|
import { saturnMesh, saturnGroup } from "./js/saturn/saturn.js";
|
||||||
|
import { jupiterMesh, jupiterGroup } from "./js/jupiter/jupiter.js";
|
||||||
|
import { uranusMesh, uranusGroup } from "./js/uranus/uranus.js";
|
||||||
|
import { neptuneMesh, neptuneGroup } from "./js/neptune/neptune.js";
|
||||||
|
import { plutoMesh, plutoGroup } from "./js/pluto/pluto.js";
|
||||||
|
import skybox from "./js/skybox/skybox.js";
|
||||||
|
import { ArcballControls } from "three/addons/controls/ArcballControls";
|
||||||
|
import { OrbitControls } from "three/addons/controls/OrbitControls";
|
||||||
|
import { BufferAttribute, BufferGeometryLoader, Color, Vector3 } from "three";
|
||||||
|
import axios from "axios";
|
||||||
|
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
|
||||||
|
import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
|
||||||
|
import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";
|
||||||
|
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
|
||||||
|
import { FXAAShader } from "three/addons/shaders/FXAAShader.js";
|
||||||
|
import { GlitchPass } from "three/addons/postprocessing/GlitchPass.js";
|
||||||
|
import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
|
||||||
|
import { PointLight } from "three";
|
||||||
|
//import { data } from "./orbitcalculations.js";
|
||||||
|
|
||||||
|
var objectsToOutline = [];
|
||||||
|
|
||||||
|
let selectedObjects = [];
|
||||||
|
|
||||||
|
var distanceScaleFactor = 10000000;
|
||||||
|
|
||||||
|
document.body.style.margin = 0;
|
||||||
|
|
||||||
|
var clock = new THREE.Clock();
|
||||||
|
var delta = 0;
|
||||||
|
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
|
||||||
|
const axesHelper = new THREE.AxesHelper(1000);
|
||||||
|
scene.add(axesHelper);
|
||||||
|
|
||||||
|
scene.add(earthGroup);
|
||||||
|
earthGroup.position.setX(149598262.0 / 1000);
|
||||||
|
scene.add(sunGroup);
|
||||||
|
scene.add(venusGroup);
|
||||||
|
venusGroup.position.setX(108209475.0 / 1000);
|
||||||
|
scene.add(mercuryGroup);
|
||||||
|
mercuryGroup.position.setX(57909227.0 / 1000);
|
||||||
|
scene.add(jupiterGroup);
|
||||||
|
jupiterGroup.position.setX(778340821.0 / 1000);
|
||||||
|
scene.add(saturnGroup);
|
||||||
|
saturnGroup.position.setX(1426666422.0 / 1000);
|
||||||
|
scene.add(uranusGroup);
|
||||||
|
uranusGroup.position.setX(2870658186.0 / 1000);
|
||||||
|
scene.add(marsGroup);
|
||||||
|
marsGroup.position.setX(227943842.0 / 1000);
|
||||||
|
scene.add(neptuneGroup);
|
||||||
|
neptuneGroup.position.setX(4498396441.0 / 1000);
|
||||||
|
|
||||||
|
scene.background = skybox;
|
||||||
|
|
||||||
|
const camera = new THREE.PerspectiveCamera(
|
||||||
|
75,
|
||||||
|
innerWidth / innerHeight,
|
||||||
|
0.1,
|
||||||
|
1000000000
|
||||||
|
);
|
||||||
|
camera.position.z = 40;
|
||||||
|
//camera.useQuaternion = true;
|
||||||
|
|
||||||
|
const renderer = new THREE.WebGLRenderer({ alpha: false });
|
||||||
|
renderer.setPixelRatio(devicePixelRatio);
|
||||||
|
renderer.setSize(innerWidth, innerHeight);
|
||||||
|
//renderer.setClearColor(0x222222, 0.0);
|
||||||
|
renderer.shadowMap.enabled = true;
|
||||||
|
document.body.appendChild(renderer.domElement);
|
||||||
|
renderer.autoClear = false;
|
||||||
|
//var arc = new ArcballControls(camera, renderer.domElement, scene);
|
||||||
|
|
||||||
|
const controls = new OrbitControls(camera, renderer.domElement);
|
||||||
|
|
||||||
|
var planetGroups = [
|
||||||
|
mercuryGroup,
|
||||||
|
venusGroup,
|
||||||
|
earthGroup,
|
||||||
|
marsGroup,
|
||||||
|
jupiterGroup,
|
||||||
|
saturnGroup,
|
||||||
|
uranusGroup,
|
||||||
|
neptuneGroup,
|
||||||
|
];
|
||||||
|
|
||||||
|
var meshes = [];
|
||||||
|
planetGroups.forEach((planet) => {
|
||||||
|
meshes.push(planet.children[0]);
|
||||||
|
});
|
||||||
|
console.log(meshes);
|
||||||
|
|
||||||
|
const color = 0xffffff;
|
||||||
|
const intensity = 1;
|
||||||
|
const light = new THREE.AmbientLight(color, intensity);
|
||||||
|
scene.add(light);
|
||||||
|
|
||||||
|
var composer = new EffectComposer(renderer);
|
||||||
|
|
||||||
|
var renderPass = new RenderPass(scene, camera);
|
||||||
|
|
||||||
|
const bloomPass = new UnrealBloomPass(
|
||||||
|
new THREE.Vector2(window.innerWidth, window.innerHeight, 1.5, 0.4, 0.85)
|
||||||
|
);
|
||||||
|
|
||||||
|
bloomPass.threshold = 0;
|
||||||
|
bloomPass.strength = 5;
|
||||||
|
bloomPass.radius = 0;
|
||||||
|
|
||||||
|
var outlinePass = new OutlinePass(
|
||||||
|
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
||||||
|
scene,
|
||||||
|
camera
|
||||||
|
);
|
||||||
|
|
||||||
|
outlinePass.renderToScreen = true;
|
||||||
|
composer.addPass(renderPass);
|
||||||
|
composer.addPass(outlinePass);
|
||||||
|
//composer.addPass(bloomPass);
|
||||||
|
|
||||||
|
var effectFXAA = new ShaderPass(FXAAShader);
|
||||||
|
effectFXAA.uniforms["resolution"].value.set(
|
||||||
|
1 / window.innerWidth,
|
||||||
|
1 / window.innerHeight
|
||||||
|
);
|
||||||
|
effectFXAA.renderToScreen = true;
|
||||||
|
composer.addPass(effectFXAA);
|
||||||
|
|
||||||
|
/*var effectFXAA = new ShaderPass(THREE.FXAAShader);
|
||||||
|
effectFXAA.uniforms["resolution"].value.set(
|
||||||
|
1 / window.innerWidth,
|
||||||
|
1 / window.innerHeight
|
||||||
|
);
|
||||||
|
effectFXAA.renderToScreen = true;
|
||||||
|
composer.addPass(effectFXAA);*/
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
edgeStrength: 10.0,
|
||||||
|
edgeGlow: 1.0,
|
||||||
|
edgeThickness: 1.0,
|
||||||
|
pulsePeriod: 0,
|
||||||
|
rotate: true,
|
||||||
|
usePatternTexture: false,
|
||||||
|
};
|
||||||
|
outlinePass.edgeStrength = params.edgeStrength;
|
||||||
|
outlinePass.edgeGlow = params.edgeGlow;
|
||||||
|
outlinePass.visibleEdgeColor.set(0xffffff);
|
||||||
|
outlinePass.hiddenEdgeColor.set(0xffffff);
|
||||||
|
|
||||||
|
const raycaster = new THREE.Raycaster();
|
||||||
|
const pointer = new THREE.Vector2();
|
||||||
|
/*const phongMaterial = new THREE.MeshPhongMaterial({
|
||||||
|
color: 0xffffff,
|
||||||
|
specular: 0x111111,
|
||||||
|
shininess: 5,
|
||||||
|
});
|
||||||
|
const test = new THREE.Mesh(
|
||||||
|
new THREE.SphereGeometry(6371.0, 50, 50),
|
||||||
|
phongMaterial
|
||||||
|
);
|
||||||
|
test.position.add(new THREE.Vector3(100000, 100000, 100000));
|
||||||
|
scene.add(test);*/
|
||||||
|
let lines = [];
|
||||||
|
planetGroups.forEach((planet) => {
|
||||||
|
const lineGeometry = new THREE.BufferGeometry();
|
||||||
|
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff });
|
||||||
|
const line = new THREE.Line(lineGeometry, lineMaterial);
|
||||||
|
lineGeometry.setAttribute(
|
||||||
|
"position",
|
||||||
|
new THREE.BufferAttribute(new Float32Array([]), 3)
|
||||||
|
);
|
||||||
|
lineGeometry.setAttribute(
|
||||||
|
"normal",
|
||||||
|
new THREE.BufferAttribute(new Float32Array([]), 3)
|
||||||
|
);
|
||||||
|
line.geometry.attributes.position.needsUpdate = true;
|
||||||
|
scene.add(line);
|
||||||
|
planet.userData["line"] = line;
|
||||||
|
});
|
||||||
|
console.log(lines);
|
||||||
|
|
||||||
|
//renderer.shadowMap.enabled = true;
|
||||||
|
//light.castShadow = true;
|
||||||
|
//light.shadow.mapSize.width = 512;
|
||||||
|
//light.shadow.mapSize.height = 512;
|
||||||
|
//light.shadow.camera.near = 150;
|
||||||
|
//light.shadow.camera.far = 350;
|
||||||
|
|
||||||
|
var obj = null;
|
||||||
|
function onPointerDown(event) {
|
||||||
|
// calculate pointer position in normalized device coordinates
|
||||||
|
// (-1 to +1) for both components
|
||||||
|
|
||||||
|
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||||
|
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||||
|
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
// calculate objects intersecting the picking ray
|
||||||
|
const intersects = raycaster.intersectObjects(planetGroups);
|
||||||
|
for (let i = 0; i < intersects.length; i++) {
|
||||||
|
obj = intersects[i].object.parent;
|
||||||
|
}
|
||||||
|
if (event.button == 0 && obj) {
|
||||||
|
controls.target.copy(obj.position);
|
||||||
|
controls.minDistance = obj.children[0].geometry.boundingSphere.radius * 1.5;
|
||||||
|
controls.maxDistance = obj.children[0].geometry.boundingSphere.radius * 10;
|
||||||
|
controls.update();
|
||||||
|
}
|
||||||
|
if (event.button == 2) {
|
||||||
|
obj = null;
|
||||||
|
controls.minDistance = 1;
|
||||||
|
controls.maxDistance = Infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerMove(event) {
|
||||||
|
// calculate pointer position in normalized device coordinates
|
||||||
|
// (-1 to +1) for both components
|
||||||
|
|
||||||
|
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||||
|
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||||
|
|
||||||
|
// calculate objects intersecting the picking ray
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
|
||||||
|
const intersects = raycaster.intersectObject(scene, true);
|
||||||
|
|
||||||
|
function addSelectedObject(object) {
|
||||||
|
selectedObjects = [];
|
||||||
|
selectedObjects.push(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
const selectedObject = intersects[0].object;
|
||||||
|
addSelectedObject(selectedObject);
|
||||||
|
outlinePass.selectedObjects = selectedObjects;
|
||||||
|
} else {
|
||||||
|
outlinePass.selectedObjects = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = "http://127.0.0.1:8000/duration";
|
||||||
|
|
||||||
|
var data;
|
||||||
|
setInterval(
|
||||||
|
await axios.get(url).then((res) => {
|
||||||
|
data = res.data;
|
||||||
|
console.log(data);
|
||||||
|
}),
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
planetGroups.forEach((planet) => {
|
||||||
|
planet.userData["positions"] = data[planet.userData.id];
|
||||||
|
});
|
||||||
|
function calculateOrbitLength() {
|
||||||
|
planetGroups.forEach((planet) => {
|
||||||
|
let length = 0;
|
||||||
|
if (planet.name != "Sun") {
|
||||||
|
for (let i = 0; i < planet.userData.positions.length - 1; i += 2) {
|
||||||
|
const dx = Math.abs(
|
||||||
|
planet.userData.positions[i + 1].x - planet.userData.positions[i].x
|
||||||
|
);
|
||||||
|
const dy = Math.abs(
|
||||||
|
planet.userData.positions[i + 1].y - planet.userData.positions[i].y
|
||||||
|
);
|
||||||
|
const dz = Math.abs(
|
||||||
|
planet.userData.positions[i + 1].z - planet.userData.positions[i].z
|
||||||
|
);
|
||||||
|
var segment = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
//console.log(
|
||||||
|
// `dx: ${dx}, dy: ${dy}, dz: ${dz}, segmentLength: ${segment}`
|
||||||
|
//);
|
||||||
|
length += segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
planet.userData["orbitLength"] = length / distanceScaleFactor;
|
||||||
|
console.log(
|
||||||
|
planet.userData.orbitLength * distanceScaleFactor +
|
||||||
|
" " +
|
||||||
|
planet.userData.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
calculateOrbitLength();
|
||||||
|
|
||||||
|
function cutPath(line, maxLength) {
|
||||||
|
const positions = line.geometry.attributes.position.array;
|
||||||
|
var currLength = getLength(line);
|
||||||
|
if (currLength > maxLength) {
|
||||||
|
line.geometry.attributes.position.array = positions.slice(3);
|
||||||
|
line.geometry.setDrawRange(
|
||||||
|
0,
|
||||||
|
line.geometry.attributes.position.array.length / 3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLength(line, maxLength) {
|
||||||
|
var length = 0;
|
||||||
|
const positions = line.geometry.attributes.position.array;
|
||||||
|
for (let i = 0; i < positions.length - 6; i += 3) {
|
||||||
|
const dx = positions[i + 3] - positions[i];
|
||||||
|
const dy = positions[i + 4] - positions[i + 1];
|
||||||
|
const dz = positions[i + 5] - positions[i + 2];
|
||||||
|
length += Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asdf = 0;
|
||||||
|
var last = 0;
|
||||||
|
function animate(now) {
|
||||||
|
window.requestAnimationFrame(animate);
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
controls.update();
|
||||||
|
composer.render();
|
||||||
|
|
||||||
|
if (obj) {
|
||||||
|
controls.target.copy(obj.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
planetGroups.forEach((planet) => {
|
||||||
|
if (false) {
|
||||||
|
if (planet.name != "Sun") {
|
||||||
|
planet.position.set(
|
||||||
|
Number(data[planet.userData.id].position.x / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id].position.y / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id].position.z / distanceScaleFactor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (planet.name != "Sun" && asdf < data["199"].length) {
|
||||||
|
if (true) {
|
||||||
|
const vertices =
|
||||||
|
planet.userData.line.geometry.attributes.position.array;
|
||||||
|
const newVertices = new Float32Array(vertices.length + 3);
|
||||||
|
newVertices.set(vertices);
|
||||||
|
newVertices.set(
|
||||||
|
[
|
||||||
|
Number(data[planet.userData.id][asdf].x / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id][asdf].y / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id][asdf].z / distanceScaleFactor),
|
||||||
|
],
|
||||||
|
vertices.length
|
||||||
|
);
|
||||||
|
planet.userData.line.geometry.setAttribute(
|
||||||
|
"position",
|
||||||
|
new THREE.BufferAttribute(newVertices, 3)
|
||||||
|
);
|
||||||
|
planet.userData["pathLength"] = getLength(planet.userData.line, 10);
|
||||||
|
cutPath(planet.userData.line, planet.userData.orbitLength * 0.5);
|
||||||
|
}
|
||||||
|
planet.position.set(
|
||||||
|
Number(data[planet.userData.id][asdf].x / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id][asdf].y / distanceScaleFactor),
|
||||||
|
Number(data[planet.userData.id][asdf].z / distanceScaleFactor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
performance.now();
|
||||||
|
earthGroup.children[0].rotation.y += 0.0015;
|
||||||
|
earthGroup.children[1].rotation.y += 0.0025;
|
||||||
|
earthGroup.children[3].position.y =
|
||||||
|
(-Math.cos(0.001 * performance.now() * 1) * 384000) / 200000;
|
||||||
|
earthGroup.children[3].position.z =
|
||||||
|
(-Math.sin(0.001 * performance.now() * 1) * 384000) / 200000;
|
||||||
|
asdf++;
|
||||||
|
}
|
||||||
|
animate();
|
||||||
|
|
||||||
|
window.addEventListener("pointermove", onPointerMove);
|
||||||
|
window.addEventListener("pointerdown", onPointerDown);
|
||||||
9727
package-lock.json
generated
Normal file
42
package.json
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"name": "solar-system",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@react-three/drei": "^9.66.1",
|
||||||
|
"@react-three/fiber": "^8.13.0",
|
||||||
|
"@react-three/postprocessing": "^2.10.0",
|
||||||
|
"@tweenjs/tween.js": "^18.6.4",
|
||||||
|
"axios": "^1.4.0",
|
||||||
|
"babel-plugin": "^1.0.7",
|
||||||
|
"glsl": "^0.0.1",
|
||||||
|
"glsl-noise": "^0.0.0",
|
||||||
|
"glslify": "^7.1.1",
|
||||||
|
"leva": "^0.9.34",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-query": "^3.39.3",
|
||||||
|
"react-router": "^6.11.0",
|
||||||
|
"react-router-dom": "^6.11.0",
|
||||||
|
"three": "^0.152.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.0.28",
|
||||||
|
"@types/react-dom": "^18.0.11",
|
||||||
|
"@vitejs/plugin-react": "^4.0.0",
|
||||||
|
"eslint": "^8.38.0",
|
||||||
|
"eslint-plugin-react": "^7.32.2",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.3.4",
|
||||||
|
"vite": "^4.3.2",
|
||||||
|
"vite-plugin-glsl": "^1.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/default.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
public/earth.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
public/jupiter.jpg
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
public/mars.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/mercury.jpg
Normal file
|
After Width: | Height: | Size: 6 KiB |
BIN
public/neptune.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/saturn.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/uranus.jpg
Normal file
|
After Width: | Height: | Size: 8 KiB |
BIN
public/venus.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
149
src/App.css
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root,
|
||||||
|
#canvas-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay .wrapper {
|
||||||
|
transform: translate3d(-10px, -10px, 0);
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay .wrapper .content {
|
||||||
|
position: absolute;
|
||||||
|
color: rgb(254, 254, 254);
|
||||||
|
font-size: 1.05em;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
user-select: none;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay .wrapper .icon {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo {
|
||||||
|
z-index: 12;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slidecontainer {
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
z-index: 12;
|
||||||
|
top: 90%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfoFadeIn {
|
||||||
|
z-index: 12;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
transition-delay: 1s;
|
||||||
|
transition-property: opacity;
|
||||||
|
transition: opacity 2s;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-close {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
top: 50px;
|
||||||
|
font-size: x-large;
|
||||||
|
color: white;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
right: calc(-100% + 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper {
|
||||||
|
padding-top: 100px;
|
||||||
|
background-color: rgba(194, 15, 15, 0);
|
||||||
|
backdrop-filter: blur(0.5px);
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
border-right: 1px solid rgba(255, 255, 255, 0.216);
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper p {
|
||||||
|
color: white;
|
||||||
|
padding: 10px 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper .data-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 10px 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper .data-wrapper .data {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
border-bottom: 1px solid rgb(116, 116, 116);
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper .data-wrapper .data-1 {
|
||||||
|
padding-right: 5px;
|
||||||
|
font-size: 28.8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper .data-wrapper .data-2 {
|
||||||
|
padding-right: 5px;
|
||||||
|
color: white;
|
||||||
|
font-size: 18.8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper .data-wrapper .data-3 {
|
||||||
|
padding-right: 5px;
|
||||||
|
color: rgb(83, 83, 83);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planetInfo .wrapper h1 {
|
||||||
|
color: white;
|
||||||
|
padding: 2px;
|
||||||
|
margin-left: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
position:absolute;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
top:95%;
|
||||||
|
height: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dateSpan {
|
||||||
|
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
7
src/App.jsx
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
|
import App from "./Main";
|
||||||
|
import "../src/App.css";
|
||||||
|
|
||||||
|
const container = document.getElementById("root");
|
||||||
|
const root = createRoot(container);
|
||||||
|
root.render(<App />);
|
||||||
219
src/CustomCamera.jsx
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
import { Canvas, useFrame, useThree } from "@react-three/fiber";
|
||||||
|
import {
|
||||||
|
OrbitControls,
|
||||||
|
PositionPoint,
|
||||||
|
TrackballControls,
|
||||||
|
ArcballControls,
|
||||||
|
} from "@react-three/drei";
|
||||||
|
import React, {
|
||||||
|
Suspense,
|
||||||
|
useRef,
|
||||||
|
createContext,
|
||||||
|
memo,
|
||||||
|
useState,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useLayoutEffect,
|
||||||
|
} from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
|
||||||
|
import { MyContext } from "./SolarSystemMain.jsx";
|
||||||
|
|
||||||
|
export function CustomCamera(props) {
|
||||||
|
const { customData } = useContext(MyContext);
|
||||||
|
const [animate, setAnimate] = useState(false);
|
||||||
|
const [zoom, setZoom] = useState(true);
|
||||||
|
const [pos, setPos] =useState();
|
||||||
|
const mouseDown = useRef(false);
|
||||||
|
const mouseUp = useRef(false);
|
||||||
|
const dist = useRef(60);
|
||||||
|
let _mouseStart = useRef(new THREE.Vector2(0, 0));
|
||||||
|
let _mouseEnd = useRef(new THREE.Vector2(0, 0));
|
||||||
|
let distance = useRef(200);
|
||||||
|
const [globalQuaternion, setGlobalQuaternion] = useState(
|
||||||
|
new THREE.Quaternion()
|
||||||
|
);
|
||||||
|
|
||||||
|
const [currObj, setCurrObj] = useState(undefined);
|
||||||
|
let rotate = useRef(true);
|
||||||
|
|
||||||
|
const handleMouseWheel = (event) => {
|
||||||
|
const delta = Math.sign(event.deltaY);
|
||||||
|
handleZoom(delta);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = (event) => {
|
||||||
|
if (mouseDown.current && rotate.current) {
|
||||||
|
_mouseEnd.current = new THREE.Vector2(event.clientX, event.clientY);
|
||||||
|
const deltaX = -event.movementX;
|
||||||
|
const deltaY = -event.movementY;
|
||||||
|
|
||||||
|
const rotationSpeed = 0.005;
|
||||||
|
|
||||||
|
// Create quaternions for rotation around X and Y axes
|
||||||
|
const quaternionX = new THREE.Quaternion().setFromAxisAngle(
|
||||||
|
new THREE.Vector3(1, 0, 0),
|
||||||
|
deltaY * 0.01
|
||||||
|
);
|
||||||
|
const quaternionY = new THREE.Quaternion().setFromAxisAngle(
|
||||||
|
new THREE.Vector3(0, 1, 0),
|
||||||
|
deltaX * rotationSpeed
|
||||||
|
);
|
||||||
|
|
||||||
|
const quaternionZ = new THREE.Quaternion().setFromAxisAngle(
|
||||||
|
new THREE.Vector3(0, 0, 1),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Combine the quaternions
|
||||||
|
const deltaQuaternion = quaternionY
|
||||||
|
.multiply(quaternionX)
|
||||||
|
.multiply(quaternionZ);
|
||||||
|
|
||||||
|
// Apply the rotation to the camera quaternion
|
||||||
|
if (camGroup && camGroup.current.quaternion) {
|
||||||
|
const finalQuaternion = camGroup.current.quaternion.clone();
|
||||||
|
finalQuaternion.multiply(deltaQuaternion);
|
||||||
|
|
||||||
|
const slerpSpeed = 0.3; // Adjust this value to control the smoothness
|
||||||
|
|
||||||
|
camGroup.current.quaternion.slerp(finalQuaternion, slerpSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseDown = (event) => {
|
||||||
|
_mouseStart.current = new THREE.Vector2(event.clientX, event.clientY);
|
||||||
|
mouseDown.current = true;
|
||||||
|
mouseUp.current = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = (event) => {
|
||||||
|
mouseDown.current = false;
|
||||||
|
mouseUp.current = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleZoom = (delta) => {
|
||||||
|
let zoomSpeed = 0.03;
|
||||||
|
if (camGroup && cameraRef) {
|
||||||
|
zoomSpeed *= cameraRef.current.position.distanceTo(
|
||||||
|
camGroup.current.position
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function newDistance(prevDistance) {
|
||||||
|
const newDistance = prevDistance + delta * zoomSpeed;
|
||||||
|
return Math.max(dist.current, newDistance); // Adjust the minimum distance as needed
|
||||||
|
}
|
||||||
|
distance.current = newDistance(distance.current);
|
||||||
|
};
|
||||||
|
customData.current["handleZoom"] = handleZoom;
|
||||||
|
|
||||||
|
const handlePosition = (pos, obj) => {
|
||||||
|
if (currObj) {
|
||||||
|
currObj.remove(camGroup.current);
|
||||||
|
setGlobalQuaternion(new THREE.Quaternion());
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrObj(obj);
|
||||||
|
setAnimate(true);
|
||||||
|
};
|
||||||
|
customData.current["handlePosition"] = handlePosition;
|
||||||
|
|
||||||
|
const cameraRef = useRef();
|
||||||
|
const set = useThree(({ set }) => set);
|
||||||
|
const size = useThree(({ size }) => size);
|
||||||
|
const camGroup = useRef();
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (cameraRef.current) {
|
||||||
|
cameraRef.current.aspect = size.width / size.height;
|
||||||
|
cameraRef.current.updateProjectionMatrix();
|
||||||
|
setPos(camGroup.current.position);
|
||||||
|
}
|
||||||
|
//cameraRef.current.position.copy(new THREE.Vector3(0, 0, 400));
|
||||||
|
window.addEventListener("mousedown", handleMouseDown);
|
||||||
|
window.addEventListener("mouseup", handleMouseUp);
|
||||||
|
window.addEventListener("mousemove", handleMouseMove);
|
||||||
|
window.addEventListener("wheel", handleMouseWheel);
|
||||||
|
}, [size, props]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
set({ camera: cameraRef.current });
|
||||||
|
});
|
||||||
|
|
||||||
|
let lerpedilerp = useRef(0.01);
|
||||||
|
|
||||||
|
function easeIn(t){
|
||||||
|
return t*t;
|
||||||
|
}
|
||||||
|
|
||||||
|
function myLerp(v3Start, v3End, t){
|
||||||
|
return new THREE.Vector3(
|
||||||
|
v3Start.x + (v3End.x - v3Start.x)*t,
|
||||||
|
v3Start.y + (v3End.y - v3Start.y)*t,
|
||||||
|
v3Start.z + (v3End.z - v3Start.z)*t
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
useFrame(({ clock }) => {
|
||||||
|
cameraRef.current.updateProjectionMatrix();
|
||||||
|
|
||||||
|
if (animate && currObj) {
|
||||||
|
setZoom(false);
|
||||||
|
distance.current =
|
||||||
|
currObj.children[1].geometry.boundingSphere.radius * 2.5;
|
||||||
|
dist.current = currObj.children[1].geometry.boundingSphere.radius * 2.5;
|
||||||
|
//camGroup.current.position.lerp(currObj.position,lerpedilerp.current);
|
||||||
|
//camGroup.current.position.copy(myLerp(pos, currObj.position, 0.5));
|
||||||
|
|
||||||
|
camGroup.current.position.lerp(currObj.position, lerpedilerp.current);
|
||||||
|
cameraRef.current.position.lerp(
|
||||||
|
new THREE.Vector3(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
currObj.children[1].geometry.boundingSphere.radius * 2.5
|
||||||
|
),
|
||||||
|
lerpedilerp.current
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cameraRef.current.lookAt(currObj.position);
|
||||||
|
camGroup.current.quaternion.copy(globalQuaternion);
|
||||||
|
|
||||||
|
rotate.current = false;
|
||||||
|
lerpedilerp.current *= 1.08;
|
||||||
|
//console.log(camGroup.current.position.distanceTo(currObj.position));
|
||||||
|
|
||||||
|
if (camGroup.current.position.distanceTo(currObj.position) < 0.3) {
|
||||||
|
currObj.add(camGroup.current);
|
||||||
|
camGroup.current.position.copy(new THREE.Vector3(0, 0, 0), 0.2);
|
||||||
|
|
||||||
|
rotate.current = true;
|
||||||
|
lerpedilerp.current = 0.01;
|
||||||
|
setZoom(true);
|
||||||
|
setAnimate(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rotate.current && currObj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (zoom && cameraRef.current) {
|
||||||
|
cameraRef.current.position.copy(
|
||||||
|
new THREE.Vector3(0, 0, distance.current)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group ref={camGroup} position={[0, 0, 0]}>
|
||||||
|
<perspectiveCamera
|
||||||
|
ref={cameraRef}
|
||||||
|
position={[0, 0, 0]}
|
||||||
|
fov={75}
|
||||||
|
near={0.1}
|
||||||
|
far={1000000}
|
||||||
|
/>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
src/Main.jsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||||
|
import SolarSystemScene from "./SolarSystemMain";
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
return (
|
||||||
|
<BrowserRouter>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<SolarSystemScene />} />
|
||||||
|
</Routes>
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
230
src/SharedPlanetState.jsx
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
import { useFrame } from "@react-three/fiber";
|
||||||
|
import { Html } from "@react-three/drei";
|
||||||
|
import { useState, useRef, createContext, useContext } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import { MyContext } from "./SolarSystemMain.jsx";
|
||||||
|
import Planet from "./planets/planet.jsx";
|
||||||
|
import Sun from "./planets/sun.jsx";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
export const PlanetOverlayContext = createContext();
|
||||||
|
|
||||||
|
export const SharedPlanetState = ({ planetData, linePos }) => {
|
||||||
|
const distanceScaleFactor = 1000000;
|
||||||
|
const { customData } = useContext(MyContext);
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [positions, setPositions] = useState(null);
|
||||||
|
const [realPos, setRealPos] = useState(null);
|
||||||
|
let first = useRef(true);
|
||||||
|
|
||||||
|
const planetPositionIndex = useRef(0);
|
||||||
|
const lastPositionUpdate = useRef(0);
|
||||||
|
const lastRealPositionUpdate = useRef(0);
|
||||||
|
|
||||||
|
let [nameVis, setNameVis] = useState("visible");
|
||||||
|
let [iconVis, setIconVis] = useState("visible");
|
||||||
|
let [pathVis, setPathVis] = useState("visible");
|
||||||
|
|
||||||
|
const handleVisibility = () => {
|
||||||
|
if (nameVis == "visible" && iconVis == "visible" && pathVis == "visible") {
|
||||||
|
setNameVis("hidden");
|
||||||
|
} else if (nameVis == "hidden" && iconVis == "visible" && pathVis == "visible") {
|
||||||
|
setIconVis("hidden");
|
||||||
|
} else if (nameVis == "hidden" && iconVis == "hidden" && pathVis == "visible") {
|
||||||
|
setPathVis("hidden")
|
||||||
|
} else if(nameVis == "hidden" && iconVis == "hidden" && pathVis == "hidden"){
|
||||||
|
setIconVis("visible");
|
||||||
|
setNameVis("visible");
|
||||||
|
setPathVis("visible")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
customData.current["handleVisibility"] = handleVisibility;
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setSpeed(-1);
|
||||||
|
console.log("reset");
|
||||||
|
planetPositionIndex.current = 0;
|
||||||
|
lastRealPositionUpdate.current = 0;
|
||||||
|
getRealTimePos();
|
||||||
|
};
|
||||||
|
customData.current["handleReset"] = handleReset;
|
||||||
|
|
||||||
|
//set speed (timeinterval between positions 60000ms*speed)
|
||||||
|
const [speed, setSpeed] = useState(-1);
|
||||||
|
const updateSpeed = (newSpeed) => {
|
||||||
|
setSpeed(newSpeed);
|
||||||
|
};
|
||||||
|
customData.current["updateSpeed"] = updateSpeed;
|
||||||
|
|
||||||
|
//get position data and reset if necessary
|
||||||
|
const dateTime = useRef(new Date(Date.now()));
|
||||||
|
|
||||||
|
function updatePlanetPosition(group, posArr, lineArr, realPos) {
|
||||||
|
if (
|
||||||
|
!loading &&
|
||||||
|
planetPositionIndex.current < posArr.length &&
|
||||||
|
speed != -1
|
||||||
|
) {
|
||||||
|
group.current.position.set(
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.x / distanceScaleFactor
|
||||||
|
),
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.y / distanceScaleFactor
|
||||||
|
),
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.z / distanceScaleFactor
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//realtime
|
||||||
|
|
||||||
|
customData.current.setDate(
|
||||||
|
new Date(positions[199][planetPositionIndex.current].date)
|
||||||
|
);
|
||||||
|
if (speed > 0) {
|
||||||
|
lineArr.current.push(
|
||||||
|
new THREE.Vector3(
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.x /
|
||||||
|
distanceScaleFactor
|
||||||
|
),
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.y /
|
||||||
|
distanceScaleFactor
|
||||||
|
),
|
||||||
|
Number(
|
||||||
|
posArr[planetPositionIndex.current].position.z /
|
||||||
|
distanceScaleFactor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//realtime
|
||||||
|
if (speed == -1) {
|
||||||
|
group.current.position.set(
|
||||||
|
Number(realPos.position.x / distanceScaleFactor),
|
||||||
|
Number(realPos.position.y / distanceScaleFactor),
|
||||||
|
Number(realPos.position.z / distanceScaleFactor)
|
||||||
|
);
|
||||||
|
customData.current.setDate(
|
||||||
|
new Date(realPos.date)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useFrame(({ clock }) => {
|
||||||
|
if (first.current) {
|
||||||
|
getAllPositions();
|
||||||
|
getRealTimePos();
|
||||||
|
first.current = false;
|
||||||
|
}
|
||||||
|
if (speed > 0 && !loading) planetPositionIndex.current += Number(speed);
|
||||||
|
const timeSinceLastUpdate = clock.elapsedTime - lastPositionUpdate.current;
|
||||||
|
const timeSinceLastRealUpdate = clock.elapsedTime - lastRealPositionUpdate.current;
|
||||||
|
if(timeSinceLastRealUpdate > 60) {
|
||||||
|
lastRealPositionUpdate.current = clock.elapsedTime;
|
||||||
|
getRealTimePos()
|
||||||
|
}
|
||||||
|
if (timeSinceLastUpdate >= 1 && !loading && speed > 0) {
|
||||||
|
|
||||||
|
getAllPositions();
|
||||||
|
lastPositionUpdate.current = clock.elapsedTime;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const getAllPositions = () => {
|
||||||
|
if (positions && positions[199].length > 0 && speed > 0) {
|
||||||
|
dateTime.current = new Date(
|
||||||
|
positions[199][positions[199].length - 1].date
|
||||||
|
).toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
fetch(
|
||||||
|
`http://192.168.1.136:8000/duration` + `?date=${dateTime.current}`
|
||||||
|
).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`This is an HTTP error: The status is ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then((data) => {
|
||||||
|
if (!positions) {
|
||||||
|
setPositions(data);
|
||||||
|
} else {
|
||||||
|
let obj = new Object();
|
||||||
|
for (let key in positions) {
|
||||||
|
obj[key] = positions[key].concat(data[key]);
|
||||||
|
}
|
||||||
|
setPositions(obj);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRealTimePos = () => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
fetch(`http://192.168.1.136:8000/now`).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`This is an HTTP error: The status is ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then((data) => {
|
||||||
|
setRealPos(data);
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
//setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
const planets = [];
|
||||||
|
for (let planet of planetData) {
|
||||||
|
planets.push(
|
||||||
|
<Planet
|
||||||
|
key={planet._id}
|
||||||
|
planetData={planet}
|
||||||
|
setPosition={updatePlanetPosition}
|
||||||
|
positions={positions && positions[planet._id]}
|
||||||
|
realPos={realPos && realPos[planet._id]}
|
||||||
|
linePos={linePos && linePos[planet._id]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PlanetOverlayContext.Provider value={{ nameVis, iconVis, speed, pathVis }}>
|
||||||
|
{!loading && planets}
|
||||||
|
{loading && (
|
||||||
|
<Html>
|
||||||
|
<h1 style={{color:"white"}}>Loading...</h1>
|
||||||
|
</Html>
|
||||||
|
)}
|
||||||
|
<Sun />
|
||||||
|
</PlanetOverlayContext.Provider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SharedPlanetState.propTypes = {
|
||||||
|
planetData: PropTypes.array,
|
||||||
|
linePos: PropTypes.object
|
||||||
|
};
|
||||||
18
src/Skybox.jsx
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { useThree } from "@react-three/fiber";
|
||||||
|
|
||||||
|
import * as THREE from "three";
|
||||||
|
export const Skybox = () => {
|
||||||
|
const { scene } = useThree();
|
||||||
|
const loader = new THREE.CubeTextureLoader();
|
||||||
|
const box = loader.load([
|
||||||
|
"../img/front.png",
|
||||||
|
"../img/back.png",
|
||||||
|
"../img/top.png",
|
||||||
|
"../img/bottom.png",
|
||||||
|
"../img/left.png",
|
||||||
|
"../img/right.png",
|
||||||
|
]);
|
||||||
|
scene.background = box;
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
108
src/SolarSystemMain.jsx
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
import { Canvas } from "@react-three/fiber";
|
||||||
|
import {
|
||||||
|
Suspense,
|
||||||
|
useRef,
|
||||||
|
createContext,
|
||||||
|
useLayoutEffect,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
|
import { ScreenOverlay } from "./planets/omnioverlay.jsx";
|
||||||
|
import { SharedPlanetState } from "./SharedPlanetState.jsx";
|
||||||
|
import { Skybox } from "./Skybox.jsx";
|
||||||
|
import { CustomCamera } from "./CustomCamera.jsx";
|
||||||
|
|
||||||
|
export const MyContext = createContext();
|
||||||
|
|
||||||
|
const SolarSystemScene = () => {
|
||||||
|
const controls = useRef();
|
||||||
|
let customData = useRef({});
|
||||||
|
const [pinfo, setPinfo] = useState(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [linePos, setLinePos] = useState(null);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
const fetchPlanetInfo = async () => {
|
||||||
|
fetch(`http://192.168.1.136:8000/planetInfo`).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`This is an HTTP error: The status is ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then((data) => {
|
||||||
|
setPinfo(data);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setPinfo(null);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
fetchPlanetInfo();
|
||||||
|
const fetchLinePos = async () => {
|
||||||
|
fetch(`http://192.168.1.136:8000/duration/line`).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`This is an HTTP error: The status is ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then((data) => {
|
||||||
|
|
||||||
|
setLinePos(data);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLinePos(null)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//fetchLinePos();
|
||||||
|
fetchPlanetInfo();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//console.log(progress);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<div className="loadingScreen">Suspense</div>}>
|
||||||
|
{!loading && (
|
||||||
|
<>
|
||||||
|
<MyContext.Provider value={{ controls, customData }}>
|
||||||
|
<ScreenOverlay planetInfo={pinfo} />
|
||||||
|
|
||||||
|
{true && (
|
||||||
|
<Canvas
|
||||||
|
camera={{
|
||||||
|
position: [0, 0, 100],
|
||||||
|
fov: 75,
|
||||||
|
near: 0.1,
|
||||||
|
far: 10000000,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{true && <CustomCamera />}
|
||||||
|
<Skybox />
|
||||||
|
<ambientLight intensity={0.025} />
|
||||||
|
<pointLight position={[0, 0, 0]} />
|
||||||
|
<SharedPlanetState planetData={pinfo} linePos={linePos}/>
|
||||||
|
</Canvas>
|
||||||
|
)}
|
||||||
|
</MyContext.Provider>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SolarSystemScene;
|
||||||
72
src/planets/omnioverlay.jsx
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { useContext, useState } from "react";
|
||||||
|
import { PlanetInfo } from "./planetInfo.jsx";
|
||||||
|
import { MyContext } from "../SolarSystemMain.jsx";
|
||||||
|
|
||||||
|
export const ScreenOverlay = (props) => {
|
||||||
|
const { customData } = useContext(MyContext);
|
||||||
|
|
||||||
|
const [date, setDate] = useState();
|
||||||
|
customData.current["setDate"] = setDate;
|
||||||
|
|
||||||
|
const handleChange = () => {
|
||||||
|
customData.current.updateSpeed(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange0 = () => {
|
||||||
|
customData.current.updateSpeed(3);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange1 = () => {
|
||||||
|
customData.current.updateSpeed(8);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange2 = () => {
|
||||||
|
customData.current.updateSpeed(20);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
customData.current.handleReset();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePlanetOverlayVisibility = () => {
|
||||||
|
customData.current.handleVisibility();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="btn-toolbar slidecontainer">
|
||||||
|
<div className="btn-group mr-2" role="group">
|
||||||
|
<button onClick={handleReset} className="btn btn-primary">
|
||||||
|
<
|
||||||
|
</button>
|
||||||
|
<button onClick={handleChange} className="btn btn-primary">
|
||||||
|
II
|
||||||
|
</button>
|
||||||
|
<button onClick={handleChange0} className="btn btn-primary">
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
<button onClick={handleChange1} className="btn btn-primary">
|
||||||
|
>>
|
||||||
|
</button>
|
||||||
|
<button onClick={handleChange2} className="btn btn-primary">
|
||||||
|
>>>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="btn-group" role="group">
|
||||||
|
<button
|
||||||
|
onClick={handlePlanetOverlayVisibility}
|
||||||
|
className="btn btn-primary"
|
||||||
|
>
|
||||||
|
O
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="date">
|
||||||
|
<span className="dateSpan" style={{ color: "white" }}>
|
||||||
|
{date && date.toUTCString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<PlanetInfo planetInfo={props.planetInfo} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
128
src/planets/path.jsx
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
import { useFrame } from "@react-three/fiber";
|
||||||
|
import React, { useRef, useContext, useLayoutEffect, useState } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import { PlanetOverlayContext } from "../SharedPlanetState";
|
||||||
|
|
||||||
|
export const PlanetPath = ({
|
||||||
|
linePos,
|
||||||
|
color,
|
||||||
|
lineLength,
|
||||||
|
planet,
|
||||||
|
}) => {
|
||||||
|
const lineref = useRef();
|
||||||
|
const lineArr = useRef([]);
|
||||||
|
const first = useRef(true);
|
||||||
|
const [loading, setLoading] = useState();
|
||||||
|
const { speed } = useContext(PlanetOverlayContext);
|
||||||
|
const [linePoss, setLinePoss] = useState(null);
|
||||||
|
const [second, setSecond] = useState(false);
|
||||||
|
const asd = useContext(PlanetOverlayContext);
|
||||||
|
|
||||||
|
//from chatgpt very nice :D
|
||||||
|
const cutPath = (path, maxLength) => {
|
||||||
|
let length = getLength(path);
|
||||||
|
while (length > maxLength && path.length >= 2) {
|
||||||
|
const firstPoint = path[0];
|
||||||
|
const secondPoint = path[1];
|
||||||
|
const segmentLength = firstPoint.distanceTo(secondPoint);
|
||||||
|
if (segmentLength > maxLength) {
|
||||||
|
// If the first segment is longer than the maximum length,
|
||||||
|
// split it into multiple segments of the maximum length.
|
||||||
|
const numSegments = Math.ceil(segmentLength / maxLength);
|
||||||
|
const segmentDirection = secondPoint
|
||||||
|
.clone()
|
||||||
|
.sub(firstPoint)
|
||||||
|
.normalize();
|
||||||
|
const segmentLength = segmentLength / numSegments;
|
||||||
|
const newPoints = [firstPoint];
|
||||||
|
for (let i = 1; i < numSegments; i++) {
|
||||||
|
const newPoint = firstPoint
|
||||||
|
.clone()
|
||||||
|
.add(segmentDirection.clone().multiplyScalar(segmentLength * i));
|
||||||
|
newPoints.push(newPoint);
|
||||||
|
}
|
||||||
|
newPoints.push(secondPoint);
|
||||||
|
path.splice(0, 2, ...newPoints);
|
||||||
|
length = getLength(path);
|
||||||
|
} else {
|
||||||
|
path.shift();
|
||||||
|
length -= segmentLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getLength(arrV3) {
|
||||||
|
let sum = 0;
|
||||||
|
for (var i = 0; i < arrV3.length - 1; i += 2) {
|
||||||
|
sum += arrV3[i].distanceTo(arrV3[i + 1]);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
const distanceScaleFactor = 1000000;
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (second && linePoss) {
|
||||||
|
linePoss.forEach((element) => {
|
||||||
|
element.position.x = element.position.x / distanceScaleFactor;
|
||||||
|
element.position.y = element.position.y / distanceScaleFactor;
|
||||||
|
element.position.z = element.position.z / distanceScaleFactor;
|
||||||
|
lineArr.current.push(
|
||||||
|
new THREE.Vector3(
|
||||||
|
element.position.x,
|
||||||
|
element.position.y,
|
||||||
|
element.position.z
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
setSecond(false);
|
||||||
|
}
|
||||||
|
if(first.current){
|
||||||
|
const fetchLinePos = async () => {
|
||||||
|
fetch(
|
||||||
|
`http://192.168.1.136:8000/duration/line?name=${planet.name}&id=${planet.id}&LOY=${planet.year}`
|
||||||
|
).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`This is an HTTP error: The status is ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then((data) => {
|
||||||
|
setLinePoss(data)
|
||||||
|
setSecond(true);
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
fetchLinePos();
|
||||||
|
first.current = false;
|
||||||
|
}
|
||||||
|
//console.log(lineArr.current);
|
||||||
|
},[linePoss, planet, second]);
|
||||||
|
|
||||||
|
const lineGeometry = new THREE.BufferGeometry();
|
||||||
|
useFrame(() => {
|
||||||
|
let vis = Infinity;
|
||||||
|
if(asd.pathVis == "hidden") vis = 0;
|
||||||
|
else vis = Infinity;
|
||||||
|
lineref.current.geometry.setFromPoints(lineArr.current);
|
||||||
|
lineref.current.geometry.setDrawRange(0, vis);
|
||||||
|
//cutPath(linePos, lineLength);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<line ref={lineref} geometry={lineGeometry} frustumCulled={false}>
|
||||||
|
<lineBasicMaterial color={color} />
|
||||||
|
</line>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
62
src/planets/planet.jsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { useFrame, useLoader, useThree } from "@react-three/fiber";
|
||||||
|
import { useRef, useLayoutEffect } from "react";
|
||||||
|
import { TextureLoader } from "three/src/loaders/TextureLoader";
|
||||||
|
import { PlanetOverlay } from "./planetOverlay";
|
||||||
|
import { PlanetPath } from "./path";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
const Planet = ({ planetData, setPosition, positions, realPos, linePos }) => {
|
||||||
|
const lineArr = useRef([]);
|
||||||
|
|
||||||
|
const colorMap = useLoader(
|
||||||
|
TextureLoader,
|
||||||
|
`../img/${planetData.name.toLowerCase()}/color.jpg`
|
||||||
|
);
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (positions) setPosition(group, positions, lineArr, realPos);
|
||||||
|
});
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
group.current.userData.name = planetData.name;
|
||||||
|
group.current.userData.nearOvOp = planetData.overlayVisibilityDistance;
|
||||||
|
group.current.userData.scolor = planetData.color;
|
||||||
|
});
|
||||||
|
|
||||||
|
useThree(() => {});
|
||||||
|
|
||||||
|
const group = useRef();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PlanetPath
|
||||||
|
linePos={lineArr.current}
|
||||||
|
linePoss={linePos}
|
||||||
|
planet={{
|
||||||
|
name: planetData.name,
|
||||||
|
id: planetData._id,
|
||||||
|
year: planetData.LOY,
|
||||||
|
}}
|
||||||
|
color={planetData.color}
|
||||||
|
lineLength={200}
|
||||||
|
/>
|
||||||
|
<group ref={group}>
|
||||||
|
<PlanetOverlay planet={group} />
|
||||||
|
<mesh>
|
||||||
|
<sphereGeometry args={[planetData.Radius / 6000, 100, 100]} />
|
||||||
|
<meshPhongMaterial map={colorMap} />
|
||||||
|
</mesh>
|
||||||
|
</group>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Planet.propTypes = {
|
||||||
|
planetData: PropTypes.object,
|
||||||
|
setPosition: PropTypes.func,
|
||||||
|
positions: PropTypes.array,
|
||||||
|
realPos: PropTypes.object,
|
||||||
|
linePos: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Planet;
|
||||||
79
src/planets/planetInfo.jsx
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { useState, useEffect, useContext } from "react";
|
||||||
|
import { MyContext } from "../SolarSystemMain";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
export const PlanetInfo = (props) => {
|
||||||
|
const [visibility, setVisibility] = useState("hidden");
|
||||||
|
const { customData } = useContext(MyContext);
|
||||||
|
const [planetData, setPlanetData] = useState({ name: "Default" });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const showInfo = (planet) => {
|
||||||
|
props.planetInfo.forEach((oplanet) => {
|
||||||
|
if (planet.name == oplanet.name) {
|
||||||
|
setPlanetData(oplanet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setVisibility("visible");
|
||||||
|
};
|
||||||
|
if (showInfo) customData.current["showInfo"] = showInfo;
|
||||||
|
}, [customData, planetData, props.planetInfo]);
|
||||||
|
|
||||||
|
function closeInfo() {
|
||||||
|
setVisibility("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={visibility == "visible" ? "planetInfo" : "planetInfoFadeIn"}
|
||||||
|
style={{ visibility: visibility }}
|
||||||
|
>
|
||||||
|
<div className="wrapper">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={closeInfo}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</button>
|
||||||
|
<h1>{planetData.name}</h1>
|
||||||
|
<img id="plInfoImg" src={`${planetData.name.toLowerCase()}.jpg`}></img>
|
||||||
|
<p>{planetData.Description}</p>
|
||||||
|
<div className="data-wrapper">
|
||||||
|
<div className="data">
|
||||||
|
<span style={{ color: planetData.color }} className="data-1">
|
||||||
|
{planetData.LOY}
|
||||||
|
</span>
|
||||||
|
<span className="data-2">Earth Days/Years</span>
|
||||||
|
</div>
|
||||||
|
<div className="data">
|
||||||
|
<span style={{ color: planetData.color }} className="data-1">
|
||||||
|
{planetData.DFS}
|
||||||
|
</span>
|
||||||
|
<span className="data-2">AU</span>
|
||||||
|
<span className="data-3">Distance from Sun</span>
|
||||||
|
</div>
|
||||||
|
<div className="data">
|
||||||
|
<span style={{ color: planetData.color }} className="data-1">
|
||||||
|
{planetData.Moons}
|
||||||
|
</span>
|
||||||
|
<span className="data-2">Moons</span>
|
||||||
|
</div>
|
||||||
|
<div className="data">
|
||||||
|
<span style={{ color: planetData.color }} className="data-1">
|
||||||
|
{planetData.Radius}
|
||||||
|
</span>
|
||||||
|
<span className="data-2">Radius</span>
|
||||||
|
<span className="data-3">Kilometers</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PlanetInfo.propTypes = {
|
||||||
|
planet: PropTypes.object,
|
||||||
|
planetInfo: PropTypes.array
|
||||||
|
};
|
||||||
90
src/planets/planetOverlay.jsx
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
|
import { Html } from "@react-three/drei";
|
||||||
|
import React, { useState, useEffect, useContext } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import { MyContext } from "../SolarSystemMain";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { PlanetOverlayContext } from "../SharedPlanetState";
|
||||||
|
|
||||||
|
export const PlanetOverlay = ({ planet }) => {
|
||||||
|
let [opacity, setOpacity] = useState(0);
|
||||||
|
let [minDistance, setMinDistance] = useState(0);
|
||||||
|
const { nameVis, iconVis } = useContext(PlanetOverlayContext);
|
||||||
|
|
||||||
|
let [scolor, setSColor] = useState("white");
|
||||||
|
const { camera } = useThree();
|
||||||
|
const [name, setName] = useState("Undefined");
|
||||||
|
const svgStyle = { height: "20px", width: "20px", stroke: scolor };
|
||||||
|
const { customData } = useContext(MyContext);
|
||||||
|
|
||||||
|
const handleClick = React.useCallback(
|
||||||
|
(event) => {
|
||||||
|
// prevent context menu from opening on right-click
|
||||||
|
event.preventDefault();
|
||||||
|
// native event
|
||||||
|
switch (event.nativeEvent.button) {
|
||||||
|
case 0:
|
||||||
|
customData.current.showInfo(planet.current.userData);
|
||||||
|
customData.current.handlePosition(
|
||||||
|
planet.current.position,
|
||||||
|
planet.current
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[planet, customData]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setName(planet.current.userData.name);
|
||||||
|
setMinDistance(planet.current.userData.nearOvOp);
|
||||||
|
setSColor(planet.current.userData.scolor);
|
||||||
|
}, [planet, name, minDistance, customData, iconVis, nameVis]);
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
let worldpos = new THREE.Vector3();
|
||||||
|
camera.getWorldPosition(worldpos);
|
||||||
|
var distance = worldpos.distanceTo(planet.current.position);
|
||||||
|
if (distance < minDistance) {
|
||||||
|
setOpacity(0);
|
||||||
|
} else {
|
||||||
|
setOpacity(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Html
|
||||||
|
zIndexRange={[11, 0]}
|
||||||
|
className="overlay"
|
||||||
|
style={{ opacity: opacity }}
|
||||||
|
>
|
||||||
|
<div className="wrapper">
|
||||||
|
<span
|
||||||
|
className="icon"
|
||||||
|
onClick={handleClick}
|
||||||
|
onContextMenu={handleClick}
|
||||||
|
style={{ visibility: iconVis }}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
onMouseEnter={() => setSColor("lightgrey")}
|
||||||
|
onMouseLeave={() => setSColor(planet.current.userData.scolor)}
|
||||||
|
style={svgStyle}
|
||||||
|
>
|
||||||
|
<circle cx="10" cy="10" r="9" strokeWidth="1" fill="none" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span className="content" style={{ visibility: nameVis }}>
|
||||||
|
{name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Html>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PlanetOverlay.propTypes = {
|
||||||
|
planet: PropTypes.object,
|
||||||
|
};
|
||||||
390
src/planets/sun.jsx
Normal file
|
|
@ -0,0 +1,390 @@
|
||||||
|
import {
|
||||||
|
Canvas,
|
||||||
|
extend,
|
||||||
|
useFrame,
|
||||||
|
useLoader,
|
||||||
|
useThree,
|
||||||
|
} from "@react-three/fiber";
|
||||||
|
import {
|
||||||
|
shaderMaterial,
|
||||||
|
OrbitControls,
|
||||||
|
CubeCamera,
|
||||||
|
useCubeCamera,
|
||||||
|
} from "@react-three/drei";
|
||||||
|
import React, { useRef, Suspense, useLayoutEffect, useContext } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import glsl from "glslify";
|
||||||
|
import { PlanetOverlay } from "./planetOverlay";
|
||||||
|
|
||||||
|
const SunPerlinMaterial = shaderMaterial(
|
||||||
|
//uniform
|
||||||
|
{
|
||||||
|
uTime: 0,
|
||||||
|
},
|
||||||
|
//Vertex SHader
|
||||||
|
glsl`
|
||||||
|
uniform float uTime;
|
||||||
|
|
||||||
|
varying vec3 vPosition;
|
||||||
|
|
||||||
|
varying vec2 vUv;
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
vPosition = position;
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = projectionMatrix* modelViewMatrix*vec4(position,1.);
|
||||||
|
}`,
|
||||||
|
//Fragment Shader
|
||||||
|
glsl`
|
||||||
|
// Classic Perlin 3D Noise
|
||||||
|
// by Stefan Gustavson
|
||||||
|
//
|
||||||
|
vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
|
||||||
|
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}
|
||||||
|
vec4 fade(vec4 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}
|
||||||
|
|
||||||
|
float cnoise(vec4 P){
|
||||||
|
vec4 Pi0 = floor(P); // Integer part for indexing
|
||||||
|
vec4 Pi1 = Pi0 + 1.0; // Integer part + 1
|
||||||
|
Pi0 = mod(Pi0, 289.0);
|
||||||
|
Pi1 = mod(Pi1, 289.0);
|
||||||
|
vec4 Pf0 = fract(P); // Fractional part for interpolation
|
||||||
|
vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0
|
||||||
|
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
|
||||||
|
vec4 iy = vec4(Pi0.yy, Pi1.yy);
|
||||||
|
vec4 iz0 = vec4(Pi0.zzzz);
|
||||||
|
vec4 iz1 = vec4(Pi1.zzzz);
|
||||||
|
vec4 iw0 = vec4(Pi0.wwww);
|
||||||
|
vec4 iw1 = vec4(Pi1.wwww);
|
||||||
|
|
||||||
|
vec4 ixy = permute(permute(ix) + iy);
|
||||||
|
vec4 ixy0 = permute(ixy + iz0);
|
||||||
|
vec4 ixy1 = permute(ixy + iz1);
|
||||||
|
vec4 ixy00 = permute(ixy0 + iw0);
|
||||||
|
vec4 ixy01 = permute(ixy0 + iw1);
|
||||||
|
vec4 ixy10 = permute(ixy1 + iw0);
|
||||||
|
vec4 ixy11 = permute(ixy1 + iw1);
|
||||||
|
|
||||||
|
vec4 gx00 = ixy00 / 7.0;
|
||||||
|
vec4 gy00 = floor(gx00) / 7.0;
|
||||||
|
vec4 gz00 = floor(gy00) / 6.0;
|
||||||
|
gx00 = fract(gx00) - 0.5;
|
||||||
|
gy00 = fract(gy00) - 0.5;
|
||||||
|
gz00 = fract(gz00) - 0.5;
|
||||||
|
vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
|
||||||
|
vec4 sw00 = step(gw00, vec4(0.0));
|
||||||
|
gx00 -= sw00 * (step(0.0, gx00) - 0.5);
|
||||||
|
gy00 -= sw00 * (step(0.0, gy00) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx01 = ixy01 / 7.0;
|
||||||
|
vec4 gy01 = floor(gx01) / 7.0;
|
||||||
|
vec4 gz01 = floor(gy01) / 6.0;
|
||||||
|
gx01 = fract(gx01) - 0.5;
|
||||||
|
gy01 = fract(gy01) - 0.5;
|
||||||
|
gz01 = fract(gz01) - 0.5;
|
||||||
|
vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
|
||||||
|
vec4 sw01 = step(gw01, vec4(0.0));
|
||||||
|
gx01 -= sw01 * (step(0.0, gx01) - 0.5);
|
||||||
|
gy01 -= sw01 * (step(0.0, gy01) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx10 = ixy10 / 7.0;
|
||||||
|
vec4 gy10 = floor(gx10) / 7.0;
|
||||||
|
vec4 gz10 = floor(gy10) / 6.0;
|
||||||
|
gx10 = fract(gx10) - 0.5;
|
||||||
|
gy10 = fract(gy10) - 0.5;
|
||||||
|
gz10 = fract(gz10) - 0.5;
|
||||||
|
vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
|
||||||
|
vec4 sw10 = step(gw10, vec4(0.0));
|
||||||
|
gx10 -= sw10 * (step(0.0, gx10) - 0.5);
|
||||||
|
gy10 -= sw10 * (step(0.0, gy10) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx11 = ixy11 / 7.0;
|
||||||
|
vec4 gy11 = floor(gx11) / 7.0;
|
||||||
|
vec4 gz11 = floor(gy11) / 6.0;
|
||||||
|
gx11 = fract(gx11) - 0.5;
|
||||||
|
gy11 = fract(gy11) - 0.5;
|
||||||
|
gz11 = fract(gz11) - 0.5;
|
||||||
|
vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
|
||||||
|
vec4 sw11 = step(gw11, vec4(0.0));
|
||||||
|
gx11 -= sw11 * (step(0.0, gx11) - 0.5);
|
||||||
|
gy11 -= sw11 * (step(0.0, gy11) - 0.5);
|
||||||
|
|
||||||
|
vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x);
|
||||||
|
vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y);
|
||||||
|
vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z);
|
||||||
|
vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w);
|
||||||
|
vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x);
|
||||||
|
vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y);
|
||||||
|
vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z);
|
||||||
|
vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w);
|
||||||
|
vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x);
|
||||||
|
vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y);
|
||||||
|
vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z);
|
||||||
|
vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w);
|
||||||
|
vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x);
|
||||||
|
vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y);
|
||||||
|
vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z);
|
||||||
|
vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w);
|
||||||
|
|
||||||
|
vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
|
||||||
|
g0000 *= norm00.x;
|
||||||
|
g0100 *= norm00.y;
|
||||||
|
g1000 *= norm00.z;
|
||||||
|
g1100 *= norm00.w;
|
||||||
|
|
||||||
|
vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
|
||||||
|
g0001 *= norm01.x;
|
||||||
|
g0101 *= norm01.y;
|
||||||
|
g1001 *= norm01.z;
|
||||||
|
g1101 *= norm01.w;
|
||||||
|
|
||||||
|
vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
|
||||||
|
g0010 *= norm10.x;
|
||||||
|
g0110 *= norm10.y;
|
||||||
|
g1010 *= norm10.z;
|
||||||
|
g1110 *= norm10.w;
|
||||||
|
|
||||||
|
vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
|
||||||
|
g0011 *= norm11.x;
|
||||||
|
g0111 *= norm11.y;
|
||||||
|
g1011 *= norm11.z;
|
||||||
|
g1111 *= norm11.w;
|
||||||
|
|
||||||
|
float n0000 = dot(g0000, Pf0);
|
||||||
|
float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));
|
||||||
|
float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));
|
||||||
|
float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));
|
||||||
|
float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));
|
||||||
|
float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
|
||||||
|
float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));
|
||||||
|
float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));
|
||||||
|
float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));
|
||||||
|
float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));
|
||||||
|
float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
|
||||||
|
float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));
|
||||||
|
float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));
|
||||||
|
float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));
|
||||||
|
float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));
|
||||||
|
float n1111 = dot(g1111, Pf1);
|
||||||
|
|
||||||
|
vec4 fade_xyzw = fade(Pf0);
|
||||||
|
vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);
|
||||||
|
vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);
|
||||||
|
vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);
|
||||||
|
vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);
|
||||||
|
float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
|
||||||
|
return 2.2 * n_xyzw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Classic Perlin noise, periodic version
|
||||||
|
float cnoise(vec4 P, vec4 rep){
|
||||||
|
vec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep
|
||||||
|
vec4 Pi1 = mod(Pi0 + 1.0, rep); // Integer part + 1 mod rep
|
||||||
|
vec4 Pf0 = fract(P); // Fractional part for interpolation
|
||||||
|
vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0
|
||||||
|
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
|
||||||
|
vec4 iy = vec4(Pi0.yy, Pi1.yy);
|
||||||
|
vec4 iz0 = vec4(Pi0.zzzz);
|
||||||
|
vec4 iz1 = vec4(Pi1.zzzz);
|
||||||
|
vec4 iw0 = vec4(Pi0.wwww);
|
||||||
|
vec4 iw1 = vec4(Pi1.wwww);
|
||||||
|
|
||||||
|
vec4 ixy = permute(permute(ix) + iy);
|
||||||
|
vec4 ixy0 = permute(ixy + iz0);
|
||||||
|
vec4 ixy1 = permute(ixy + iz1);
|
||||||
|
vec4 ixy00 = permute(ixy0 + iw0);
|
||||||
|
vec4 ixy01 = permute(ixy0 + iw1);
|
||||||
|
vec4 ixy10 = permute(ixy1 + iw0);
|
||||||
|
vec4 ixy11 = permute(ixy1 + iw1);
|
||||||
|
|
||||||
|
vec4 gx00 = ixy00 / 7.0;
|
||||||
|
vec4 gy00 = floor(gx00) / 7.0;
|
||||||
|
vec4 gz00 = floor(gy00) / 6.0;
|
||||||
|
gx00 = fract(gx00) - 0.5;
|
||||||
|
gy00 = fract(gy00) - 0.5;
|
||||||
|
gz00 = fract(gz00) - 0.5;
|
||||||
|
vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
|
||||||
|
vec4 sw00 = step(gw00, vec4(0.0));
|
||||||
|
gx00 -= sw00 * (step(0.0, gx00) - 0.5);
|
||||||
|
gy00 -= sw00 * (step(0.0, gy00) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx01 = ixy01 / 7.0;
|
||||||
|
vec4 gy01 = floor(gx01) / 7.0;
|
||||||
|
vec4 gz01 = floor(gy01) / 6.0;
|
||||||
|
gx01 = fract(gx01) - 0.5;
|
||||||
|
gy01 = fract(gy01) - 0.5;
|
||||||
|
gz01 = fract(gz01) - 0.5;
|
||||||
|
vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
|
||||||
|
vec4 sw01 = step(gw01, vec4(0.0));
|
||||||
|
gx01 -= sw01 * (step(0.0, gx01) - 0.5);
|
||||||
|
gy01 -= sw01 * (step(0.0, gy01) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx10 = ixy10 / 7.0;
|
||||||
|
vec4 gy10 = floor(gx10) / 7.0;
|
||||||
|
vec4 gz10 = floor(gy10) / 6.0;
|
||||||
|
gx10 = fract(gx10) - 0.5;
|
||||||
|
gy10 = fract(gy10) - 0.5;
|
||||||
|
gz10 = fract(gz10) - 0.5;
|
||||||
|
vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
|
||||||
|
vec4 sw10 = step(gw10, vec4(0.0));
|
||||||
|
gx10 -= sw10 * (step(0.0, gx10) - 0.5);
|
||||||
|
gy10 -= sw10 * (step(0.0, gy10) - 0.5);
|
||||||
|
|
||||||
|
vec4 gx11 = ixy11 / 7.0;
|
||||||
|
vec4 gy11 = floor(gx11) / 7.0;
|
||||||
|
vec4 gz11 = floor(gy11) / 6.0;
|
||||||
|
gx11 = fract(gx11) - 0.5;
|
||||||
|
gy11 = fract(gy11) - 0.5;
|
||||||
|
gz11 = fract(gz11) - 0.5;
|
||||||
|
vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
|
||||||
|
vec4 sw11 = step(gw11, vec4(0.0));
|
||||||
|
gx11 -= sw11 * (step(0.0, gx11) - 0.5);
|
||||||
|
gy11 -= sw11 * (step(0.0, gy11) - 0.5);
|
||||||
|
|
||||||
|
vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x);
|
||||||
|
vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y);
|
||||||
|
vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z);
|
||||||
|
vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w);
|
||||||
|
vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x);
|
||||||
|
vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y);
|
||||||
|
vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z);
|
||||||
|
vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w);
|
||||||
|
vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x);
|
||||||
|
vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y);
|
||||||
|
vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z);
|
||||||
|
vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w);
|
||||||
|
vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x);
|
||||||
|
vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y);
|
||||||
|
vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z);
|
||||||
|
vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w);
|
||||||
|
|
||||||
|
vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
|
||||||
|
g0000 *= norm00.x;
|
||||||
|
g0100 *= norm00.y;
|
||||||
|
g1000 *= norm00.z;
|
||||||
|
g1100 *= norm00.w;
|
||||||
|
|
||||||
|
vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
|
||||||
|
g0001 *= norm01.x;
|
||||||
|
g0101 *= norm01.y;
|
||||||
|
g1001 *= norm01.z;
|
||||||
|
g1101 *= norm01.w;
|
||||||
|
|
||||||
|
vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
|
||||||
|
g0010 *= norm10.x;
|
||||||
|
g0110 *= norm10.y;
|
||||||
|
g1010 *= norm10.z;
|
||||||
|
g1110 *= norm10.w;
|
||||||
|
|
||||||
|
vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
|
||||||
|
g0011 *= norm11.x;
|
||||||
|
g0111 *= norm11.y;
|
||||||
|
g1011 *= norm11.z;
|
||||||
|
g1111 *= norm11.w;
|
||||||
|
|
||||||
|
float n0000 = dot(g0000, Pf0);
|
||||||
|
float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));
|
||||||
|
float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));
|
||||||
|
float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));
|
||||||
|
float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));
|
||||||
|
float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
|
||||||
|
float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));
|
||||||
|
float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));
|
||||||
|
float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));
|
||||||
|
float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));
|
||||||
|
float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
|
||||||
|
float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));
|
||||||
|
float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));
|
||||||
|
float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));
|
||||||
|
float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));
|
||||||
|
float n1111 = dot(g1111, Pf1);
|
||||||
|
|
||||||
|
vec4 fade_xyzw = fade(Pf0);
|
||||||
|
vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);
|
||||||
|
vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);
|
||||||
|
vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);
|
||||||
|
vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);
|
||||||
|
float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
|
||||||
|
return 2.2 * n_xyzw;
|
||||||
|
}
|
||||||
|
|
||||||
|
varying vec2 vUv;
|
||||||
|
varying vec3 vPosition;
|
||||||
|
uniform float uTime;
|
||||||
|
|
||||||
|
// 6 lyers of noise
|
||||||
|
|
||||||
|
float fbm(vec4 p){
|
||||||
|
float sum = 0.;
|
||||||
|
float amp = 1.;
|
||||||
|
float scale = 0.5;
|
||||||
|
for(int i = 0; i < 6; i++){
|
||||||
|
sum+=cnoise(p*scale)*amp;
|
||||||
|
//p.w += 100.;
|
||||||
|
amp*=0.9;
|
||||||
|
scale *= 3.9;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
vec4 p = vec4(vPosition*3.,uTime*0.4);
|
||||||
|
|
||||||
|
float noisy = fbm(p*0.1);
|
||||||
|
|
||||||
|
vec4 p1 = vec4(vPosition*2.,uTime*0.05);
|
||||||
|
float spots = max(cnoise(p1),0.5);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(noisy);
|
||||||
|
gl_FragColor *= mix(1.,spots, 1.0);
|
||||||
|
gl_FragColor *= vec4(1.,0.7,0.,1.);
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
extend({ SunPerlinMaterial });
|
||||||
|
|
||||||
|
const Sun = () => {
|
||||||
|
const { scene, camera } = useThree();
|
||||||
|
const sunPerlinMesh = useRef();
|
||||||
|
const group = useRef();
|
||||||
|
const ref = useRef();
|
||||||
|
|
||||||
|
useFrame(({ clock, gl }) => {
|
||||||
|
gl.render(scene, camera);
|
||||||
|
ref.current.uTime = clock.getElapsedTime();
|
||||||
|
});
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
group.current.userData.counter = 0;
|
||||||
|
group.current.userData.name = "Sun";
|
||||||
|
group.current.userData.nearOvOp = 1800;
|
||||||
|
group.current.userData.scolor = "white";
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const sunMesh = useRef();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<group ref={group}>
|
||||||
|
<PlanetOverlay planet={group} />
|
||||||
|
<mesh ref={sunPerlinMesh} position={[0, 0, 0]}>
|
||||||
|
<sphereGeometry args={[32, 50, 50]} />
|
||||||
|
<sunPerlinMaterial ref={ref} />
|
||||||
|
</mesh>
|
||||||
|
<CubeCamera near={0.1} far={35} frames={3}>
|
||||||
|
{(texture) => (
|
||||||
|
<>
|
||||||
|
<mesh ref={sunMesh} position={[0, 0, 0]}>
|
||||||
|
<sphereGeometry args={[33, 50, 50]} />
|
||||||
|
<meshBasicMaterial envMap={texture} />
|
||||||
|
</mesh>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</CubeCamera>
|
||||||
|
</group>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sun;
|
||||||
9
vite.config.js
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
import glsl from "vite-plugin-glsl";
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react(), glsl()],
|
||||||
|
publicDir: 'public'
|
||||||
|
});
|
||||||