parent
fdaef58223
commit
bffde87473
@ -0,0 +1,117 @@
|
|||||||
|
## [1.4.1](https://github.com/hujiulong/vue-3d-model/compare/v1.4.0...v1.4.1) (2022-08-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix order of calculations ([f58bf72](https://github.com/hujiulong/vue-3d-model/commit/f58bf72be93c7c088c73e64919deaea3f20301a1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.4.0](https://github.com/hujiulong/vue-3d-model/compare/v1.3.1...v1.4.0) (2021-06-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **demo:** fix json loader demo ([3236bc2](https://github.com/hujiulong/vue-3d-model/commit/3236bc2c990905f812835a81f1c96c318d06a3d5))
|
||||||
|
* remove calls to removed methods ([ff01a19](https://github.com/hujiulong/vue-3d-model/commit/ff01a19d8715d0b44b9cb98ae4e51e070ad44915))
|
||||||
|
* the default props should return a new object ([e5cf0e1](https://github.com/hujiulong/vue-3d-model/commit/e5cf0e106c3cb95738c7201ee322b41a28d824a6))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* loaders should use setRequestHeader ([#267](https://github.com/hujiulong/vue-3d-model/issues/267)) ([40b077a](https://github.com/hujiulong/vue-3d-model/commit/40b077a3513f0830d1ba28a3c653b401b7ac97b2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.1](https://github.com/hujiulong/vue-3d-model/compare/v1.3.0...v1.3.1) (2020-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.3.0](https://github.com/hujiulong/vue-3d-model/compare/v1.2.0...v1.3.0) (2020-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix controlsOptions ([be18b78](https://github.com/hujiulong/vue-3d-model/commit/be18b783eee5fca2fceacc42ec002a80478f50e0))
|
||||||
|
* publicPath ([b69a2c7](https://github.com/hujiulong/vue-3d-model/commit/b69a2c7a6146c43849640926a97dbf11f65b75cb))
|
||||||
|
* resolve gammaOutput removed warning and update the README.md ([#172](https://github.com/hujiulong/vue-3d-model/issues/172)) ([f4ab34b](https://github.com/hujiulong/vue-3d-model/commit/f4ab34bc7663be40be122def73c7dcbed636eeb8))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* model-fbx and update three.js ([#167](https://github.com/hujiulong/vue-3d-model/issues/167)) ([c700a0f](https://github.com/hujiulong/vue-3d-model/commit/c700a0f9181ef5f1bb8f474cbf59c079a41e2b33))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.2.0](https://github.com/hujiulong/vue-3d-model/compare/v1.1.0...v1.2.0) (2019-10-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* dispose objects before component destroy ([02adf5b](https://github.com/hujiulong/vue-3d-model/commit/02adf5bc53f9911daa46c8dc0daa0aa3a61e396a))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add a new prop: glOptions. closes [#111](https://github.com/hujiulong/vue-3d-model/issues/111) ([7d3448e](https://github.com/hujiulong/vue-3d-model/commit/7d3448eee51ebbf603c859ba62bc28efd9f4ec89))
|
||||||
|
* allow override OrbitControls Properties ([#123](https://github.com/hujiulong/vue-3d-model/issues/123)) ([55e29f6](https://github.com/hujiulong/vue-3d-model/commit/55e29f678b7278bd36ae52b67c028182931b871a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.1.0-alpha.0](https://github.com/hujiulong/vue-3d-model/compare/v1.0.2...1.1.0-alpha.0) (2019-06-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix camera options ([#67](https://github.com/hujiulong/vue-3d-model/issues/67)) ([f5a0fe5](https://github.com/hujiulong/vue-3d-model/commit/f5a0fe5fea94774437c215a47008157637edc43e))
|
||||||
|
* fix props check ([693295b](https://github.com/hujiulong/vue-3d-model/commit/693295b764bd780732f420ad7e2d19881ceef8f1))
|
||||||
|
* updated background example ([#68](https://github.com/hujiulong/vue-3d-model/issues/68)) ([3760535](https://github.com/hujiulong/vue-3d-model/commit/3760535879ea71dbf92e647bd393d27e2b133d38))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **gltf:** set the default value of gammaOutput to true ([e609c91](https://github.com/hujiulong/vue-3d-model/commit/e609c9145a95c425a4de1ba6e2d866881b7ecb73))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.0.2](https://github.com/hujiulong/vue-3d-model/compare/v1.0.1...v1.0.2) (2018-08-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix the config of dev(close [#43](https://github.com/hujiulong/vue-3d-model/issues/43)) ([e0468c0](https://github.com/hujiulong/vue-3d-model/commit/e0468c0736a2db001e4a1c4a8747ed0c3bad4a32))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add crossOrigin option(fix [#33](https://github.com/hujiulong/vue-3d-model/issues/33)) ([1c815de](https://github.com/hujiulong/vue-3d-model/commit/1c815de53fea93f5e787c7c8ed3eb58ef610b164))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.0.1](https://github.com/hujiulong/vue-3d-model/compare/v1.0.0...v1.0.1) (2018-05-01)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.0.0](https://github.com/hujiulong/vue-3d-model/compare/v0.0.15...v1.0.0) (2018-02-08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.0.15](https://github.com/hujiulong/vue-3d-model/compare/3dc003e51745d500d8e7faed945088e70664d029...v0.0.15) (2018-01-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* export `model-ply`.([#22](https://github.com/hujiulong/vue-3d-model/issues/22)) ([945930c](https://github.com/hujiulong/vue-3d-model/commit/945930c427e8a9d7c753e3c326b71a56ec78f07d))
|
||||||
|
* fix `on-error` event and add `on-progress` event([#15](https://github.com/hujiulong/vue-3d-model/issues/15)). ([0a92d7b](https://github.com/hujiulong/vue-3d-model/commit/0a92d7b160bdf495dbda47385e83e688874e14a0))
|
||||||
|
* fix `PointLight` not imported in `vue-mixin`([#16](https://github.com/hujiulong/vue-3d-model/issues/16)). ([01427f6](https://github.com/hujiulong/vue-3d-model/commit/01427f6c90159e0e87939e454831b96e0a81347a))
|
||||||
|
* fix rotate example ([5b5535e](https://github.com/hujiulong/vue-3d-model/commit/5b5535e43f8e3b07a43ff90aa7a7a30a064e937d))
|
||||||
|
* update OBJLoader to fix som bugs([#19](https://github.com/hujiulong/vue-3d-model/issues/19)). ([1889732](https://github.com/hujiulong/vue-3d-model/commit/1889732f7bc5055d4ed3c2da5e7accb70dd31d5c))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add `model-gltf` to support the gltf format model. ([ad952a5](https://github.com/hujiulong/vue-3d-model/commit/ad952a58ede84c754e3dc7a5b9be9f462f30d703))
|
||||||
|
* model-obj supports MTL file ([3dc003e](https://github.com/hujiulong/vue-3d-model/commit/3dc003e51745d500d8e7faed945088e70664d029))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017-present, Jiulong Hu
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -0,0 +1,93 @@
|
|||||||
|
{
|
||||||
|
"_from": "vue-3d-model",
|
||||||
|
"_id": "vue-3d-model@1.4.1",
|
||||||
|
"_inBundle": false,
|
||||||
|
"_integrity": "sha512-IQjpqEjK1OLF/0XgF6O++IvOPLinLQ2aWZQFHxPFoTfPlB4vQW2sgv8EJSqpsIYC/wSCdGlP3CEnv9L3aZHlow==",
|
||||||
|
"_location": "/vue-3d-model",
|
||||||
|
"_phantomChildren": {},
|
||||||
|
"_requested": {
|
||||||
|
"type": "tag",
|
||||||
|
"registry": true,
|
||||||
|
"raw": "vue-3d-model",
|
||||||
|
"name": "vue-3d-model",
|
||||||
|
"escapedName": "vue-3d-model",
|
||||||
|
"rawSpec": "",
|
||||||
|
"saveSpec": null,
|
||||||
|
"fetchSpec": "latest"
|
||||||
|
},
|
||||||
|
"_requiredBy": [
|
||||||
|
"#USER",
|
||||||
|
"/"
|
||||||
|
],
|
||||||
|
"_resolved": "https://registry.npmmirror.com/vue-3d-model/-/vue-3d-model-1.4.1.tgz",
|
||||||
|
"_shasum": "3d3e415e42ce32520dcc42f5d9e1ddb5e022f3eb",
|
||||||
|
"_spec": "vue-3d-model",
|
||||||
|
"_where": "D:\\ZtProject\\SuzhouVolunteer\\volunteer-pc",
|
||||||
|
"author": {
|
||||||
|
"name": "Jiulong Hu",
|
||||||
|
"email": "me@hujiulong.com"
|
||||||
|
},
|
||||||
|
"bundleDependencies": false,
|
||||||
|
"dependencies": {
|
||||||
|
"three": "^0.135.0"
|
||||||
|
},
|
||||||
|
"deprecated": false,
|
||||||
|
"description": "3D models viewer with vue.js",
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.8",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.8",
|
||||||
|
"@vue/cli-plugin-unit-jest": "~4.5.8",
|
||||||
|
"@vue/cli-service": "~4.5.8",
|
||||||
|
"@vue/eslint-config-airbnb": "^5.0.2",
|
||||||
|
"@vue/test-utils": "^1.0.3",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"chalk": "^4.1.1",
|
||||||
|
"conventional-changelog-cli": "^2.1.1",
|
||||||
|
"enquirer": "^2.3.6",
|
||||||
|
"eslint": "^7.5.0",
|
||||||
|
"eslint-plugin-import": "^2.20.2",
|
||||||
|
"eslint-plugin-vue": "^7.1.0",
|
||||||
|
"execa": "^5.1.1",
|
||||||
|
"less": "^4.1.1",
|
||||||
|
"less-loader": "^10.0.0",
|
||||||
|
"minimist": "^1.2.5",
|
||||||
|
"semver": "^7.3.5",
|
||||||
|
"vue": "^2.6.11",
|
||||||
|
"vue-router": "^3.3.4",
|
||||||
|
"vue-template-compiler": "^2.6.11",
|
||||||
|
"yorkie": "^2.0.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"src",
|
||||||
|
"LICENSE",
|
||||||
|
"package.json",
|
||||||
|
"preview.gif",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"gitHooks": {
|
||||||
|
"commit-msg": "node scripts/verify-commit.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"vue",
|
||||||
|
"three.js",
|
||||||
|
"component"
|
||||||
|
],
|
||||||
|
"main": "dist/vue-3d-model.umd.js",
|
||||||
|
"name": "vue-3d-model",
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": ">=2.0.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "vue-cli-service build --target lib --name vue-3d-model src/index.js",
|
||||||
|
"build-examples": "vue-cli-service build examples/index.js --dest examples-dist",
|
||||||
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||||
|
"dev": "vue-cli-service serve examples/index.js",
|
||||||
|
"gpr-setup": "node scripts/gpr-setup.js",
|
||||||
|
"lint": "vue-cli-service lint src/ tests/ examples/",
|
||||||
|
"lint:fix": "npm run lint -- --fix",
|
||||||
|
"release": "node scripts/release.js",
|
||||||
|
"test": "vue-cli-service test:unit"
|
||||||
|
},
|
||||||
|
"version": "1.4.1"
|
||||||
|
}
|
After Width: | Height: | Size: 273 KiB |
@ -0,0 +1,67 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
|
||||||
|
import ModelObj from "./model-obj.vue";
|
||||||
|
import ModelFbx from "./model-fbx.vue";
|
||||||
|
import ModelThree from "./model-three.vue";
|
||||||
|
import ModelStl from "./model-stl.vue";
|
||||||
|
import ModelPly from "./model-ply.vue";
|
||||||
|
import ModelCollada from "./model-collada.vue";
|
||||||
|
import ModelGltf from "./model-gltf.vue";
|
||||||
|
|
||||||
|
// alias
|
||||||
|
const ModelJson = Vue.extend(ModelThree, {
|
||||||
|
name: "model-json",
|
||||||
|
});
|
||||||
|
|
||||||
|
const ModelDae = Vue.extend(ModelCollada, {
|
||||||
|
name: "model-dae",
|
||||||
|
});
|
||||||
|
|
||||||
|
const components = [
|
||||||
|
ModelObj,
|
||||||
|
ModelFbx,
|
||||||
|
ModelThree,
|
||||||
|
ModelJson,
|
||||||
|
ModelStl,
|
||||||
|
ModelPly,
|
||||||
|
ModelCollada,
|
||||||
|
ModelDae,
|
||||||
|
ModelGltf,
|
||||||
|
];
|
||||||
|
|
||||||
|
/* eslint-disable no-shadow */
|
||||||
|
const install = (Vue) => {
|
||||||
|
components.forEach((component) => {
|
||||||
|
Vue.component(component.name, component);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof window !== "undefined" && window.Vue) {
|
||||||
|
install(window.Vue);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install,
|
||||||
|
ModelObj,
|
||||||
|
ModelFbx,
|
||||||
|
ModelThree,
|
||||||
|
ModelJson,
|
||||||
|
ModelStl,
|
||||||
|
ModelPly,
|
||||||
|
ModelCollada,
|
||||||
|
ModelDae,
|
||||||
|
ModelGltf,
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
install,
|
||||||
|
ModelObj,
|
||||||
|
ModelFbx,
|
||||||
|
ModelThree,
|
||||||
|
ModelJson,
|
||||||
|
ModelStl,
|
||||||
|
ModelPly,
|
||||||
|
ModelCollada,
|
||||||
|
ModelDae,
|
||||||
|
ModelGltf,
|
||||||
|
};
|
@ -0,0 +1,48 @@
|
|||||||
|
<script>
|
||||||
|
import { ColladaLoader } from 'three/examples/jsm/loaders/ColladaLoader';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-collada',
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'HemisphereLight',
|
||||||
|
position: { x: 0, y: 1, z: 0 },
|
||||||
|
skyColor: 0xaaaaff,
|
||||||
|
groundColor: 0x806060,
|
||||||
|
intensity: 0.2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DirectionalLight',
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
smoothing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const loader = new ColladaLoader();
|
||||||
|
loader.setCrossOrigin(this.crossOrigin);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getObject(collada) {
|
||||||
|
return collada.scene;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,42 @@
|
|||||||
|
<script>
|
||||||
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-fbx',
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'HemisphereLight',
|
||||||
|
position: { x: 0, y: 1, z: 0 },
|
||||||
|
skyColor: 0xffffff,
|
||||||
|
groundColor: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DirectionalLight',
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loader: new FBXLoader(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getObject(geometry) {
|
||||||
|
this.animations = geometry.animations;
|
||||||
|
return geometry;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,60 @@
|
|||||||
|
<script>
|
||||||
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-gltf',
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'AmbientLight',
|
||||||
|
color: 0xaaaaaa,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DirectionalLight',
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gammaOutput: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const loader = new GLTFLoader();
|
||||||
|
loader.setCrossOrigin(this.crossOrigin);
|
||||||
|
loader.setRequestHeader(this.requestHeader);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
load() {
|
||||||
|
if (!this.src) return;
|
||||||
|
|
||||||
|
if (this.object) {
|
||||||
|
this.wrapper.remove(this.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loader.load(this.src, (data) => {
|
||||||
|
this.addObject(data.scene);
|
||||||
|
|
||||||
|
this.$emit('on-load');
|
||||||
|
}, (xhr) => {
|
||||||
|
this.$emit('on-progress', xhr);
|
||||||
|
}, (err) => {
|
||||||
|
this.$emit('on-error', err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,137 @@
|
|||||||
|
<script>
|
||||||
|
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
|
||||||
|
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
|
||||||
|
import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader";
|
||||||
|
import { LoadingManager } from "three/src/loaders/LoadingManager";
|
||||||
|
import { toIndexed } from "./util";
|
||||||
|
import mixin from "./model-mixin.vue";
|
||||||
|
|
||||||
|
// TODO: Better way to handle texture formats
|
||||||
|
const manager = new LoadingManager(); // 0.122+ new api
|
||||||
|
manager.addHandler(/\.dds$/i, new DDSLoader());
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "model-obj",
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: "HemisphereLight",
|
||||||
|
position: { x: 0, y: 1, z: 0 },
|
||||||
|
skyColor: 0xaaaaff,
|
||||||
|
groundColor: 0x806060,
|
||||||
|
intensity: 0.2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "DirectionalLight",
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
smoothing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mtlPath: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
mtl: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const objLoader = new OBJLoader(manager);
|
||||||
|
const mtlLoader = new MTLLoader(manager);
|
||||||
|
|
||||||
|
mtlLoader.setCrossOrigin(this.crossOrigin);
|
||||||
|
mtlLoader.setRequestHeader(this.requestHeader);
|
||||||
|
objLoader.setRequestHeader(this.requestHeader);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loader: objLoader,
|
||||||
|
mtlLoader,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
mtl() {
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
process(object) {
|
||||||
|
if (this.smoothing) {
|
||||||
|
object.traverse((child) => {
|
||||||
|
if (child.geometry) {
|
||||||
|
child.geometry = toIndexed(child.geometry);
|
||||||
|
child.geometry.computeVertexNormals();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
load() {
|
||||||
|
if (!this.src) return;
|
||||||
|
|
||||||
|
if (this.object) {
|
||||||
|
this.wrapper.remove(this.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onLoad = (object) => {
|
||||||
|
if (this.process) {
|
||||||
|
this.process(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addObject(object);
|
||||||
|
|
||||||
|
this.$emit("on-load");
|
||||||
|
};
|
||||||
|
|
||||||
|
const onProgress = (xhr) => {
|
||||||
|
this.$emit("on-progress", xhr);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onError = (err) => {
|
||||||
|
this.$emit("on-error", err);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.mtl) {
|
||||||
|
let { mtlPath } = this;
|
||||||
|
let mtlSrc = this.mtl;
|
||||||
|
|
||||||
|
if (!this.mtlPath) {
|
||||||
|
const result = /^(.*\/)([^/]*)$/.exec(this.mtl);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
mtlPath = result[1];
|
||||||
|
mtlSrc = result[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mtlPath) {
|
||||||
|
this.mtlLoader.setPath(mtlPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mtlLoader.load(
|
||||||
|
mtlSrc,
|
||||||
|
(materials) => {
|
||||||
|
materials.preload();
|
||||||
|
|
||||||
|
this.loader
|
||||||
|
.setMaterials(materials)
|
||||||
|
.load(this.src, onLoad, onProgress, onError);
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
onError
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.loader.load(this.src, onLoad, onProgress, onError);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,47 @@
|
|||||||
|
<script>
|
||||||
|
import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader';
|
||||||
|
import {
|
||||||
|
Mesh,
|
||||||
|
MeshStandardMaterial,
|
||||||
|
} from 'three';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-ply',
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'HemisphereLight',
|
||||||
|
position: { x: 0, y: 1, z: 0 },
|
||||||
|
skyColor: 0xaaaaff,
|
||||||
|
groundColor: 0x806060,
|
||||||
|
intensity: 0.2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DirectionalLight',
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loader: new PLYLoader(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getObject(geometry) {
|
||||||
|
geometry.computeVertexNormals();
|
||||||
|
|
||||||
|
return new Mesh(geometry, new MeshStandardMaterial());
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader';
|
||||||
|
import {
|
||||||
|
Mesh,
|
||||||
|
MeshPhongMaterial,
|
||||||
|
} from 'three';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-stl',
|
||||||
|
mixins: [mixin],
|
||||||
|
props: {
|
||||||
|
lights: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'HemisphereLight',
|
||||||
|
position: { x: 0, y: 1, z: 0 },
|
||||||
|
skyColor: 0xaaaaff,
|
||||||
|
groundColor: 0x806060,
|
||||||
|
intensity: 0.2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DirectionalLight',
|
||||||
|
position: { x: 1, y: 1, z: 1 },
|
||||||
|
color: 0xffffff,
|
||||||
|
intensity: 0.8,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loader: new STLLoader(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getObject(geometry) {
|
||||||
|
return new Mesh(geometry, new MeshPhongMaterial());
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,18 @@
|
|||||||
|
<script>
|
||||||
|
import { ObjectLoader } from 'three';
|
||||||
|
import mixin from './model-mixin.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model-three',
|
||||||
|
mixins: [mixin],
|
||||||
|
data() {
|
||||||
|
const loader = new ObjectLoader();
|
||||||
|
loader.setCrossOrigin(this.crossOrigin);
|
||||||
|
loader.setRequestHeader(this.requestHeader);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,160 @@
|
|||||||
|
import {
|
||||||
|
Box3, Vector3, Vector2, BufferAttribute,
|
||||||
|
} from 'three';
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
const box = new Box3();
|
||||||
|
|
||||||
|
function getSize(object) {
|
||||||
|
box.setFromObject(object);
|
||||||
|
|
||||||
|
return box.getSize(new Vector3());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCenter(object) {
|
||||||
|
box.setFromObject(object);
|
||||||
|
|
||||||
|
return box.getCenter(new Vector3());
|
||||||
|
}
|
||||||
|
|
||||||
|
// function lightsDiff(lights, oldLights) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
function toIndexed(bufferGeometry) {
|
||||||
|
const rawPositions = bufferGeometry.getAttribute('position').array;
|
||||||
|
|
||||||
|
let rawUvs;
|
||||||
|
const hasUV = bufferGeometry.getAttribute('uv') !== undefined;
|
||||||
|
if (hasUV) rawUvs = bufferGeometry.getAttribute('uv').array;
|
||||||
|
|
||||||
|
let rawNormals;
|
||||||
|
const hasNormal = bufferGeometry.getAttribute('normal') !== undefined;
|
||||||
|
if (hasNormal) rawNormals = bufferGeometry.getAttribute('normal').array;
|
||||||
|
|
||||||
|
const indices = [];
|
||||||
|
const vertices = [];
|
||||||
|
const normals = [];
|
||||||
|
const uvs = [];
|
||||||
|
|
||||||
|
let face; let faceNormalss; let faceUvs; let
|
||||||
|
tmpIndices;
|
||||||
|
|
||||||
|
const v0 = new Vector3();
|
||||||
|
const v1 = new Vector3();
|
||||||
|
const v2 = new Vector3();
|
||||||
|
|
||||||
|
const n0 = new Vector3();
|
||||||
|
const n1 = new Vector3();
|
||||||
|
const n2 = new Vector3();
|
||||||
|
|
||||||
|
const uv0 = new Vector2();
|
||||||
|
const uv1 = new Vector2();
|
||||||
|
const uv2 = new Vector2();
|
||||||
|
|
||||||
|
for (let i = 0; i < rawPositions.length; i += 9) {
|
||||||
|
v0.x = rawPositions[i];
|
||||||
|
v0.y = rawPositions[i + 1];
|
||||||
|
v0.z = rawPositions[i + 2];
|
||||||
|
|
||||||
|
v1.x = rawPositions[i + 3];
|
||||||
|
v1.y = rawPositions[i + 4];
|
||||||
|
v1.z = rawPositions[i + 5];
|
||||||
|
|
||||||
|
v2.x = rawPositions[i + 6];
|
||||||
|
v2.y = rawPositions[i + 7];
|
||||||
|
v2.z = rawPositions[i + 8];
|
||||||
|
|
||||||
|
face = [v0, v1, v2];
|
||||||
|
|
||||||
|
if (hasNormal) {
|
||||||
|
n0.x = rawNormals[i];
|
||||||
|
n0.y = rawNormals[i + 1];
|
||||||
|
n0.z = rawNormals[i + 2];
|
||||||
|
|
||||||
|
n1.x = rawNormals[i + 3];
|
||||||
|
n1.y = rawNormals[i + 4];
|
||||||
|
n1.z = rawNormals[i + 5];
|
||||||
|
|
||||||
|
n2.x = rawNormals[i + 6];
|
||||||
|
n2.y = rawNormals[i + 7];
|
||||||
|
n2.z = rawNormals[i + 8];
|
||||||
|
|
||||||
|
faceNormalss = [n0, n1, n2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasUV) {
|
||||||
|
uv0.x = rawUvs[i];
|
||||||
|
uv0.y = rawUvs[i + 1];
|
||||||
|
|
||||||
|
uv1.x = rawUvs[i + 2];
|
||||||
|
uv1.y = rawUvs[i + 3];
|
||||||
|
|
||||||
|
uv2.x = rawUvs[i + 4];
|
||||||
|
uv2.y = rawUvs[i + 5];
|
||||||
|
|
||||||
|
faceUvs = [uv0, uv1, uv2];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpIndices = [];
|
||||||
|
|
||||||
|
face.forEach((v, i) => {
|
||||||
|
let id = exists(v, vertices);
|
||||||
|
if (id === -1) {
|
||||||
|
id = vertices.length;
|
||||||
|
vertices.push(v.clone());
|
||||||
|
|
||||||
|
if (hasNormal) normals.push(faceNormalss[i].clone());
|
||||||
|
if (hasUV) uvs.push(faceUvs[i].clone());
|
||||||
|
}
|
||||||
|
tmpIndices.push(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
indices.push(tmpIndices[0], tmpIndices[1], tmpIndices[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const positionBuffer = new Float32Array(vertices.length * 3);
|
||||||
|
|
||||||
|
let normalBuffer; let
|
||||||
|
uvBuffer;
|
||||||
|
|
||||||
|
if (hasNormal) normalBuffer = new Float32Array(vertices.length * 3);
|
||||||
|
if (hasUV) uvBuffer = new Float32Array(vertices.length * 2);
|
||||||
|
|
||||||
|
let i2 = 0;
|
||||||
|
let i3 = 0;
|
||||||
|
for (let i = 0; i < vertices.length; i++) {
|
||||||
|
i3 = i * 3;
|
||||||
|
|
||||||
|
positionBuffer[i3] = vertices[i].x;
|
||||||
|
positionBuffer[i3 + 1] = vertices[i].y;
|
||||||
|
positionBuffer[i3 + 2] = vertices[i].z;
|
||||||
|
|
||||||
|
if (hasNormal) {
|
||||||
|
normalBuffer[i3] = normals[i].x;
|
||||||
|
normalBuffer[i3 + 1] = normals[i].y;
|
||||||
|
normalBuffer[i3 + 2] = normals[i].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasUV) {
|
||||||
|
i2 = i * 2;
|
||||||
|
uvBuffer[i2] = uvs[i].x;
|
||||||
|
uvBuffer[i2 + 1] = uvs[i].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferGeometry.addAttribute('position', new BufferAttribute(positionBuffer, 3));
|
||||||
|
if (hasNormal) bufferGeometry.addAttribute('normal', new BufferAttribute(normalBuffer, 3));
|
||||||
|
if (hasUV) bufferGeometry.addAttribute('uv', new BufferAttribute(uvBuffer, 2));
|
||||||
|
bufferGeometry.setIndex(new BufferAttribute(new Uint32Array(indices), 1));
|
||||||
|
return bufferGeometry;
|
||||||
|
|
||||||
|
function exists(v, vertices) {
|
||||||
|
for (let i = 0; i < vertices.length; i++) {
|
||||||
|
if (v.equals(vertices[i])) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { getSize, getCenter, toIndexed };
|
Loading…
Reference in new issue