This commit is contained in:
2022-04-28 10:17:01 +08:00
commit 691b3da557
23 changed files with 1254 additions and 0 deletions

173
src/App.vue Normal file
View File

@@ -0,0 +1,173 @@
<script>
import { defineComponent } from 'vue'
import BasicScene from './scene/index'
export default defineComponent({
data() {
return {
camera: {
position: {
x: 0,
y: 0,
z: 10
},
matrix: []
},
model: {
position: {
x: 0,
y: 0,
z: 0
},
matrix: []
}
}
},
methods: {
resetCamera() {
this.effect.camera.position.set(0, 0, 10)
},
resetModel() {},
cameraPos(pos) {
this.effect.camera.position.set(
this.camera.position.x,
this.camera.position.y,
this.camera.position.z
)
this.effect.camera.updateMatrixWorld(true)
this.camera.matrix = []
this.camera.matrix = [...this.effect.camera.matrix.elements]
},
modelPos(pos) {
this.effect.box.position.set(
this.model.position.x,
this.model.position.y,
this.model.position.z
)
this.effect.box.updateMatrixWorld(true)
this.model.matrix = []
this.model.matrix = [...this.effect.box.matrix.elements]
}
},
beforeMount() {
this.effect = new BasicScene()
this.camera.matrix = [...this.effect.camera.matrix.elements]
this.model.matrix = [...this.effect.box.matrix.elements]
}
})
</script>
<template>
<div class="controller">
<el-row>
<el-col :span="6">
<h4>View(Camera)</h4>
<div>
<!-- {{ effect.camera.matrix.elements }} -->
<el-form label-width="120px">
<el-form-item label="Position X">
<el-input-number
:step="1"
size="small"
v-model="camera.position.x"
@change="cameraPos('x')"
/>
</el-form-item>
<el-form-item label="Position Y">
<el-input-number
:step="1"
size="small"
v-model="camera.position.y"
@change="cameraPos('y')"
/>
</el-form-item>
<el-form-item label="Position Z">
<el-input-number
:step="1"
size="small"
v-model="camera.position.z"
@change="cameraPos('z')"
/>
</el-form-item>
</el-form>
<el-button type="primary" size="small" @click="resetCamera"
>重置View(Camera)</el-button
>
</div>
</el-col>
<el-col :span="6">
<h4>Model(Camera)</h4>
<div>
<el-form label-width="120px">
<el-form-item label="Position X">
<el-input-number
:step="1"
size="small"
v-model="model.position.x"
@change="modelPos('x')"
/>
</el-form-item>
<el-form-item label="Position Y">
<el-input-number
:step="1"
size="small"
v-model="model.position.y"
@change="modelPos('y')"
/>
</el-form-item>
<el-form-item label="Position Z">
<el-input-number
:step="1"
size="small"
v-model="model.position.z"
@change="modelPos('z')"
/>
</el-form-item>
</el-form>
<el-button type="primary" size="small" @click="resetModel"
>重置View(Camera)</el-button
>
</div>
</el-col>
<el-col :span="4">
<h4>View(Matrix)</h4>
<div class="grid">
<div v-for="(item, index) in camera.matrix" :key="index">
{{ item }}
</div>
</div>
</el-col>
<el-col :span="4">
<h4>Model(Matrix)</h4>
<div class="grid">
<div v-for="(item, index) in model.matrix" :key="index">
{{ item }}
</div>
</div>
</el-col>
<el-col :span="4">
<h4>ModelView(Matrix)</h4>
</el-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
.controller {
width: 100%;
height: 20vh;
background: #fff;
position: fixed;
bottom: 0;
left: 0;
padding: 35px 32px;
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
div {
font-size: 10px;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
src/assets/ground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

11
src/main.js Normal file
View File

@@ -0,0 +1,11 @@
import {
createApp
} from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'normalize.css';
let app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

122
src/scene/index.js Normal file
View File

@@ -0,0 +1,122 @@
import * as THREE from 'three';
import {
REVISION
} from 'three';
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls'
import Stats from 'stats.js'
import {
Pane
} from 'tweakpane'
let debug = true;
export default class Sketch {
constructor() {
if (debug) console.log("Three Version: ", REVISION);
// 初始化
this.initParam();
this.init();
// 调试
// this.initAxesHelp();
this.initGridHelp();
this.initController();
this.render();
this.loop();
// Main
this.generateCircular();
}
/// 对象
generateCircular() {
let box = new THREE.BoxGeometry(1, 1, 1);
let material = new THREE.MeshBasicMaterial({
color: 'blue',
});
let mesh = new THREE.Mesh(box, material);
this.box = mesh;
this.scene.add(this.box);
var mat4 = new THREE.Matrix4()
// 默认值单位矩阵
// 1, 0, 0, 0,
// 0, 1, 0, 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1
console.log('查看矩阵对象默认值', mat4.elements);
/// set()方法
/// 重置矩阵的元素值,执行.set()方法本质上改变的就是矩阵elements属性值
mat4.set(
1, 0, 0, 5,
0, 1, 0, 3,
0, 0, 1, 9,
0, 0, 0, 1
)
mat4.transpose();
console.log('查看mat4的转置矩阵', mat4.elements);
}
loop() {
const Delta = this.clock.getDelta();
this.index = window.requestAnimationFrame(this.loop.bind(this));
this.render();
}
initParam() {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.aspect = this.width / this.height;
this.clock = new THREE.Clock();
}
init() {
const {
innerWidth,
innerHeight
} = window;
this.aspect = innerWidth / innerHeight;
// 场景
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color('#eeeeee');
// 摄像机
this.camera = new THREE.PerspectiveCamera(75, this.aspect, 0.1, 1000);
this.camera.position.set(0, 0, 10);
this.camera.lookAt(0, 0, 0);
// 渲染
this.aspect = innerWidth / innerHeight;
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
});
this.renderer.setSize(innerWidth, innerHeight);
this.renderer.render(this.scene, this.camera);
this.renderer.setPixelRatio = window.Pixi
document.body.appendChild(this.renderer.domElement);
}
initAxesHelp() {
this.axesHelper = new THREE.AxesHelper(100);
this.scene.add(this.axesHelper);
}
initGridHelp() {
this.gridHelper = new THREE.GridHelper(300, 300);
this.gridHelper.position.y = -0.5;
this.gridHelper.position.x = -0.5;
this.gridHelper.position.z = -0.5;
this.scene.add(this.gridHelper);
}
initController() {
const that = this;
this.controller = new OrbitControls(this.camera, this.renderer.domElement);
this.controller.addEventListener('change', function () {
that.renderer.render(that.scene, that.camera);
})
}
render() {
this.renderer.render(this.scene, this.camera);
}
}

3
src/style/variables.scss Normal file
View File

@@ -0,0 +1,3 @@
body {
background-color: red;
}

4
src/utils/index.js Normal file
View File

@@ -0,0 +1,4 @@
// 两个数字之间随机数
function rand(min, max) {
return Math.random() * (max - min + 1) + min
}