mirror of
https://github.com/troisjs/trois.git
synced 2024-11-24 04:12:02 +08:00
init
This commit is contained in:
commit
a21071af6a
40
.eslintrc.js
Normal file
40
.eslintrc.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* eslint-disable quote-props */
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2020: true,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/essential',
|
||||||
|
'standard',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 12,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
'vue',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'semi': [2, 'always'],
|
||||||
|
'space-before-function-paren': 'off',
|
||||||
|
'one-var': 'off',
|
||||||
|
'quotes': 'off',
|
||||||
|
'quote-props': 'off',
|
||||||
|
'object-curly-newline': 'off',
|
||||||
|
'no-unused-vars': 'warn',
|
||||||
|
// 'comma-dangle': ['warn', 'always-multiline'],
|
||||||
|
'comma-dangle': ['warn', {
|
||||||
|
'arrays': 'always-multiline',
|
||||||
|
'objects': 'always-multiline',
|
||||||
|
'imports': 'always-multiline',
|
||||||
|
'exports': 'always-multiline',
|
||||||
|
'functions': 'never',
|
||||||
|
}],
|
||||||
|
'indent': 'warn',
|
||||||
|
'no-new': 'off',
|
||||||
|
'object-property-newline': 'off',
|
||||||
|
'eqeqeq': 'warn',
|
||||||
|
'no-multiple-empty-lines': 'off',
|
||||||
|
},
|
||||||
|
};
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
*.local
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
25
package.json
Normal file
25
package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "test-vite",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"three": "^0.119",
|
||||||
|
"vue": "^3.0.0-rc.10",
|
||||||
|
"vuex": "^4.0.0-beta.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/compiler-sfc": "^3.0.0-rc.10",
|
||||||
|
"eslint": "^7.7.0",
|
||||||
|
"eslint-config-airbnb-base": "^14.2.0",
|
||||||
|
"eslint-config-standard": "^14.1.1",
|
||||||
|
"eslint-plugin-import": "^2.22.0",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
|
"eslint-plugin-standard": "^4.0.1",
|
||||||
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
|
"vite": "^1.0.0-rc.1"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
14
src/App.vue
Normal file
14
src/App.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<Test></Test>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Test from './components/Test.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
Test,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
59
src/components/Test.vue
Normal file
59
src/components/Test.vue
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<Renderer ref="renderer" :animate="anim">
|
||||||
|
<PerspectiveCamera :position="{ z: 100 }"></PerspectiveCamera>
|
||||||
|
|
||||||
|
<PhongMaterial name="mat1" color="#ff0000"></PhongMaterial>
|
||||||
|
<LambertMaterial name="mat2" color="#0000ff"></LambertMaterial>
|
||||||
|
|
||||||
|
<Scene>
|
||||||
|
<PointLight :position="{ x: 0, y: 50, z: 50 }"></PointLight>
|
||||||
|
<Box ref="box" :size="10" :rotation="{ x: 0.5, y: 0.25 }" material="mat1"></Box>
|
||||||
|
<Sphere ref="sphere" :radius="10" :position="{ x: 50 }" material="mat2"></Sphere>
|
||||||
|
</Scene>
|
||||||
|
</Renderer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Renderer, PerspectiveCamera, Scene,
|
||||||
|
PointLight,
|
||||||
|
Box, Sphere,
|
||||||
|
LambertMaterial, PhongMaterial,
|
||||||
|
} from '../index.js';
|
||||||
|
|
||||||
|
import { useAnimate } from '../core/Renderer.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Renderer, PerspectiveCamera, Scene,
|
||||||
|
PointLight,
|
||||||
|
Box, Sphere,
|
||||||
|
LambertMaterial, PhongMaterial,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
anim: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('Test mounted');
|
||||||
|
// useAnimate(() => {
|
||||||
|
// this.$refs.box.mesh.rotation.x += 0.01;
|
||||||
|
// });
|
||||||
|
// useAnimate(this.animate);
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
console.log('Test beforeUnmount');
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
animate() {
|
||||||
|
this.$refs.box.mesh.rotation.x += 0.01;
|
||||||
|
// if (this.$refs.box) {
|
||||||
|
// this.$refs.box.mesh.rotation.x += 0.01;
|
||||||
|
// this.$refs.box.mesh.rotation.y += 0.013;
|
||||||
|
// this.$refs.box.mesh.rotation.z += 0.007;
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
26
src/core/PerspectiveCamera.js
Normal file
26
src/core/PerspectiveCamera.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { PerspectiveCamera, Vector3 } from 'three';
|
||||||
|
|
||||||
|
import { setFromProp } from '../tools.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['three'],
|
||||||
|
props: {
|
||||||
|
fov: {
|
||||||
|
type: Number,
|
||||||
|
default: 50,
|
||||||
|
},
|
||||||
|
position: Object,
|
||||||
|
// position: {
|
||||||
|
// type: Object,
|
||||||
|
// default: new Vector3(),
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const camera = new PerspectiveCamera(this.fov);
|
||||||
|
setFromProp(camera.position, this.position);
|
||||||
|
this.three.camera = camera;
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
70
src/core/Renderer.vue
Normal file
70
src/core/Renderer.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<canvas ref="canvas">
|
||||||
|
<slot></slot>
|
||||||
|
</canvas>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import useThree from './useThree';
|
||||||
|
|
||||||
|
const animateCallbacks = [];
|
||||||
|
|
||||||
|
export function useAnimate(callback) {
|
||||||
|
animateCallbacks.push(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
alpha: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
type: Function,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
raf: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return {
|
||||||
|
three: useThree(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
provide() {
|
||||||
|
return {
|
||||||
|
three: this.three,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// console.log('Renderer mounted');
|
||||||
|
this.three.init({
|
||||||
|
canvas: this.$refs.canvas,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._animate();
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
// console.log('Renderer beforeUnmount');
|
||||||
|
// animateCallbacks.splice(0);
|
||||||
|
this.raf = false;
|
||||||
|
this.three.dispose();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_animate() {
|
||||||
|
if (this.raf) requestAnimationFrame(this._animate);
|
||||||
|
// if (this.animate) this.animate();
|
||||||
|
animateCallbacks.forEach(c => c());
|
||||||
|
if (this.three.scene) this.three.render(this.three.scene);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
22
src/core/Scene.js
Normal file
22
src/core/Scene.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Scene } from 'three';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
emits: ['scene-ready'],
|
||||||
|
inject: ['three'],
|
||||||
|
setup (props) {
|
||||||
|
const scene = new Scene();
|
||||||
|
return { scene };
|
||||||
|
},
|
||||||
|
provide() {
|
||||||
|
return {
|
||||||
|
scene: this.scene,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.three.scene = this.scene;
|
||||||
|
this.$emit('scene-ready');
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return this.$slots.default();
|
||||||
|
},
|
||||||
|
};
|
3
src/core/index.js
Normal file
3
src/core/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export { default as Renderer } from './Renderer.vue';
|
||||||
|
export { default as PerspectiveCamera } from './PerspectiveCamera.js';
|
||||||
|
export { default as Scene } from './Scene.js';
|
175
src/core/useThree.js
Normal file
175
src/core/useThree.js
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import {
|
||||||
|
PerspectiveCamera,
|
||||||
|
Plane,
|
||||||
|
Raycaster,
|
||||||
|
Vector2,
|
||||||
|
Vector3,
|
||||||
|
WebGLRenderer,
|
||||||
|
} from 'three';
|
||||||
|
|
||||||
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Three.js helper
|
||||||
|
*/
|
||||||
|
export default function useThree() {
|
||||||
|
// default conf
|
||||||
|
const conf = {
|
||||||
|
canvas: null,
|
||||||
|
antialias: true,
|
||||||
|
alpha: false,
|
||||||
|
camera_fov: 50,
|
||||||
|
camera_pos: new Vector3(0, 0, 100),
|
||||||
|
camera_ctrl: false,
|
||||||
|
mouse_move: false,
|
||||||
|
mouse_raycast: false,
|
||||||
|
window_resize: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// size
|
||||||
|
const size = {
|
||||||
|
width: 0, height: 0,
|
||||||
|
wWidth: 0, wHeight: 0,
|
||||||
|
ratio: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// mouse tracking
|
||||||
|
const mouse = new Vector2();
|
||||||
|
const mouseV3 = new Vector3();
|
||||||
|
const mousePlane = new Plane(new Vector3(0, 0, 1), 0);
|
||||||
|
const raycaster = new Raycaster();
|
||||||
|
|
||||||
|
// returned object
|
||||||
|
const obj = {
|
||||||
|
conf,
|
||||||
|
renderer: null,
|
||||||
|
camera: null,
|
||||||
|
cameraCtrl: null,
|
||||||
|
materials: {},
|
||||||
|
size,
|
||||||
|
mouse, mouseV3,
|
||||||
|
init,
|
||||||
|
dispose,
|
||||||
|
render,
|
||||||
|
setSize,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init three
|
||||||
|
*/
|
||||||
|
function init(params) {
|
||||||
|
if (params) {
|
||||||
|
for (const [key, value] of Object.entries(params)) {
|
||||||
|
conf[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha });
|
||||||
|
|
||||||
|
// obj.camera = new PerspectiveCamera(conf.camera_fov);
|
||||||
|
// obj.camera.position.copy(conf.camera_pos);
|
||||||
|
|
||||||
|
// if (conf.camera_ctrl) {
|
||||||
|
// obj.cameraCtrl = new OrbitControls(obj.camera, obj.renderer.domElement);
|
||||||
|
// if (conf.camera_ctrl instanceof Object) {
|
||||||
|
// for (const [key, value] of Object.entries(conf.camera_ctrl)) {
|
||||||
|
// obj.cameraCtrl[key] = value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (conf.window_resize) {
|
||||||
|
onResize();
|
||||||
|
window.addEventListener('resize', onResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf.mouse_move) {
|
||||||
|
obj.renderer.domElement.addEventListener('mousemove', onMousemove);
|
||||||
|
obj.renderer.domElement.addEventListener('mouseleave', onMouseleave);
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default render
|
||||||
|
*/
|
||||||
|
function render(scene) {
|
||||||
|
if (obj.cameraCtrl) obj.cameraCtrl.update();
|
||||||
|
obj.renderer.render(scene, obj.camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove listeners
|
||||||
|
*/
|
||||||
|
function dispose() {
|
||||||
|
window.removeEventListener('resize', onResize);
|
||||||
|
obj.renderer.domElement.removeEventListener('mousemove', onMousemove);
|
||||||
|
obj.renderer.domElement.removeEventListener('mouseleave', onMouseleave);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mousemove listener
|
||||||
|
*/
|
||||||
|
function onMousemove(e) {
|
||||||
|
mouse.x = (e.clientX / size.width) * 2 - 1;
|
||||||
|
mouse.y = -(e.clientY / size.height) * 2 + 1;
|
||||||
|
updateMouseV3();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mouseleave listener
|
||||||
|
*/
|
||||||
|
function onMouseleave(e) {
|
||||||
|
mouse.x = 0;
|
||||||
|
mouse.y = 0;
|
||||||
|
updateMouseV3();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get 3d mouse position
|
||||||
|
*/
|
||||||
|
function updateMouseV3() {
|
||||||
|
if (conf.mouse_raycast) {
|
||||||
|
obj.camera.getWorldDirection(mousePlane.normal);
|
||||||
|
mousePlane.normal.normalize();
|
||||||
|
raycaster.setFromCamera(mouse, obj.camera);
|
||||||
|
raycaster.ray.intersectPlane(mousePlane, mouseV3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resize listener
|
||||||
|
*/
|
||||||
|
function onResize() {
|
||||||
|
setSize(window.innerWidth, window.innerHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update renderer size and camera
|
||||||
|
*/
|
||||||
|
function setSize(width, height) {
|
||||||
|
size.width = width;
|
||||||
|
size.height = height;
|
||||||
|
size.ratio = width / height;
|
||||||
|
|
||||||
|
obj.renderer.setSize(width, height, false);
|
||||||
|
obj.camera.aspect = size.ratio;
|
||||||
|
obj.camera.updateProjectionMatrix();
|
||||||
|
|
||||||
|
const wsize = getCameraSize();
|
||||||
|
size.wWidth = wsize[0]; size.wHeight = wsize[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate camera visible area size
|
||||||
|
*/
|
||||||
|
function getCameraSize() {
|
||||||
|
const vFOV = (obj.camera.fov * Math.PI) / 180;
|
||||||
|
const h = 2 * Math.tan(vFOV / 2) * Math.abs(obj.camera.position.z);
|
||||||
|
const w = h * obj.camera.aspect;
|
||||||
|
return [w, h];
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
6
src/index.css
Normal file
6
src/index.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
}
|
4
src/index.js
Normal file
4
src/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './core/index.js';
|
||||||
|
export * from './lights/index.js';
|
||||||
|
export * from './materials/index.js';
|
||||||
|
export * from './meshes/index.js';
|
39
src/lights/Light.js
Normal file
39
src/lights/Light.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
Vector3,
|
||||||
|
} from 'three';
|
||||||
|
|
||||||
|
import { setFromProp } from '../tools.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['scene'],
|
||||||
|
props: {
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#ffffff',
|
||||||
|
},
|
||||||
|
intensity: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
distance: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
decay: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
position: Object,
|
||||||
|
// position: {
|
||||||
|
// type: Object,
|
||||||
|
// default: new Vector3(0, 0, 0),
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
setFromProp(this.light.position, this.position);
|
||||||
|
this.scene.add(this.light);
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
9
src/lights/PointLight.js
Normal file
9
src/lights/PointLight.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { PointLight } from 'three';
|
||||||
|
import Light from './Light.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Light,
|
||||||
|
created() {
|
||||||
|
this.light = new PointLight(this.color, this.intensity, this.distance, this.decay);
|
||||||
|
},
|
||||||
|
};
|
1
src/lights/index.js
Normal file
1
src/lights/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as PointLight } from './PointLight.js';
|
6
src/main.js
Normal file
6
src/main.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import App from './App.vue';
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
const app = createApp(App);
|
||||||
|
app.mount('#app');
|
11
src/materials/BasicMaterial.js
Normal file
11
src/materials/BasicMaterial.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MeshBasicMaterial } from 'three';
|
||||||
|
import Material from './Material';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Material,
|
||||||
|
created() {
|
||||||
|
this.material = new MeshBasicMaterial({
|
||||||
|
color: this.color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
11
src/materials/LambertMaterial.js
Normal file
11
src/materials/LambertMaterial.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MeshLambertMaterial } from 'three';
|
||||||
|
import Material from './Material';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Material,
|
||||||
|
created() {
|
||||||
|
this.material = new MeshLambertMaterial({
|
||||||
|
color: this.color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
16
src/materials/Material.js
Normal file
16
src/materials/Material.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export default {
|
||||||
|
inject: ['three'],
|
||||||
|
props: {
|
||||||
|
name: String,
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#ffffff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.three.materials[this.name] = this.material;
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
11
src/materials/PhongMaterial.js
Normal file
11
src/materials/PhongMaterial.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MeshPhongMaterial } from 'three';
|
||||||
|
import Material from './Material';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Material,
|
||||||
|
created() {
|
||||||
|
this.material = new MeshPhongMaterial({
|
||||||
|
color: this.color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
11
src/materials/PhysicalMaterial.js
Normal file
11
src/materials/PhysicalMaterial.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MeshPhysicalMaterial } from 'three';
|
||||||
|
import Material from './Material';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Material,
|
||||||
|
created() {
|
||||||
|
this.material = new MeshPhysicalMaterial({
|
||||||
|
color: this.color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
11
src/materials/StandardMaterial.js
Normal file
11
src/materials/StandardMaterial.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { MeshStandardMaterial } from 'three';
|
||||||
|
import Material from './Material';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Material,
|
||||||
|
created() {
|
||||||
|
this.material = new MeshStandardMaterial({
|
||||||
|
color: this.color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
5
src/materials/index.js
Normal file
5
src/materials/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export { default as BasicMaterial } from './BasicMaterial.js';
|
||||||
|
export { default as LambertMaterial } from './LambertMaterial.js';
|
||||||
|
export { default as PhongMaterial } from './PhongMaterial.js';
|
||||||
|
export { default as PhysicalMaterial } from './PhysicalMaterial.js';
|
||||||
|
export { default as StandardMaterial } from './StandardMaterial.js';
|
33
src/meshes/Box.js
Normal file
33
src/meshes/Box.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {
|
||||||
|
BoxBufferGeometry,
|
||||||
|
} from 'three';
|
||||||
|
|
||||||
|
import Mesh from './Mesh.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Mesh,
|
||||||
|
props: {
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
depth: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.size) {
|
||||||
|
this.geometry = new BoxBufferGeometry(this.size, this.size, this.size);
|
||||||
|
} else {
|
||||||
|
this.geometry = new BoxBufferGeometry(this.width, this.height, this.depth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
34
src/meshes/Mesh.js
Normal file
34
src/meshes/Mesh.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Mesh } from 'three';
|
||||||
|
import { setFromProp } from '../tools.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['three', 'scene'],
|
||||||
|
props: {
|
||||||
|
material: String,
|
||||||
|
position: Object,
|
||||||
|
rotation: Object,
|
||||||
|
scale: Object,
|
||||||
|
// position: {
|
||||||
|
// type: Object,
|
||||||
|
// default: new Vector3(),
|
||||||
|
// },
|
||||||
|
// rotation: {
|
||||||
|
// type: Object,
|
||||||
|
// default: new Euler(),
|
||||||
|
// },
|
||||||
|
// scale: {
|
||||||
|
// type: Object,
|
||||||
|
// default: new Vector3(1, 1, 1),
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.mesh = new Mesh(this.geometry, this.three.materials[this.material]);
|
||||||
|
setFromProp(this.mesh.position, this.position);
|
||||||
|
setFromProp(this.mesh.rotation, this.rotation);
|
||||||
|
setFromProp(this.mesh.scale, this.scale);
|
||||||
|
this.scene.add(this.mesh);
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
15
src/meshes/Sphere.js
Normal file
15
src/meshes/Sphere.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {
|
||||||
|
SphereBufferGeometry,
|
||||||
|
} from 'three';
|
||||||
|
|
||||||
|
import Mesh from './Mesh.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Mesh,
|
||||||
|
props: {
|
||||||
|
radius: Number,
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.geometry = new SphereBufferGeometry(this.radius, 32, 32);
|
||||||
|
},
|
||||||
|
};
|
2
src/meshes/index.js
Normal file
2
src/meshes/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { default as Box } from './Box.js';
|
||||||
|
export { default as Sphere } from './Sphere.js';
|
7
src/tools.js
Normal file
7
src/tools.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function setFromProp(o, prop) {
|
||||||
|
if (prop instanceof Object) {
|
||||||
|
for (const [key, value] of Object.entries(prop)) {
|
||||||
|
o[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user