提交 58ece2d4 编写于 作者: S skyun

Thu Oct 19 08:13:00 CST 2023 inscode

上级 f4092830
<script setup> <script setup>
import Basic from './views/basic.vue' import Lights from './views/lights.vue'
</script> </script>
<template> <template>
<Basic /> <Lights />
</template> </template>
<style scoped> <style scoped>
......
...@@ -8,6 +8,8 @@ body { ...@@ -8,6 +8,8 @@ body {
place-items: center; place-items: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #000;
color: #fff;
} }
#app { #app {
margin: 0 auto; margin: 0 auto;
...@@ -58,6 +60,15 @@ a, ...@@ -58,6 +60,15 @@ a,
.flex-1 { .flex-1 {
flex: 1; flex: 1;
} }
.flex-align-start {
align-items: flex-start;
}
.match-width {
width: 100%;
}
.mr10px {
margin-right: 10px;
}
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; display: none;
......
import { ref, onMounted } from 'vue' import { onMounted } from 'vue'
import * as THREE from 'three' import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
export class ThreejsDefault { import * as TT from './threejs-tools'
export default class ThreejsManager {
constructor(container) { constructor(container) {
// init scene camera // init scene camera
this.scene = new THREE.Scene() this.scene = new THREE.Scene()
this.scene.add(new THREE.GridHelper(100, 100, 0x660000, 0x004400))
// init renderer // init renderer
this.renderer = new THREE.WebGLRenderer() this.renderer = new THREE.WebGLRenderer()
this.animateFuncs = {}
this.animateFuncs = []
const animate = () => { const animate = () => {
requestAnimationFrame(animate) requestAnimationFrame(animate)
this.animateFuncs.forEach(animFunc => animFunc()) Object.values(this.animateFuncs).forEach(animFunc => animFunc())
this.renderer.render(this.scene, this.camera) this.renderer.render(this.scene, this.camera)
} }
...@@ -29,23 +29,47 @@ export class ThreejsDefault { ...@@ -29,23 +29,47 @@ export class ThreejsDefault {
animate() animate()
}) })
}
this.initDefaultScene()
onAnimate(animFunc) { }
this.animateFuncs.push(animFunc) initDefaultScene() {
this.scene.add(new THREE.GridHelper(100, 100, 0x660000, 0x004400))
this.addPlane()
this.addCube()
this.lightHelpers = []
this.lightHelpers.push(this.addAmbientLight())
this.lightHelpers.push(this.addDirectLight())
this.lightHelpers.push(this.addPointLight())
this.lightHelpers.push(this.addSpotLight())
}
onAnimate(name, animFunc) {
this.animateFuncs[name] = animFunc
}
addPlane() {
const plane = TT.createPlane()
this.scene.add(plane)
return plane
}
addCube() {
const cube = TT.createCube()
cube.position.y = 1
this.onAnimate('cube', () => {
cube.rotation.x += 0.01
cube.rotation.y += 0.01
})
this.scene.add(cube)
return cube
}
addAmbientLight() {
return TT.addLight(this.scene, THREE.AmbientLight, [0xffffff, .1])
}
addDirectLight() {
return TT.addLight(this.scene, THREE.DirectionalLight, [0xff0000, 1], [-4, 5, -3])
}
addPointLight() {
return TT.addLight(this.scene, THREE.PointLight, [0x00ff00, 50], [3, 3, -2], .5)
}
addSpotLight() {
return TT.addLight(this.scene, THREE.SpotLight, [0x0000ff, 1000, 7, .2, .5], [-1, 6, 1])
} }
}
export function createPlane(w = 10, h = 10, position = [0, .1, 0], rotation = [90, 0, 0]) {
const material = new THREE.MeshLambertMaterial({
color: 0x88888888,
side: THREE.DoubleSide,
// wireframe: true,
})
const geometry = new THREE.PlaneGeometry(w, h)
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(...position)
mesh.rotation.set(...rotation.map(deg => deg / 180 * Math.PI))
return mesh
} }
import * as THREE from 'three'
export function createPlane(w = 10, h = 10, position = [0, .1, 0], rotation = [90, 0, 0]) {
const material = new THREE.MeshLambertMaterial({
color: 0x88888888,
side: THREE.DoubleSide,
// wireframe: true,
})
const geometry = new THREE.PlaneGeometry(w, h)
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(...position)
mesh.rotation.set(...rotation.map(deg => deg / 180 * Math.PI))
return mesh
}
export function createCube() {
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshLambertMaterial({ color: 0xffffff })
const cube = new THREE.Mesh(geometry, material)
return cube
}
export function createLight(lightConstuctor, lightArgs = [0xffffff, 1], lightPos = [0, 0, 1], ...helperArgs) {
const light = new lightConstuctor(...lightArgs)
light.position.set(...lightPos)
let helperType
if (lightConstuctor === THREE.AmbientLight) {
} else if (lightConstuctor === THREE.DirectionalLight) {
helperType = THREE.DirectionalLightHelper
} else if (lightConstuctor === THREE.PointLight) {
helperType = THREE.PointLightHelper
} else if (lightConstuctor === THREE.SpotLight) {
helperType = THREE.SpotLightHelper
}
const helper = helperType && new helperType(light, ...helperArgs) || {light, isMockHelper: true}
return helper
}
export function addLight(scene, ...createArgs) {
const helper = createLight(...createArgs)
scene.add(helper.light)
helper.isMockHelper || scene.add(helper)
return helper
}
\ No newline at end of file
<template>
<div class="options">
<h1>Light Options {{test}}</h1>
<div v-for="l in props.lights" class="light-option flex-col flex-align-start">
<Checkbox :label="l.name" v-model="l.visible">{{l.type}}</Checkbox>
<div class="match-width flex-row">
<label class="mr10px">强度</label>
<Slider class="flex-1" v-model="l.intensity" :step=l._intensity*.01 :max=l._intensity*10></Slider>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRef, watch, onMounted, defineProps } from 'vue'
const props = defineProps({
lights:{
type: Array,
},
})
props.lights.forEach(l => {
l._intensity = l.intensity
})
const test = reactive(1)
</script>
<style scoped>
.options {
width: 100%;
height: 100%;
padding: 40px 20px;
align-items: flex-start;
}
.light-option {
width: 100%;
margin-top: 20px;
display: flex;
}
</style>
\ No newline at end of file
<template>
<div id="root" class="flex-row">
<LightOption class="options" :lights="lights" />
<div id="container" ref="container"></div>
</div>
</template>
<script setup>
import { ref, reactive, toRef, watch, onMounted } from 'vue'
import * as THREE from 'three'
import ThreeManager from '../threejs-utils/threejs-manager'
import LightOption from './light-option.vue'
const container = ref(null)
const tm = new ThreeManager(container)
const lights = reactive(tm.lightHelpers.map(helper => helper.light))
</script>
<style scoped>
#root {
width: 100%;
height: 100%;
align-items: flex-start;
}
.options {
flex: 1;
}
#container {
flex: 2;
width: 100%;
height: 100%;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册