mirror of
				https://github.com/haselkern/Minecraft-ArmorStand.git
				synced 2025-10-30 21:24:06 +00:00 
			
		
		
		
	TroisJS demo
This commit is contained in:
		
							parent
							
								
									608fce96cc
								
							
						
					
					
						commit
						e46ba54aac
					
				
					 18 changed files with 2725 additions and 12871 deletions
				
			
		
							
								
								
									
										36
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								README.md
									
										
									
									
									
								
							|  | @ -1,36 +0,0 @@ | |||
| # Minecraft Armorstand | ||||
| 
 | ||||
| ## [Try it out](http://haselkern.github.io/Minecraft-ArmorStand) | ||||
| 
 | ||||
| In Minecraft 1.8 armorstands were introduced. Unfortunately, the syntax to summon one is quite confusing and not very intuitive, especially when you're trying to create an awesome pose. This tool provides a graphical interface so that you can focus on the looks and not worry about the code. | ||||
| 
 | ||||
| If you would like to see a feature implemented, feel free to open an issue or submit a pull request. | ||||
| 
 | ||||
| ## Development | ||||
| 
 | ||||
| To install all required dependencies run: | ||||
| 
 | ||||
| ```sh | ||||
| npm install | ||||
| ``` | ||||
| 
 | ||||
| Run this when developing. It will automatically rebuild the project on changes. | ||||
| 
 | ||||
| ```sh | ||||
| npm run serve | ||||
| ``` | ||||
| 
 | ||||
| The project will automatically build on pushes on the master branch. If you want to build the production build locally, you can run this to generate the `dist` directory. | ||||
| 
 | ||||
| ```sh | ||||
| npm run build | ||||
| ``` | ||||
| 
 | ||||
| Run the linter to check for mistakes: | ||||
| 
 | ||||
| ```sh | ||||
| npm run lint | ||||
| ``` | ||||
| 
 | ||||
| ## TODO | ||||
| Currently Vue does not support Postcss 8, so we use a compatibility build of it. Some time in the future, [this should be upgraded](https://tailwindcss.com/docs/installation#post-css-7-compatibility-build). | ||||
|  | @ -1,5 +0,0 @@ | |||
| module.exports = { | ||||
|     presets: [ | ||||
|         '@vue/cli-plugin-babel/preset' | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										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>TroisJS App</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div id="app"></div> | ||||
|     <script type="module" src="/src/main.js"></script> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										15183
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										15183
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										58
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								package.json
									
										
									
									
									
								
							|  | @ -1,50 +1,22 @@ | |||
| { | ||||
|   "name": "minecraft-armorstand", | ||||
|   "version": "2.0.0", | ||||
|   "private": true, | ||||
|   "name": "troisjs-app", | ||||
|   "version": "0.0.0", | ||||
|   "scripts": { | ||||
|     "serve": "vue-cli-service serve", | ||||
|     "build": "vue-cli-service build", | ||||
|     "lint": "vue-cli-service lint" | ||||
|     "dev": "vite", | ||||
|     "build": "vite build", | ||||
|     "serve": "vite preview" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@fortawesome/fontawesome-free": "^5.15.1", | ||||
|     "autoprefixer": "^9.8.6", | ||||
|     "core-js": "^3.6.5", | ||||
|     "dat.gui": "^0.7.7", | ||||
|     "oimo": "^1.0.9", | ||||
|     "postcss": "^7.0.35", | ||||
|     "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2", | ||||
|     "three": "^0.123.0", | ||||
|     "vue": "^2.6.11", | ||||
|     "vue-threejs": "^0.2.0-alpha.1" | ||||
|     "three": "^0.127.0", | ||||
|     "troisjs": "^0.3.1", | ||||
|     "vue": "^3.0.11" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@vue/cli-plugin-babel": "~4.5.0", | ||||
|     "@vue/cli-plugin-eslint": "~4.5.0", | ||||
|     "@vue/cli-service": "~4.5.0", | ||||
|     "babel-eslint": "^10.1.0", | ||||
|     "eslint": "^6.7.2", | ||||
|     "eslint-plugin-vue": "^6.2.2", | ||||
|     "vue-template-compiler": "^2.6.11" | ||||
|   }, | ||||
|   "eslintConfig": { | ||||
|     "root": true, | ||||
|     "env": { | ||||
|       "node": true | ||||
|     }, | ||||
|     "extends": [ | ||||
|       "plugin:vue/essential", | ||||
|       "eslint:recommended" | ||||
|     ], | ||||
|     "parserOptions": { | ||||
|       "parser": "babel-eslint" | ||||
|     }, | ||||
|     "rules": {} | ||||
|   }, | ||||
|   "browserslist": [ | ||||
|     "> 1%", | ||||
|     "last 2 versions", | ||||
|     "not dead" | ||||
|   ] | ||||
|     "@vitejs/plugin-vue": "^1.2.2", | ||||
|     "@vue/compiler-sfc": "^3.0.11", | ||||
|     "autoprefixer": "^10.3.1", | ||||
|     "postcss": "^8.3.6", | ||||
|     "tailwindcss": "^2.2.7", | ||||
|     "vite": "^2.2.3" | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const autoprefixer = require("autoprefixer"); | ||||
| const tailwindcss = require("tailwindcss"); | ||||
| 
 | ||||
| module.exports = { | ||||
|     plugins: [ | ||||
|         require("tailwindcss"), | ||||
|         require("autoprefixer"), | ||||
|     ] | ||||
|   plugins: { | ||||
|     tailwindcss: {}, | ||||
|     autoprefixer: {}, | ||||
|   }, | ||||
| } | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								public/favicon.ico
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/favicon.ico
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.2 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 360 B | 
|  | @ -1,17 +0,0 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
|     <meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||||
|     <link rel="icon" type="image/png" href="<%= BASE_URL %>favicon.png"> | ||||
|     <title>Minecraft Armorstand</title> | ||||
| </head> | ||||
| <body> | ||||
|     <noscript> | ||||
|         <strong>We're sorry but Minecraft Armorstand doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | ||||
|     </noscript> | ||||
|     <div id="app"></div> | ||||
|     <!-- built files will be auto injected --> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										81
									
								
								src/App.vue
									
										
									
									
									
								
							
							
						
						
									
										81
									
								
								src/App.vue
									
										
									
									
									
								
							|  | @ -1,83 +1,24 @@ | |||
|     <template> | ||||
|     <div class="grid grid-cols-5 min-h-screen bg-gray-700"> | ||||
|         <div ref="rendererwrapper" class="col-span-3"> | ||||
|             <renderer :obj="renderer" :size="{w: 400, h: 400}"> | ||||
|                 <scene> | ||||
|                     <orbit-controls :position="{z: 3}" | ||||
|                         :rotation="{x: 2, y: 0, z: 3}"> | ||||
|                         <camera :obj="camera"></camera> | ||||
|                         <light :hex="0xFFFFFF" :position="{x: 100, y: 200, z: 300}"></light> | ||||
|                     </orbit-controls> | ||||
|                     <armorstand :pose="pose"></armorstand> | ||||
|                 </scene> | ||||
|             </renderer> | ||||
| <template> | ||||
|     <div class="flex"> | ||||
|         <div class="flex-1 h-screen"> | ||||
|             <Scene :rot="roty" /> | ||||
|         </div> | ||||
|         <div class="col-span-2"> | ||||
|             <card class="text-center"> | ||||
|                 <h1 class="text-2xl font-bold">Minecraft Armorstand</h1> | ||||
|                 <a | ||||
|                     title="Source Code" | ||||
|                     href="https://github.com/haselkern/Minecraft-ArmorStand" | ||||
|                     class="inline-flex items-center justify-center w-8 h-8 m-2 text-white bg-gray-700 rounded-lg"> | ||||
|                     <i class="fas fa-code"></i> | ||||
|                 </a> | ||||
|                 <a | ||||
|                     title="Help" | ||||
|                     href="https://haselkern.com/armorstand/" | ||||
|                     class="inline-flex items-center justify-center w-8 h-8 m-2 text-white bg-gray-700 rounded-lg"> | ||||
|                     <i class="fas fa-question"></i> | ||||
|                 </a> | ||||
|             </card> | ||||
|             <card> | ||||
|                 <h1 class="text-xl">Pose</h1> | ||||
|                 <!-- TODO modularize sliders --> | ||||
|                 <table class="w-full"> | ||||
|                     <tr> | ||||
|                         <td>Rotation</td> | ||||
|                         <td colspan="3"><input class="w-full" type="range" min="0" max="360"></td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td>Head</td> | ||||
|                         <td><input v-model="pose.head.x" class="w-full" type="range" min="0" max="360"></td> | ||||
|                         <td><input v-model="pose.head.y" class="w-full" type="range" min="0" max="360"></td> | ||||
|                         <td><input v-model="pose.head.z" class="w-full" type="range" min="0" max="360"></td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </card> | ||||
|         <div class="flex-none w-60"> | ||||
|             <h1>{{ roty }}</h1> | ||||
|             <input type="range" min="0" max="100" v-model="roty" /> | ||||
|         </div> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import Card from "./components/Card"; | ||||
| import Armorstand from "./components/Armorstand"; | ||||
| import * as THREE from "three"; | ||||
| import Scene from "./Scene.vue" | ||||
| 
 | ||||
| export default { | ||||
|     components: {Card, Armorstand}, | ||||
|     data() { | ||||
|         return { | ||||
|             renderer: new THREE.WebGLRenderer({alpha: true, antialias: true}), | ||||
|             camera: new THREE.PerspectiveCamera(70, 400 / 400, 0.1, 100), | ||||
|             ambientLight: new THREE.AmbientLight(0x333333), | ||||
|             pose: { | ||||
|                 head: {x: 0, y: 0, z: 0}, | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
|     mounted() { | ||||
|         this.resize(); | ||||
|         window.resize = this.resize; | ||||
|     }, | ||||
|     methods: { | ||||
|         resize() { | ||||
|             let el = this.$refs.rendererwrapper; | ||||
|             let w = el.clientWidth; | ||||
|             let h = el.clientHeight; | ||||
|             this.camera.aspect = w/h; | ||||
|             this.camera.updateProjectionMatrix(); | ||||
|             this.renderer.setSize(w, h); | ||||
|         }, | ||||
|             roty: 0, | ||||
|         } | ||||
|     }, | ||||
|     components: {Scene}, | ||||
| } | ||||
| </script> | ||||
|  |  | |||
							
								
								
									
										39
									
								
								src/Scene.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/Scene.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| <template> | ||||
|     <Renderer ref="renderer" antialias :orbit-ctrl="{ enableDamping: false }" resize="true"> | ||||
|         <Camera :position="{ z: 10 }" /> | ||||
|         <Scene> | ||||
|             <AmbientLight :intensity="0.3" /> | ||||
|             <DirectionalLight :intensity="1" :position="{ x: 10, y: 9 }" /> | ||||
|             <Box ref="box" :rotation="{ y: rot / Math.PI / 4 }"> | ||||
|                 <LambertMaterial /> | ||||
|             </Box> | ||||
|         </Scene> | ||||
|     </Renderer> | ||||
| </template> | ||||
|    | ||||
| <script> | ||||
| 
 | ||||
| import { Box, Camera, LambertMaterial, AmbientLight, Renderer, Scene } from 'troisjs'; | ||||
| 
 | ||||
| export default { | ||||
|     props: ["rot"], | ||||
|     mounted() { | ||||
|         // const renderer = this.$refs.renderer | ||||
|         // const box = this.$refs.box.mesh | ||||
|         // renderer.onBeforeRender(() => { | ||||
|         //     box.rotation.x += 0.01 | ||||
|         // }) | ||||
|     }, | ||||
|     components: { Box, Camera, LambertMaterial, Renderer, Scene }, | ||||
| } | ||||
| </script> | ||||
|    | ||||
| <style> | ||||
| body { | ||||
|     margin: 0; | ||||
| } | ||||
| canvas { | ||||
|     display: block; | ||||
| } | ||||
| </style> | ||||
|    | ||||
|  | @ -1,3 +0,0 @@ | |||
| @tailwind base; | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
|  | @ -1,101 +0,0 @@ | |||
| <template> | ||||
|     <!-- Armorstand --> | ||||
|     <object3d :position="{y: -1}"> | ||||
|         <!-- BasePlate --> | ||||
|         <mesh :position="{x: 0, y: -1/32, z: 0}"> | ||||
|             <material type="MeshPhong" :color="colorStone"></material> | ||||
|             <geometry type="Box" :args="[12/16, 1/16, 12/16]"></geometry> | ||||
|         </mesh> | ||||
|         <!-- Little direction indicator for the baseplate --> | ||||
|         <mesh :position="{x: 0, y: -1/32, z: 10/16}"> | ||||
|             <material type="MeshPhong" :color="colorStone"></material> | ||||
|             <geometry type="Box" :args="[2/16, 1/16, 4/16]"></geometry> | ||||
|         </mesh> | ||||
|         <!-- Left leg --> | ||||
|         <object3d :position="{x: 2/16, y: 11/16, z: 0}"> | ||||
|             <mesh :position="{x: 0, y: -5.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 11/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|         <!-- Right leg --> | ||||
|         <object3d :position="{x: -2/16, y: 11/16, z: 0}"> | ||||
|             <mesh :position="{x: 0, y: -5.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 11/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|         <!-- Left arm --> | ||||
|         <object3d :position="{x: 6/16, y: 21/16, z: 0}"> | ||||
|             <mesh :position="{x: 0, y: -4/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 12/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|         <!-- Right arm --> | ||||
|         <object3d :position="{x: -6/16, y: 21/16, z: 0}"> | ||||
|             <mesh :position="{x: 0, y: -4/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 12/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|         <!-- Body --> | ||||
|         <object3d :position="{x: 0, y: 23/16, z: 0}"> | ||||
|             <!-- Hip --> | ||||
|             <mesh :position="{x: 0, y: -11/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[8/16, 2/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|             <!-- Left side --> | ||||
|             <mesh :position="{x: 2/16, y: -6.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 7/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|             <!-- Right side --> | ||||
|             <mesh :position="{x: -2/16, y: -6.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 7/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|             <!-- Shoulders --> | ||||
|             <mesh :position="{x: 0, y: -1.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[12/16, 3/16, 3/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|         <!-- Head --> | ||||
|         <object3d :position="{x: 0, y: 22/16, z: 0}" :rotation="head"> | ||||
|             <!-- Neck --> | ||||
|             <mesh :position="{x: 0, y: 3.5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorWood"></material> | ||||
|                 <geometry type="Box" :args="[2/16, 7/16, 2/16]"></geometry> | ||||
|             </mesh> | ||||
|             <!-- Skull --> | ||||
|             <mesh :position="{x: 0, y: 5/16, z: 0}"> | ||||
|                 <material type="MeshPhong" :color="colorStone"></material> | ||||
|                 <geometry type="Box" :args="[10/16, 10/16, 10/16]"></geometry> | ||||
|             </mesh> | ||||
|         </object3d> | ||||
|     </object3d> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| export default { | ||||
|     props: ["pose"], | ||||
|     data() { | ||||
|         return { | ||||
|             colorWood: 0xCC933D, | ||||
|             colorStone: 0x888888, | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         head() { | ||||
|             // TODO Translate rotation Minecraft -> ThreeJS | ||||
|             return { | ||||
|                 x: this.pose.head.x * Math.PI/180, | ||||
|                 y: this.pose.head.y * Math.PI/180, | ||||
|                 z: this.pose.head.z * Math.PI/180, | ||||
|             }; | ||||
|         }, | ||||
|     }, | ||||
| } | ||||
| </script> | ||||
|  | @ -1,5 +0,0 @@ | |||
| <template> | ||||
|     <div class="bg-white rounded-lg m-2 p-2 shadow"> | ||||
|         <slot/> | ||||
|     </div> | ||||
| </template> | ||||
							
								
								
									
										6
									
								
								src/main.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/main.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| /* | ||||
|  * Do not define your own styles, instead use https://tailwindcss.com/ classes on your elements. | ||||
|  */ | ||||
| @tailwind base; | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
							
								
								
									
										14
									
								
								src/main.js
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.js
									
										
									
									
									
								
							|  | @ -1,11 +1,5 @@ | |||
| import Vue from "vue"; | ||||
| import App from "./App.vue"; | ||||
| import * as VueThreejs from "vue-threejs"; | ||||
| import "./assets/tailwind.css"; | ||||
| import "../node_modules/@fortawesome/fontawesome-free/css/all.css"; | ||||
| import { createApp } from 'troisjs' | ||||
| import App from './App.vue' | ||||
| import "./main.css" | ||||
| 
 | ||||
| Vue.use(VueThreejs); | ||||
| 
 | ||||
| new Vue({ | ||||
|   render: h => h(App), | ||||
| }).$mount('#app'); | ||||
| createApp(App).mount('#app') | ||||
|  |  | |||
|  | @ -1,8 +1,11 @@ | |||
| module.exports = { | ||||
|     purge: [ | ||||
|       "./src/**/*.vue", | ||||
|     ], | ||||
|     theme: {}, | ||||
|     variants: {}, | ||||
|     plugins: [], | ||||
|   } | ||||
|   purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], | ||||
|   darkMode: false, // or 'media' or 'class'
 | ||||
|   theme: { | ||||
|     extend: {}, | ||||
|   }, | ||||
|   variants: { | ||||
|     extend: {}, | ||||
|   }, | ||||
|   plugins: [], | ||||
| } | ||||
|  |  | |||
							
								
								
									
										7
									
								
								vite.config.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vite.config.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| import { defineConfig } from 'vite' | ||||
| import vue from '@vitejs/plugin-vue' | ||||
| 
 | ||||
| // https://vitejs.dev/config/
 | ||||
| export default defineConfig({ | ||||
|   plugins: [vue()] | ||||
| }) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue