var container = document.getElementById("container");
|
var view = document.getElementById("main_viewer");
|
|
function getUrlParams() {
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
return Object.fromEntries(urlSearchParams);
|
}
|
|
if (!Detector.webgl) Detector.addGetWebGLMessage();
|
|
var camera,
|
camerHelper,
|
scene,
|
renderer,
|
loader,
|
stats,
|
controls,
|
transformControls,
|
numOfMeshes = 0,
|
model,
|
modelDuplicate,
|
sample_model,
|
wireframe,
|
mat,
|
scale,
|
delta;
|
|
const manager = new THREE.LoadingManager();
|
|
var modelLoaded = false,
|
sample_model_loaded = false;
|
var modelWithTextures = false,
|
fbxLoaded = false,
|
gltfLoaded = false;
|
var bg_Texture = false;
|
|
var glow_value,
|
selectedObject,
|
composer,
|
effectFXAA,
|
position,
|
outlinePass,
|
ssaaRenderPass;
|
var clock = new THREE.Clock();
|
|
var ambient,
|
directionalLight,
|
directionalLight2,
|
directionalLight3,
|
pointLight,
|
bg_colour;
|
var backgroundScene, backgroundCamera, backgroundMesh;
|
|
var amb = document.getElementById("ambient_light");
|
var rot1 = document.getElementById("rotation");
|
var wire = document.getElementById("wire_check");
|
var model_wire = document.getElementById("model_wire");
|
var phong = document.getElementById("phong_check");
|
var xray = document.getElementById("xray_check");
|
var glow = document.getElementById("glow_check");
|
var grid = document.getElementById("grid");
|
var polar_grid = document.getElementById("polar_grid");
|
var axis = document.getElementById("axis");
|
var bBox = document.getElementById("bBox");
|
|
var transform = document.getElementById("transform");
|
var smooth = document.getElementById("smooth");
|
var outline = document.getElementById("outline");
|
|
var statsNode = document.getElementById("stats");
|
|
//ANIMATION GLOBALS
|
var animations = {},
|
animationsSelect = document.getElementById("animationSelect"),
|
animsDiv = document.getElementById("anims"),
|
mixer,
|
currentAnimation,
|
actions = {};
|
|
//X-RAY SHADER MATERIAL
|
//http://free-tutorials.org/shader-x-ray-effect-with-three-js/
|
var materials = {
|
default_material: new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }),
|
default_material2: new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }),
|
wireframeMaterial: new THREE.MeshPhongMaterial({
|
side: THREE.DoubleSide,
|
wireframe: true,
|
shininess: 100,
|
specular: 0x000,
|
emissive: 0x000,
|
flatShading: false,
|
depthWrite: true,
|
depthTest: true,
|
}),
|
wireframeMaterial2: new THREE.LineBasicMaterial({
|
wireframe: true,
|
color: 0xffffff,
|
}),
|
wireframeAndModel: new THREE.LineBasicMaterial({ color: 0xffffff }),
|
phongMaterial: new THREE.MeshPhongMaterial({
|
color: 0x555555,
|
specular: 0xffffff,
|
shininess: 10,
|
flatShading: false,
|
side: THREE.DoubleSide,
|
skinning: true,
|
}),
|
xrayMaterial: new THREE.ShaderMaterial({
|
uniforms: {
|
p: { type: "f", value: 3 },
|
glowColor: { type: "c", value: new THREE.Color(0x84ccff) },
|
},
|
vertexShader: document.getElementById("vertexShader").textContent,
|
fragmentShader: document.getElementById("fragmentShader").textContent,
|
side: THREE.DoubleSide,
|
blending: THREE.AdditiveBlending,
|
transparent: true,
|
depthWrite: false,
|
}),
|
};
|
|
var clock = new THREE.Clock();
|
var winDims = [window.innerWidth * 0.8, window.innerHeight * 0.89]; //size of renderer
|
|
function onload() {
|
// 是否显示菜单
|
//window.addEventListener('resize', onWindowResize, false);
|
const dataStr = getUrlParams();
|
if (!dataStr.target) {
|
document.getElementById("fullscreen").style.display = "block";
|
document.getElementById("customSlide").style.display = "block";
|
document.getElementById("collapse_side").style.display = "block";
|
} else {
|
document.getElementById("fullscreen").style.display = "none";
|
}
|
switchScene(0);
|
animate();
|
}
|
|
function initScene(index) {
|
scene = new THREE.Scene();
|
|
camera = new THREE.PerspectiveCamera(
|
70,
|
window.innerWidth / window.innerHeight,
|
0.1,
|
500000
|
);
|
camera.position.set(0, 0, 20);
|
|
//Setup renderer
|
//renderer = new THREE.CanvasRenderer({ alpha: true });
|
renderer = new THREE.WebGLRenderer();
|
renderer.setPixelRatio(window.devicePixelRatio);
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
renderer.setClearColor(0x292121); //565646, 29212
|
|
view.appendChild(renderer.domElement);
|
|
THREEx.WindowResize(renderer, camera);
|
|
ambient = new THREE.AmbientLight(0x404040);
|
$("#ambient_light").change(function () {
|
if (amb.checked) {
|
scene.add(ambient);
|
} else {
|
scene.remove(ambient);
|
}
|
});
|
|
/*LIGHTS*/
|
directionalLight = new THREE.DirectionalLight(0xffeedd);
|
directionalLight.position.set(0, 0, 1).normalize();
|
scene.add(directionalLight);
|
|
directionalLight2 = new THREE.DirectionalLight(0xffeedd);
|
directionalLight2.position.set(0, 0, -1).normalize();
|
scene.add(directionalLight2);
|
|
directionalLight3 = new THREE.DirectionalLight(0xffeedd);
|
directionalLight3.position.set(0, 1, 0).normalize();
|
scene.add(directionalLight3);
|
|
var ambientLight = new THREE.AmbientLight(0x808080, 0.2); //Grey colour, low intensity
|
scene.add(ambientLight);
|
|
pointLight = new THREE.PointLight(0xcccccc, 0.5);
|
camera.add(pointLight);
|
|
scene.add(camera);
|
|
controls = new THREE.OrbitControls(camera, renderer.domElement);
|
controls.enableDamping = true;
|
controls.dampingFactor = 0.09;
|
controls.rotateSpeed = 0.09;
|
|
transformControls = new THREE.TransformControls(camera, renderer.domElement);
|
transformControls.addEventListener("change", render);
|
scene.add(transformControls);
|
|
transformControls.addEventListener("mouseDown", function () {
|
controls.enabled = false;
|
});
|
transformControls.addEventListener("mouseUp", function () {
|
controls.enabled = true;
|
});
|
|
window.addEventListener("keydown", function (event) {
|
switch (event.keyCode) {
|
case 82: // R key pressed - set rotate mode
|
transformControls.setMode("rotate");
|
break;
|
|
case 84: // T key pressed - set translate mode
|
transformControls.setMode("translate");
|
break;
|
|
case 83: // S key pressed - set scale mode
|
transformControls.setMode("scale");
|
break;
|
}
|
});
|
|
//Colour changer, to set background colour of renderer to user chosen colour
|
$(".bg_select").spectrum({
|
color: "#fff",
|
change: function (color) {
|
$("#basic_log").text("Hex Colour Selected: " + color.toHexString()); //Log information
|
var bg_value = $(".bg_select").spectrum("get").toHexString(); //Get the colour selected
|
renderer.setClearColor(bg_value); //Set renderer colour to the selected hex value
|
ssaaRenderPass.clearColor = bg_value;
|
document.body.style.background = bg_value; //Set body of document to selected colour
|
},
|
});
|
|
// postprocessing
|
var renderPass = new THREE.RenderPass(scene, camera);
|
|
var fxaaPass = new THREE.ShaderPass(THREE.FXAAShader);
|
var pixelRatio = renderer.getPixelRatio();
|
|
fxaaPass.material.uniforms["resolution"].value.x =
|
1 / (window.innerWidth * pixelRatio);
|
fxaaPass.material.uniforms["resolution"].value.y =
|
1 / (window.innerHeight * pixelRatio);
|
fxaaPass.renderToScreen = true;
|
|
outlinePass = new THREE.OutlinePass(
|
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
scene,
|
camera
|
);
|
outlinePass.edgeStrength = 1.5;
|
outlinePass.edgeGlow = 2;
|
|
composer = new THREE.EffectComposer(renderer);
|
composer.addPass(renderPass);
|
composer.addPass(outlinePass);
|
composer.addPass(fxaaPass);
|
|
/*LOAD SAMPLE MODELS*/
|
const dataS = getUrlParams();
|
// const str = dataS.domain + '/file/api/ApiDownload?md5=' + dataS.md5
|
let str = "";
|
let exd = dataS.exd;
|
if (dataS.token != null || dataS.token != undefined) {
|
str =
|
dataS.domain +
|
`/file/api/ApiDownloadForAuthorize?md5=${dataS.md5}&token=${dataS.token}`;
|
} else {
|
str = dataS.domain + `/file/api/ApiDownload?md5=${dataS.md5}`;
|
}
|
var modelList = [
|
{
|
name: dataS.name,
|
url: str,
|
},
|
];
|
var sceneInfo = modelList[index]; //index from array of sample models in html select options
|
if (exd == "obj") {
|
loader = new THREE.OBJLoader(manager);
|
}
|
if (exd == "fbx" || !exd) {
|
loader = new THREE.FBXLoader(manager);
|
}
|
var url = sceneInfo.url;
|
|
//progress/loading bar
|
var onProgress = function (data) {
|
if (data.lengthComputable) {
|
//if size of file transfer is known
|
var percentage = Math.round((data.loaded * 100) / data.total);
|
statsNode.innerHTML =
|
"Loaded : " +
|
percentage +
|
"%" +
|
" of " +
|
sceneInfo.name +
|
"<br>" +
|
'<progress value="0" max="100" class="progress"></progress>';
|
$(".progress").css({ width: percentage + "%" });
|
$(".progress").val(percentage);
|
}
|
};
|
var onError = function (xhr) {
|
console.log("ERROR");
|
};
|
|
loader.load(
|
url,
|
function (data) {
|
sample_model = data;
|
sample_model_loaded = true;
|
sample_model.traverse(function (child) {
|
if (child instanceof THREE.Mesh) {
|
numOfMeshes++;
|
var geometry = child.geometry;
|
stats(sceneInfo.name, geometry, numOfMeshes);
|
|
child.material = materials.default_material;
|
|
var wireframe2 = new THREE.WireframeGeometry(child.geometry);
|
var edges = new THREE.LineSegments(
|
wireframe2,
|
materials.wireframeAndModel
|
);
|
materials.wireframeAndModel.visible = false;
|
sample_model.add(edges);
|
|
setWireFrame(child);
|
setWireframeAndModel(child);
|
|
setPhong(child);
|
setXray(child);
|
}
|
});
|
|
setCamera(sample_model);
|
|
setSmooth(sample_model);
|
|
setBoundBox(sample_model);
|
setPolarGrid(sample_model);
|
setGrid(sample_model);
|
setAxis(sample_model);
|
|
scaleUp(sample_model);
|
scaleDown(sample_model);
|
|
selectedObject = sample_model;
|
outlinePass.selectedObjects = [selectedObject];
|
outlinePass.enabled = false;
|
|
scene.add(sample_model);
|
},
|
onProgress,
|
onError
|
);
|
|
$("#transform").on("change", function () {
|
if (transform.checked) {
|
document.getElementById("transformKey").style.display = "block";
|
if (modelLoaded) {
|
transformControls.attach(model);
|
} else if (sample_model_loaded) {
|
transformControls.attach(sample_model);
|
}
|
} else {
|
document.getElementById("transformKey").style.display = "none";
|
transformControls.detach(scene);
|
}
|
});
|
}
|
|
function getUrlParams() {
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
return Object.fromEntries(urlSearchParams);
|
}
|
|
function toggleFullscreen(elem) {
|
elem = elem || document.documentElement;
|
if (
|
!document.fullscreenElement &&
|
!document.mozFullScreenElement &&
|
!document.webkitFullscreenElement &&
|
!document.msFullscreenElement
|
) {
|
THREEx.FullScreen.request(container);
|
setTimeout(() => {
|
onload();
|
}, 200);
|
} else {
|
THREEx.FullScreen.cancel();
|
// if (document.exitFullscreen) {
|
// document.exitFullscreen()
|
// } else if (document.msExitFullscreen) {
|
// document.msExitFullscreen()
|
// //renderer.setSize(winDims[0], winDims[1]); //Reset renderer size on fullscreen exit
|
// } else if (document.mozCancelFullScreen) {
|
// document.mozCancelFullScreen()
|
// //renderer.setSize(winDims[0], winDims[1]);
|
// } else if (document.webkitExitFullscreen) {
|
// document.webkitExitFullscreen()
|
// // renderer.setSize(winDims[0], winDims[1]);
|
// }
|
}
|
}
|
|
document.getElementById("fullscreenBtn").addEventListener("click", function () {
|
toggleFullscreen(document.getElementById("container"));
|
});
|
|
function removeModel() {
|
scene.remove(model);
|
scale = 1;
|
numOfMeshes = 0;
|
modelLoaded = false;
|
modelWithTextures = false;
|
fbxLoaded = false;
|
gltfLoaded = false;
|
|
if (ambient) {
|
scene.remove(ambient);
|
}
|
|
$("#point_light").slider("value", 0.5);
|
pointLight.intensity = 0.5;
|
|
camera.position.set(0, 0, 20); //Reset camera to initial position
|
controls.reset(); //Reset controls, for when previous object has been moved around e.g. larger object = larger rotation
|
statsNode.innerHTML = ""; //Reset stats box (faces, vertices etc)
|
|
$("#red, #green, #blue, #ambient_red, #ambient_green, #ambient_blue").slider(
|
"value",
|
127
|
); //Reset colour sliders
|
|
amb.checked = false;
|
rot1.checked = false;
|
wire.checked = false;
|
model_wire.checked = false;
|
phong.checked = false;
|
xray.checked = false;
|
glow.checked = false;
|
grid.checked = false;
|
polar_grid.checked = false;
|
axis.checked = false;
|
bBox.checked = false;
|
smooth.checked = false;
|
(transform.checked = false), (smooth.disabled = false); //Uncheck any checked boxes
|
|
transformControls.detach(scene);
|
|
document.getElementById("smooth-model").innerHTML = "Smooth Model";
|
|
$("#rot_slider").slider({
|
disabled: true, //disable the rotation slider
|
});
|
controls.autoRotate = false; //Stop model auto rotating if doing so on new file select
|
$("#shine").slider("value", 10); //Set phong shine level back to initial
|
|
$('input[name="rotate"]').prop("checked", false); //uncheck rotate x, y or z checkboxes
|
|
animsDiv.style.display = "none"; //Hide animation <div>
|
}
|
|
$("#remove").click(function () {
|
removeModel();
|
});
|
|
$("#red, #green, #blue, #ambient_red, #ambient_green, #ambient_blue").slider({
|
change: function (event, ui) {
|
console.log(ui.value);
|
render();
|
},
|
});
|
|
var rotVal = [40, 80, 110, 140, 170, 200, 240, 280, 340, 400, 520]; //Rotation speeds low - high
|
var rotation_speed;
|
|
$("#rot_slider").slider({
|
orientation: "horizontal",
|
range: "min",
|
max: rotVal.length - 1,
|
value: 0,
|
disabled: true,
|
slide: function (event, ui) {
|
rotation_speed = rotVal[ui.value]; //Set speed variable to the current selected value of slider
|
},
|
});
|
|
$("#rotation").change(function () {
|
if (rot1.checked) {
|
rotation_speed = rotVal[$("#rot_slider").slider("value")];
|
//set the speed to the current slider value on initial use
|
controls.autoRotate = true;
|
|
$("#rot_slider").slider({
|
disabled: false,
|
change: function (event, ui) {
|
console.log(rotVal[ui.value]);
|
controls.autoRotate = true;
|
controls.autoRotateSpeed = delta * rotation_speed;
|
},
|
});
|
} else {
|
controls.autoRotate = false;
|
$("#rot_slider").slider({
|
disabled: true, //disable the slider from being able to rotate object when rotation toggle is off
|
});
|
}
|
});
|
|
function setColours() {
|
var colour = getColours(
|
$("#red").slider("value"),
|
$("#green").slider("value"),
|
$("#blue").slider("value")
|
);
|
directionalLight.color.setRGB(colour[0], colour[1], colour[2]);
|
directionalLight2.color.setRGB(colour[0], colour[1], colour[2]);
|
directionalLight3.color.setRGB(colour[0], colour[1], colour[2]);
|
|
var colour = getColours(
|
$("#ambient_red").slider("value"),
|
$("#ambient_green").slider("value"),
|
$("#ambient_blue").slider("value")
|
);
|
ambient.color.setRGB(colour[0], colour[1], colour[2]);
|
}
|
|
function getColours(r, g, b) {
|
var colour = [r.valueOf() / 255, g.valueOf() / 255, b.valueOf() / 255];
|
return colour;
|
}
|
|
function render() {
|
setColours();
|
// renderer.render(scene, camera);
|
}
|
|
function animate() {
|
delta = clock.getDelta();
|
requestAnimationFrame(animate);
|
|
if (mixer) {
|
mixer.update(delta);
|
}
|
controls.update(delta);
|
|
composer.render();
|
render();
|
}
|
|
function switchScene(index) {
|
clear();
|
initScene(index);
|
var elt = document.getElementById("scenes_list");
|
elt.selectedIndex = index;
|
}
|
|
function selectModel() {
|
var select = document.getElementById("scenes_list");
|
var index = select.selectedIndex;
|
|
if (index >= 0) {
|
removeModel();
|
switchScene(index);
|
}
|
}
|
|
function clear() {
|
if (view && renderer) {
|
view.removeChild(renderer.domElement);
|
document.body.style.background = "#292121";
|
}
|
}
|
|
onload();
|