Spaces:
Running
Running
import * as THREE from 'three'; | |
import Stats from 'three/addons/libs/stats.module.js'; | |
import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js'; | |
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | |
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | |
import { Line2 } from 'three/addons/lines/Line2.js'; | |
import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; | |
import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; | |
import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; | |
import {CSG} from "./threecsg.js" | |
var res = window.res; | |
var hc = window.hc; | |
var multi_high = window.multi_high; | |
var current_frame = 0; | |
var meshes = []; | |
var joint_meshes = []; | |
function make_linkage(x_length, y_length, z_length, hole_r) { | |
var link = new THREE.BoxGeometry( x_length, y_length, z_length ); | |
var end_1 = new THREE.CylinderGeometry(y_length/2, y_length/2, z_length, 32); | |
var end_2 = new THREE.CylinderGeometry(y_length/2, y_length/2, z_length, 32); | |
var hole_1 = new THREE.CylinderGeometry(hole_r, hole_r, z_length, 32); | |
var hole_2 = new THREE.CylinderGeometry(hole_r, hole_r, z_length, 32); | |
end_1.rotateX(Math.PI/2).translate(-x_length/2, 0, 0); | |
end_2.rotateX(Math.PI/2).translate(x_length/2, 0, 0); | |
hole_1.rotateX(Math.PI/2).translate(-x_length/2, 0, 0); | |
hole_2.rotateX(Math.PI/2).translate(x_length/2, 0, 0); | |
var bsp_link = CSG.fromMesh(new THREE.Mesh(link)); | |
var hole_1 = CSG.fromMesh(new THREE.Mesh(hole_1)); | |
var hole_2 = CSG.fromMesh(new THREE.Mesh(hole_2)); | |
var bsp_end_1 = CSG.fromMesh(new THREE.Mesh(end_1)).subtract(bsp_link).subtract(hole_1); | |
var bsp_end_2 = CSG.fromMesh(new THREE.Mesh(end_2)).subtract(bsp_link).subtract(hole_2); | |
bsp_link = bsp_link.subtract(hole_1).subtract(hole_2); | |
var full_link = CSG.toMesh(bsp_link.union(bsp_end_1).union(bsp_end_2)); | |
return full_link; | |
} | |
function make_link(x_length, y_length, z_length, hole_r, Theta_z, translation) { | |
var full_link = make_linkage(x_length, y_length, z_length * 0.9, hole_r); | |
full_link.rotation.z = Theta_z; | |
full_link.position.set(translation[0] + x_length/2 * Math.cos(Theta_z), translation[1] + x_length/2 * Math.sin(Theta_z), translation[2]); | |
return full_link; | |
} | |
function make_joint(x, y, z, height, radius=0.03) { | |
var joint = new THREE.CylinderGeometry(radius, radius, height * 0.9, 32); | |
joint.rotateX(Math.PI/2); | |
joint = new THREE.Mesh(joint); | |
joint.position.set(x, y, z); | |
return joint; | |
} | |
(async function onLoad() { | |
var res = window.res; | |
var hc = window.hc; | |
var multi_high = window.multi_high; | |
// find the mean value of the res array | |
var max_x = 0; | |
var max_y = 0; | |
var min_x = Infinity; | |
var min_y = Infinity; | |
for(let i = 0; i < res.length; i++) { | |
for(let j = 0; j < res[i][1].length; j++) { | |
if (res[i][1][j][0] > max_x) { | |
max_x = res[i][1][j][0]; | |
} | |
if (res[i][1][j][0] < min_x) { | |
min_x = res[i][1][j][0]; | |
} | |
if (res[i][1][j][1] > max_y) { | |
max_y = res[i][1][j][1]; | |
} | |
if (res[i][1][j][1] < min_y) { | |
min_y = res[i][1][j][1]; | |
} | |
} | |
} | |
var mean_x = (max_x + min_x) / 2; | |
var mean_y = (max_y + min_y) / 2; | |
var container, camera, scene, renderer, controls, last_frame_time; | |
init(); | |
animate(); | |
controls.update(); | |
function init() { | |
container = document.getElementById('container'); | |
renderer = new THREE.WebGLRenderer({ | |
antialias: true | |
}); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
renderer.shadowMap.enabled = true; | |
container.appendChild(renderer.domElement); | |
scene = new THREE.Scene(); | |
scene.background = new THREE.Color(0xfafafa); | |
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); | |
camera.position.set(mean_x,mean_y, 20); | |
scene.add(camera); | |
window.onresize = function() { | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
} | |
var ambientLight = new THREE.AmbientLight(0xffffff, 2.0); | |
scene.add(ambientLight); | |
// var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); | |
// directionalLight.position.x = 4; | |
// directionalLight.position.y = 1; | |
// directionalLight.position.z = -2; | |
// scene.add( directionalLight ); | |
controls = new OrbitControls(camera, renderer.domElement); | |
controls.target.set(mean_x,mean_y,0); | |
// addGridHelper(); | |
createModel(0); | |
last_frame_time = Date.now(); | |
} | |
function createModel(j) { | |
var results = res[j]; | |
//iterate through the results and create the links | |
meshes = [] | |
for (let i = 0; i < results[0].length; i++) { | |
var link = results[0][i]; | |
meshes.push(make_link(link[0], link[1], link[2], link[3], link[4], link[5])); | |
if (i == 0){ | |
//yellow | |
meshes[i].material = new THREE.MeshStandardMaterial({ color: 0xff8c00, opacity: 0.5, transparent: true , side: THREE.DoubleSide, depthWrite: true}); | |
} | |
else | |
meshes[i].material = new THREE.MeshStandardMaterial({ color: 0x3b3b3b, opacity: 0.5, transparent: true , side: THREE.DoubleSide, depthWrite: true}); | |
scene.add(meshes[i]); | |
} | |
joint_meshes = [] | |
for (let i = 0; i < results[1].length; i++) { | |
var joint = results[1][i]; | |
joint_meshes.push(make_joint(joint[0], joint[1], joint[3], joint[2])); | |
if(joint[4] == 1)//brown | |
joint_meshes[i].material = new THREE.MeshStandardMaterial({ color: 0xff4c00, side: THREE.DoubleSide, depthWrite: false}); | |
else | |
joint_meshes[i].material = new THREE.MeshStandardMaterial({ color: 0x121212, side: THREE.DoubleSide, depthWrite: false}); | |
scene.add(joint_meshes[i]); | |
} | |
if (multi_high) { | |
var n = hc.length; | |
for (let j = 0; j < n; j++) { | |
var points = []; | |
var colors = []; | |
for (let i = 0; i <hc[j].length; i++) { | |
points.push(hc[j][i][0], hc[j][i][1], hc[j][i][2]); | |
} | |
var geometry = new LineGeometry(); | |
geometry.setPositions( points ); | |
var material = new LineMaterial( { | |
color: 0xff4c00, | |
linewidth: 0.002, // in world units with size attenuation, pixels otherwise | |
vertexColors: false, | |
//resolution: // to be set by renderer, eventually | |
dashed: false, | |
alphaToCoverage: false, | |
depthWrite: false, | |
depthTest: false, | |
transparent: true, | |
}); | |
material.worldUnits = false; | |
const line = new Line2(geometry, material); | |
line.computeLineDistances(); | |
line.scale.set( 1, 1, 1 ); | |
line.renderOrder= 9999; | |
scene.add(line); | |
} | |
} | |
else{ | |
var points = []; | |
var colors = []; | |
for (let i = 0; i <hc.length; i++) { | |
points.push(hc[i][0], hc[i][1], hc[i][2]); | |
} | |
var geometry = new LineGeometry(); | |
geometry.setPositions( points ); | |
var material = new LineMaterial( { | |
color: 0xff4c00, | |
linewidth: 0.002, // in world units with size attenuation, pixels otherwise | |
vertexColors: false, | |
//resolution: // to be set by renderer, eventually | |
dashed: false, | |
alphaToCoverage: false, | |
depthWrite: false, | |
depthTest: false, | |
transparent: true, | |
}); | |
material.worldUnits = false; | |
const line = new Line2(geometry, material); | |
line.computeLineDistances(); | |
line.scale.set( 1, 1, 1 ); | |
line.renderOrder= 9999; | |
scene.add(line); | |
} | |
} | |
function addGridHelper() { | |
var helper = new THREE.GridHelper(10, 10); | |
helper.material.opacity = 0.25; | |
helper.material.transparent = true; | |
scene.add(helper); | |
var axis = new THREE.AxesHelper(100); | |
scene.add(axis); | |
} | |
function set_idx(){ | |
if(current_frame < res.length-1) { | |
// createModel(current_frame); | |
current_frame += 1; | |
} | |
else { | |
current_frame = 0; | |
} | |
} | |
function animate() { | |
if (Date.now() - last_frame_time > 1000/30) { | |
set_idx(); | |
last_frame_time = Date.now(); | |
} | |
for (let i = 0; i < meshes.length; i++) { | |
meshes[i].rotation.z = res[current_frame][0][i][4]; | |
meshes[i].position.set(res[current_frame][0][i][5][0] + res[current_frame][0][i][0]/2 * Math.cos(res[current_frame][0][i][4]), res[current_frame][0][i][5][1] + res[current_frame][0][i][0]/2 * Math.sin(res[current_frame][0][i][4]), res[current_frame][0][i][5][2]); | |
} | |
for (let i = 0; i < joint_meshes.length; i++) { | |
joint_meshes[i].position.set(res[current_frame][1][i][0], res[current_frame][1][i][1], res[current_frame][1][i][3]); | |
} | |
requestAnimationFrame(animate); | |
render(); | |
} | |
function render() { | |
renderer.clearDepth(); | |
renderer.render(scene, camera); | |
} | |
})(); |