Files
web3d/TestArea_IIS01/THREEJS_DOORS/index.html
T
2024-03-25 08:55:25 +01:00

265 lines
12 KiB
HTML

<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
<title> Door render </title>
<link rel = "stylesheet" href = "style.css">
<script type = "importmap">
{
"imports": {
"three": "./Libs/node_modules/three/build/three.module.js",
"three/addons/": "./Libs/node_modules/three/examples/jsm/"
}
}
</script>
</head>
<body>
<!-- definition of Menu -->
<div id = 'divMenu'>
<!-- 3 elements: Logo, button "?" and Information -->
<div id = 'divLogo'></div>
<button id = 'helpButton'>?</button>
<div id = 'infoDiv'></div>
</div>
<div id = 'DoorRender'></div>
<!--<div id = 'Info'>
Camera settings : <br>
&emsp; Zoom : Wheel-Scroll <br>
&emsp; Pan : Mouse-Left and Drag ( hold ) <br>
&emsp; Rotate : Mouse-Right and Drag ( hold ) <br>
&emsp; Type : Key-O ( orthographic ) | Key-P ( perspective ) <br><br>
Toggle Auto-rotation : Key-R <br><br>
Toggle Show-Dimension : Key-D
</div> -->
<script type = 'module'>
// importing
import * as THREE from './Libs/node_modules/three/build/three.module.js' ;
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { Rhino3dmLoader} from 'three/addons/loaders/3DMLoader.js' ;
// settings
const EPS_SMALL = 0.001 ;
const GRID_GROUP_NAME = 'gridGroup' ;
const FRAME_GROUP_NAME = 'frameGroup' ;
const CAMERA_PERSP = 0 ;
const CAMERA_ORTHO = 1 ;
var SCENE_BACKGROUND_COLOR = new THREE.Color( 0x808080) ;
var CAMERA_TYPE = CAMERA_PERSP ;
var SHOW_DIMENSION = true ;
var GRID_MAIN_COLOR = new THREE.Color( 0x000000) ;
var GRID_SECOND_COLOR = new THREE.Color( 0xcccccc) ;
var PATH = './Door_models' ;
var FILE_NAME = 'Door1.3dm' ;
// shared variables
/* Box3d of the door ------------ */
var m_box ; var m_size ; var m_center ; // set in setCameraPosition(), used in setGrid(), setFrame()
/* ------------------------------ */
// scene
const scene = new THREE.Scene() ;
scene.background = SCENE_BACKGROUND_COLOR ;
// camera
const perspCamera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.01, 150000) ;
const ortoCamera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2,
window.innerHeight / 2, window.innerHeight / - 2, EPS_SMALL, 150000) ;
// render
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true}) ;
renderer.setSize( window.innerWidth, window.innerHeight) ;
renderer.setPixelRatio( 2 * window.devicePixelRatio) ;
document.getElementById( 'DoorRender').appendChild( renderer.domElement) ;
renderer.shadowMap.enabled = true ;
// light
const ambientLight = new THREE.AmbientLight( 0xffffff, 2.5) ; // color, intensity
scene.add( ambientLight) ;
// controls
const controls = new OrbitControls( CAMERA_TYPE == CAMERA_PERSP ? perspCamera : ortoCamera, renderer.domElement) ;
// reading .3dm file
readDoor() ;
// rendering
function animate() {
requestAnimationFrame( animate) ;
renderer.render( scene, controls.object) ;
controls.update() ;
}
function readDoor() {
const loader = new Rhino3dmLoader() ;
loader.setLibraryPath( './Libs/node_modules/three/examples/jsm/libs/rhino3dm/' ) ;
loader.load( PATH + "/" + FILE_NAME, function( object) {
// removing shading from colors and adjusting z-fighting with lines
for ( let i = 0 ; i < object.children.length ; ++ i)
setOpenGLRenderProperties( object.children[i]) ;
scene.add( object) ;
// setting Box3d of the door
set3dBox( object) ;
// setting camera position
setCameraPosition() ;
// setting grid
setGrid() ;
// setting frame
setFrame() ;
// render loop
animate() ;
}) ;
}
function setOpenGLRenderProperties( object) {
if ( object.type == 'Mesh') {
object.material.emissive.set( 0x000000) ; // Set emissive color to black
object.material.polygonOffset = true ; // enable polygonOffset
object.material.polygonOffsetFactor = 1 ; // shifting mesh
object.material.polygonOffsetUnits = 1 ; // shifting units
object.material.depthTest = true ; // deep test enable for triangle rendering
object.renderOrder = 0 ; // rendering order priority
if ( object.transparent)
object.opacity = 0.25 ;
}
else if ( object.type == 'Line') {
object.material.depthTest = false ; // disable deep test ( no z-fighting with meshes)
object.material.transparent = true ; // setting transparency for visibility inside/outside meshes
object.material.opacity = 1 ; // high-level of opacity
object.renderOrder = 1 ; // ordering them on Z-buffer after meshes
}
}
function set3dBox( object) {
// box of the door
m_box = new THREE.Box3().setFromObject( object) ;
// size of the box
m_size = m_box.getSize( new THREE.Vector3()) ;
// center of the box
m_center = m_box.getCenter( new THREE.Vector3()) ;
}
function setCameraPosition() {
// maxSize of the box
const maxSize = Math.max( m_size.x, m_size.y, m_size.z) ;
if ( CAMERA_TYPE == CAMERA_ORTHO) {
const aspectRatio = window.innerWidth / window.innerHeight ;
controls.object.left = - aspectRatio * maxSize ;
controls.object.right = aspectRatio * maxSize ;
controls.object.bottom = - maxSize ;
controls.object.top = maxSize ;
controls.object.zoom = 1.5 ; // 1.25 * maxSize
}
// position of the camera
const positionVec = m_box.min.clone().add(( new THREE.Vector3( 0, 0.75, 1)).normalize().multiplyScalar( maxSize)) ;
const targetVec = m_box.min.clone().add( new THREE.Vector3( 0, 0.5 * m_size.y, 0)) ;
controls.object.position.copy( positionVec) ; // this zoom won't change for ortho, it's just for the position
controls.target.copy( targetVec) ;
// updating projection matrix
controls.object.updateProjectionMatrix() ;
controls.update() ;
}
function setGrid() {
// getting maximum size over X and Z
const gridHalf_edge = 1.25 * Math.max( m_size.x, m_size.z) ;
// defining step
const step = gridHalf_edge / 5 ;
// creating grid Group
const gridGroup = new THREE.Group() ;
// creating the grid and adding to the scene
for ( let i = 0 ; i < 11 ; ++ i) {
const x_line = new THREE.Line(
new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3( - gridHalf_edge, 0., - gridHalf_edge + i * step),
new THREE.Vector3(( i != 5 ? gridHalf_edge : 0.), 0., - gridHalf_edge + i * step)
]),
new THREE.LineBasicMaterial({ color : ( i != 5 ? GRID_SECOND_COLOR : GRID_MAIN_COLOR)})
) ;
gridGroup.add( x_line) ;
const y_line = new THREE.Line(
new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3( - gridHalf_edge + i * step , 0., - gridHalf_edge),
new THREE.Vector3( - gridHalf_edge + i * step, 0., ( i != 5 ? gridHalf_edge : 0.))
]),
new THREE.LineBasicMaterial({ color : ( i != 5 ? GRID_SECOND_COLOR : GRID_MAIN_COLOR)})
) ;
gridGroup.add( y_line) ;
}
// adding the group to the scene
gridGroup.name = GRID_GROUP_NAME ;
scene.add( gridGroup) ;
}
function setFrame() {
// getting maximum size over X and Z
const maxSize = 1.25 * Math.max( m_size.x, m_size.z) ;
// x_axis
const x_axis = new THREE.Line(
new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3( 0., 0., 0.),
new THREE.Vector3( maxSize, 0., 0.)
]),
new THREE.LineBasicMaterial({ color : new THREE.Color( 0xff0000)})
) ;
// y_axis
const y_axis = new THREE.Line(
new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3( 0., 0., 0.),
new THREE.Vector3( 0., 0., maxSize)
]),
new THREE.LineBasicMaterial({ color : new THREE.Color( 0x00ff00)})
) ;
// z_axis
const z_axis = new THREE.Line(
new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3( 0., 0., 0.),
new THREE.Vector3( 0., 1., 0.)
]),
new THREE.LineBasicMaterial({ color : new THREE.Color( 0x0000ff)})
) ;
// creating the group of the frame and adding it to the scene
const frameGroup = new THREE.Group() ;
frameGroup.add( x_axis) ;
frameGroup.add( y_axis) ;
frameGroup.add( z_axis) ;
frameGroup.name = FRAME_GROUP_NAME ;
scene.add( frameGroup) ;
}
function ToggleRotation() {
controls.autoRotate = ( ! controls.autoRotate) ;
}
document.addEventListener( "keypress", function( event) {
if ( event.key === "r")
ToggleRotation() ;
else if ( event.key === 'p') {
if ( CAMERA_TYPE == CAMERA_PERSP)
return ;
controls.object = perspCamera.clone() ;
CAMERA_TYPE = CAMERA_PERSP ;
setCameraPosition() ;
}
else if ( event.key === 'o') {
if ( CAMERA_TYPE == CAMERA_ORTHO)
return ;
controls.object = ortoCamera.clone() ;
CAMERA_TYPE = CAMERA_ORTHO ;
setCameraPosition() ;
}
else if ( event.key === 'd')
window.alert( 'manca :(') ;
});
</script>
</body>
</html>