“0feae533ddebe02cda6ccce5cac7349b446776a8”上不存在“include/linux/amd-iommu.h”
提交 45b0241f 编写于 作者: S skyun

Auto Commit

上级 e8ea12b9
import { onMounted } from 'vue'
import { ref, reactive, toRef, watch, onMounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import * as TT from './threejs-tools'
export default class ThreejsManager {
constructor(container) {
// init scene camera
constructor() {
this.animateFuncs = {}
this.lights = reactive([])
}
addScene() {
this.scene = new THREE.Scene()
// init renderer
}
addRenderer() {
this.renderer = new THREE.WebGLRenderer()
this.animateFuncs = {}
const animate = () => {
requestAnimationFrame(animate)
Object.values(this.animateFuncs).forEach(animFunc => animFunc())
this.renderer.render(this.scene, this.camera)
}
startRender(container) {
this.renderer.rendering = true
container.value.appendChild(this.renderer.domElement)
this.renderer.setSize(container.value.clientWidth, container.value.clientHeight)
this.camera = new THREE.PerspectiveCamera(60, container.value.clientWidth / container.value.clientHeight, 0.1, 1000)
this.camera.position.set(0, 10, 10)
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.animate()
}
animate() {
if (!this.renderer.rendering) {
return
}
onMounted(() => {
container.value.appendChild(this.renderer.domElement)
this.renderer.setSize(container.value.clientWidth, container.value.clientHeight)
this.camera = new THREE.PerspectiveCamera(60, container.value.clientWidth / container.value.clientHeight, 0.1, 1000)
this.camera.position.set(0, 10, 10)
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
animate()
})
this.initDefaultScene()
requestAnimationFrame(this.animate.bind(this))
Object.values(this.animateFuncs).forEach(animFunc => animFunc())
this.renderer.render(this.scene, this.camera)
}
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())
this.addAmbientLight()
}
onAnimate(name, animFunc) {
this.animateFuncs[name] = animFunc
......@@ -61,15 +58,31 @@ export default class ThreejsManager {
return cube
}
addAmbientLight() {
return TT.addLight(this.scene, THREE.AmbientLight, [0xffffff, .1])
const light = TT.createLight(THREE.AmbientLight, [0xffffff, .1])
this.scene.add(light)
this.lights.push(light)
light.name = light.type + `-` + this.lights.length
return light
}
addDirectLight() {
return TT.addLight(this.scene, THREE.DirectionalLight, [0xff0000, 1], [-4, 5, -3])
const light = TT.createLight(THREE.DirectionalLight, [0xff0000, 1], [-4, 5, -3])
this.scene.add(light)
this.lights.push(light)
light.name = light.type + `-` + this.lights.length
return light
}
addPointLight() {
return TT.addLight(this.scene, THREE.PointLight, [0x00ff00, 50], [3, 3, -2], .5)
const light = TT.createLight(THREE.PointLight, [0x00ff00, 50, 10], [3, 3, -2])
this.scene.add(light)
this.lights.push(light)
light.name = light.type + `-` + this.lights.length
return light
}
addSpotLight() {
return TT.addLight(this.scene, THREE.SpotLight, [0x0000ff, 1000, 7, .2, .5], [-1, 6, 1])
const light = TT.createLight(THREE.SpotLight, [0x0000ff, 1000, 7, .2, .5], [-1, 6, 1])
this.scene.add(light)
this.lights.push(light)
light.name = light.type + `-` + this.lights.length
return light
}
}
......@@ -20,25 +20,22 @@ export function createCube() {
return cube
}
export function createLight(lightConstuctor, lightArgs = [0xffffff, 1], lightPos = [0, 0, 1], ...helperArgs) {
export function createLight(lightConstuctor, lightArgs = [0xffffff, 1], lightPos = [0, 0, 1]) {
const light = new lightConstuctor(...lightArgs)
light.position.set(...lightPos)
return light
}
export function createLightHelper(light, ...helperArgs) {
let helperType
if (lightConstuctor === THREE.AmbientLight) {
} else if (lightConstuctor === THREE.DirectionalLight) {
if (light.type === 'AmbientLight') {
} else if (light.type === 'DirectionalLight') {
helperType = THREE.DirectionalLightHelper
} else if (lightConstuctor === THREE.PointLight) {
} else if (light.type === 'PointLight') {
helperType = THREE.PointLightHelper
} else if (lightConstuctor === THREE.SpotLight) {
} else if (light.type === 'SpotLight') {
helperType = THREE.SpotLightHelper
}
const helper = helperType && new helperType(light, ...helperArgs) || {light, isMockHelper: true}
const helper = !!helperType && new helperType(light, ...helperArgs) || null
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 lights" class="light-option flex-col flex-align-start">
<Checkbox :label="l.name" v-model="l.visible">{{l.type}}</Checkbox>
<h2>灯光选项</h2>
<div v-for="l in props.lights" class="light-option flex-col flex-align-start">
<Checkbox class="check-box"
:label="l.name"
size="small"
@on-change="refresh"
v-model="l.visible">{{l.name}}</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>
<span class="lable">位置</span>
<Input size="small"
@on-keydown="onPositionKeyPress($event, l)"
style="width: 50px;" />
</div>
<div class="match-width flex-row">
<span class="lable">光照强度: {{l.intensity}}</span>
<Slider class="flex-1"
@on-change="saveOptions"
:step=l._intensity*.01
:max=l._intensity*10
v-model="l.intensity" />
</div>
<template v-if="['PointLight', 'SpotLight'].includes(l.type)">
<div class="match-width flex-row">
<span class="lable">照射距离: {{l.distance}}</span>
<Slider class="flex-1"
@on-input="refresh"
@on-change="saveOptions"
:step=l._distance*.01
:max=l._distance*3
v-model="l.distance" />
</div>
<div class="match-width flex-row">
<span class="lable">距离衰减: {{l.decay}}</span>
<Slider class="flex-1"
@on-input="refresh"
@on-change="saveOptions"
:step=0.1
:max=10
v-model="l.decay" />
</div>
</template>
<template v-if="['SpotLight'].includes(l.type)">
<div class="match-width flex-row">
<span class="lable">散射角度: {{(l.angle * 180 / Math.PI).toFixed(0)}}</span>
<Slider class="flex-1"
@on-input="refresh"
@on-change="saveOptions"
:step=0.01
:max=Math.PI/2
v-model="l.angle" />
</div>
<div class="match-width flex-row">
<span class="lable">散射衰减: {{l.penumbra}}</span>
<Slider class="flex-1"
@on-input="refresh"
@on-change="saveOptions"
:step=0.01
:max=1
v-model="l.penumbra" />
</div>
</template>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRef, watch, onMounted, defineProps } from 'vue'
import { ref, shallowRef, reactive, toRef, toRefs, watch, onMounted, defineProps } from 'vue'
import * as TT from '../threejs-utils/threejs-tools'
function onPositionKeyPress(ev, light) {
console.log(ev.type, ev.key, ev.altKey)
const step = .5
if (ev.altKey && ev.key === `ArrowUp`) {
light.position.z -= step
} else if (ev.altKey && ev.key === `ArrowDown`) {
light.position.z += step
} else if (ev.key === `ArrowLeft`) {
light.position.x -= step
} else if (ev.key === `ArrowRight`) {
light.position.x += step
} else if (ev.key === `ArrowUp`) {
light.position.y -= step
} else if (ev.key === `ArrowDown`) {
light.position.y += step
} else if (ev.key === `ArrowRight`) {
}
}
const props = defineProps({
lights:{
type: Array,
},
})
props.lights.forEach(l => {
l._intensity = l.intensity
scene: { type: Object },
lights: { type: Array },
})
const lights = reactive(props.lights)
// helper逻辑
let helpers = []
watch(toRef(props.lights, `length`), (newVal, oldVal) => {
props.lights.forEach(l => {
l._intensity = l.intensity
l._distance = l.distance
})
helpers.forEach(h => {
h.dispose()
props.scene.remove(h)
})
helpers = props.lights
.filter(light => light.type !== `AmbientLight`)
.map(light => TT.createLightHelper(light))
helpers.forEach(helper => {
props.scene.add(helper)
})
}, {immediate: true, deep: false})
function refresh() {
helpers.forEach(helper => {
helper.visible = helper.light.visible
helper.update()
})
}
// load/save options
function loadOptions() {
const options = JSON.parse(localStorage.getItem(`light-options`))
options.forEach((opt, i) => {
Object.keys(opt).forEach(key => {
props.lights[i][key] = opt[key]
})
})
}
function saveOptions() {
const options = props.lights.map(l => {
return [`visible`, `intensity`, `distance`, `decay`, `angle`, `penumbra`].reduce((res, attr) => {
res[attr] = l[attr]
return res
}, {})
})
localStorage.setItem(`light-options`, JSON.stringify(options))
}
</script>
<style scoped>
.options {
width: 100%;
height: 100%;
padding: 40px 20px;
padding: 10px;
align-items: flex-start;
overflow-y: scroll;
}
.light-option {
width: 100%;
margin-top: 20px;
display: flex;
}
.check-box {
width: 100%;
margin: 8px 0;
padding: 2px 5px;
background: #223;
}
.lable {
width: 120px;
margin-left: 10px;
}
</style>
\ No newline at end of file
<template>
<div id="root" class="flex-row">
<LightOption class="options" :lights="tm.lightHelpers.map(helper => helper.light)" />
<LightOption class="options" :scene="tm.scene" :lights="tm.lights" />
<div id="container" ref="container"></div>
{{tm.lightHelpers[1].light.intensity}}
</div>
</template>
......@@ -14,6 +13,17 @@ import LightOption from './light-option.vue'
const container = ref(null)
const tm = new ThreeManager(container)
tm.addScene()
tm.addRenderer()
onMounted(() => {
tm.startRender(container)
})
tm.initDefaultScene()
tm.addDirectLight()
tm.addPointLight()
tm.addSpotLight()
</script>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册