├── src
├── assets
│ ├── mesh
│ │ ├── mesh.obj.manifest
│ │ └── mesh.mtl
│ └── texture
│ │ ├── Thumbs.db
│ │ ├── ground.jpg
│ │ ├── waterbump.png
│ │ └── skybox
│ │ ├── Thumbs.db
│ │ ├── TropicalSunnyDay_nx.jpg
│ │ ├── TropicalSunnyDay_ny.jpg
│ │ ├── TropicalSunnyDay_nz.jpg
│ │ ├── TropicalSunnyDay_px.jpg
│ │ ├── TropicalSunnyDay_py.jpg
│ │ └── TropicalSunnyDay_pz.jpg
├── index.ts
├── index.ejs
├── game.ts
└── game-utils.ts
├── .gitignore
├── tsconfig.json
├── README.md
├── package.json
└── webpack.config.js
/src/assets/mesh/mesh.obj.manifest:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .vscode
4 | .idea
5 | *.iml
6 | .gitignore
--------------------------------------------------------------------------------
/src/assets/texture/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/Thumbs.db
--------------------------------------------------------------------------------
/src/assets/texture/ground.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/ground.jpg
--------------------------------------------------------------------------------
/src/assets/texture/waterbump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/waterbump.png
--------------------------------------------------------------------------------
/src/assets/texture/skybox/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/Thumbs.db
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_nx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_nx.jpg
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_ny.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_ny.jpg
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_nz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_nz.jpg
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_px.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_px.jpg
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_py.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_py.jpg
--------------------------------------------------------------------------------
/src/assets/texture/skybox/TropicalSunnyDay_pz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandadelphin/babylonjs-typescript-webpack-starter/HEAD/src/assets/texture/skybox/TropicalSunnyDay_pz.jpg
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "target": "es6",
5 | "module": "commonjs",
6 | "noResolve": false,
7 | "noImplicitAny": false,
8 | "sourceMap": true,
9 | "preserveConstEnums": true,
10 | "lib": [
11 | "dom",
12 | "es6"
13 | ],
14 | "rootDir": "src"
15 | }
16 | }
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import 'babylonjs-loaders';
2 | import { Game } from './game';
3 | import CANNON = require('cannon');
4 |
5 | window.addEventListener('DOMContentLoaded', () => {
6 | // Set global variable for cannonjs physics engine
7 | window.CANNON = CANNON;
8 | let game = new Game('renderCanvas');
9 | game.createScene();
10 | game.animate();
11 | });
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | A starter template for those who want to use the famous javascript 3D game engine babylonjs with typescript and webpack.
2 |
3 | ## How to Start? ##
4 |
5 | 1. Download and Install Node.js
6 | 2. Open Commandline and Enter
7 | ```
8 | npm install
9 | npm start
10 | ```
11 | 3. Open Browser and Enter [http://localhost:8080](http://localhost:8080)
12 |
13 | ## Deployable Product Build ##
14 | 1. Build the app
15 | ```
16 | npm run build
17 | ```
18 | 2. Deployable app is in dist folder now
19 |
--------------------------------------------------------------------------------
/src/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Webpack TypeScript BabylonJS Starter
6 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/assets/mesh/mesh.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'Shark.blend'
2 | # Material Count: 3
3 |
4 | newmtl Base
5 | Ns 96.078431
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.787908 0.787908 0.787908
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.000000
11 | d 1.000000
12 | illum 2
13 |
14 | newmtl Eye
15 | Ns 96.078431
16 | Ka 1.000000 1.000000 1.000000
17 | Kd 0.015079 0.015079 0.015079
18 | Ks 0.500000 0.500000 0.500000
19 | Ke 0.000000 0.000000 0.000000
20 | Ni 1.000000
21 | d 1.000000
22 | illum 2
23 |
24 | newmtl Top
25 | Ns 96.078431
26 | Ka 1.000000 1.000000 1.000000
27 | Kd 0.321575 0.321575 0.321575
28 | Ks 0.500000 0.500000 0.500000
29 | Ke 0.000000 0.000000 0.000000
30 | Ni 1.000000
31 | d 1.000000
32 | illum 2
33 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babylonjs-typescript-webpack-starter",
3 | "version": "1.0.0",
4 | "description": "Template for Webpack TypeScript and BabylonJS",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "start": "webpack serve --open"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "@types/es6-shim": "^0.31.41",
15 | "clean-webpack-plugin": "^3.0.0",
16 | "copy-webpack-plugin": "^7.0.0",
17 | "css-loader": "^5.1.0",
18 | "html-webpack-plugin": "^5.2.0",
19 | "imports-loader": "^2.0.0",
20 | "style-loader": "^2.0.0",
21 | "ts-loader": "^8.0.17",
22 | "typescript": "^4.2.2",
23 | "webpack": "^5.24.2",
24 | "webpack-cli": "^4.5.0",
25 | "webpack-dev-server": "^3.11.2"
26 | },
27 | "dependencies": {
28 | "babylonjs": "^4.2.0",
29 | "babylonjs-gui": "^4.2.0",
30 | "babylonjs-loaders": "^4.2.0",
31 | "babylonjs-materials": "^4.2.0",
32 | "cannon": "^0.6.2",
33 | "earcut": "^2.2.2",
34 | "lodash": "^4.17.21",
35 | "oimo": "^1.0.9",
36 | "rxjs": "^6.6.6"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | // Optimizes duplicates in splitted bundles
3 | const webpack = require('webpack');
4 | // creates index.html file by a template index.ejs
5 | const HtmlWebpackPlugin = require('html-webpack-plugin');
6 | // cleans dist folder
7 | const { CleanWebpackPlugin } = require('clean-webpack-plugin');
8 | // copies the assets folder into dist folder
9 | const CopyWebpackPlugin = require('copy-webpack-plugin');
10 | // output folder location
11 | const distFolder = "./dist";
12 |
13 | module.exports = {
14 | mode: 'development',
15 | entry: './src/index.ts',
16 | plugins: [
17 | new CleanWebpackPlugin(),
18 | new HtmlWebpackPlugin({
19 | template: 'src/index.ejs'
20 | }),
21 | new CopyWebpackPlugin({
22 | patterns: [
23 | { from: 'src/assets', to: 'assets' },
24 | ]
25 | })
26 | ],
27 | devtool: 'inline-source-map',
28 | devServer: {
29 | contentBase: distFolder
30 | },
31 | module: {
32 | rules: [
33 | {
34 | test: /\.tsx?$/,
35 | use: 'ts-loader',
36 | exclude: /node_modules/
37 | },
38 | {
39 | test: /\.css$/,
40 | use: [
41 | 'style-loader',
42 | 'css-loader'
43 | ]
44 | }
45 | ]
46 | },
47 | optimization: {
48 | splitChunks: {
49 | cacheGroups: {
50 | commons: {
51 | test: /[\\/]node_modules[\\/]/,
52 | name: "vendors",
53 | chunks: "all"
54 | }
55 | }
56 | }
57 | },
58 | resolve: {
59 | extensions: [".tsx", ".ts", ".js"]
60 | },
61 | output: {
62 | filename: '[name].bundle.js',
63 | path: path.resolve(__dirname, distFolder)
64 | }
65 | };
--------------------------------------------------------------------------------
/src/game.ts:
--------------------------------------------------------------------------------
1 | import { GameUtils } from './game-utils';
2 | import * as BABYLON from 'babylonjs';
3 | import * as GUI from 'babylonjs-gui';
4 |
5 | export class Game {
6 |
7 | private _canvas: HTMLCanvasElement;
8 | private _engine: BABYLON.Engine;
9 | private _scene: BABYLON.Scene;
10 | private _camera: BABYLON.ArcRotateCamera;
11 | private _light: BABYLON.Light;
12 | private _sharkMesh: BABYLON.AbstractMesh;
13 | private _sharkAnimationTime = 0;
14 | private _swim: boolean = false;
15 | private _txtCoordinates: { txtX: GUI.TextBlock, txtY: GUI.TextBlock, txtZ: GUI.TextBlock } = null;
16 |
17 | constructor(canvasElement: string) {
18 | // Create canvas and engine
19 | this._canvas = document.getElementById(canvasElement);
20 | this._engine = new BABYLON.Engine(this._canvas, true);
21 | }
22 |
23 | /**
24 | * Creates the BABYLONJS Scene
25 | */
26 | createScene(): void {
27 | // create a basic BJS Scene object
28 | this._scene = new BABYLON.Scene(this._engine);
29 | // create a FreeCamera, and set its position to (x:0, y:5, z:-10)
30 | this._camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, Math.PI / 4, 30, BABYLON.Vector3.Zero(), this._scene);
31 | this._camera.attachControl(this._canvas, true);
32 | // create a basic light, aiming 0,1,0 - meaning, to the sky
33 | this._light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), this._scene);
34 | // create the skybox
35 | let skybox = GameUtils.createSkybox("skybox", "./assets/texture/skybox/TropicalSunnyDay", this._scene);
36 | // creates the sandy ground
37 | let ground = GameUtils.createGround(this._scene);
38 | // creates the watermaterial and adds the relevant nodes to the renderlist
39 | let waterMaterial = GameUtils.createWater(this._scene);
40 | waterMaterial.addToRenderList(skybox);
41 | waterMaterial.addToRenderList(ground);
42 | // create a shark mesh from a .obj file
43 | GameUtils.createShark(this._scene)
44 | .subscribe(sharkMesh => {
45 | this._sharkMesh = sharkMesh;
46 | this._sharkMesh.getChildren().forEach(
47 | mesh => {
48 | waterMaterial.addToRenderList(mesh);
49 | }
50 | );
51 | });
52 | // finally the new ui
53 | let guiTexture = GameUtils.createGUI();
54 |
55 | // Button to start shark animation
56 | GameUtils.createButtonSwim(guiTexture, "Start Swimming",
57 | (btn) => {
58 | let textControl = btn.children[0] as GUI.TextBlock;
59 | this._swim = !this._swim;
60 | if (this._swim) {
61 | textControl.text = "Stop Swimming";
62 | }
63 | else {
64 | this._sharkAnimationTime = 0;
65 | textControl.text = "Start Swimming";
66 | }
67 | });
68 |
69 | // Debug Text for Shark coordinates
70 | this._txtCoordinates = GameUtils.createCoordinatesText(guiTexture);
71 |
72 | // Physics engine also works
73 | let gravity = new BABYLON.Vector3(0, -0.9, 0);
74 | this._scene.enablePhysics(gravity, new BABYLON.CannonJSPlugin());
75 | }
76 |
77 |
78 | /**
79 | * Starts the animation loop.
80 | */
81 | animate(): void {
82 | this._scene.registerBeforeRender(() => {
83 | let deltaTime: number = (1 / this._engine.getFps());
84 | this.animateShark(deltaTime);
85 | });
86 |
87 | // run the render loop
88 | this._engine.runRenderLoop(() => {
89 | this._scene.render();
90 | });
91 |
92 | // the canvas/window resize event handler
93 | window.addEventListener('resize', () => {
94 | this._engine.resize();
95 | });
96 | }
97 |
98 | animateShark(deltaTime: number): void {
99 | this.debugFirstMeshCoordinate(this._sharkMesh as BABYLON.Mesh);
100 | if (this._sharkMesh && this._swim) {
101 | this._sharkAnimationTime += deltaTime;
102 | this._sharkMesh.getChildren().forEach(
103 | mesh => {
104 | let realMesh = mesh;
105 | let vertexData = BABYLON.VertexData.ExtractFromMesh(realMesh);
106 | let positions = vertexData.positions;
107 | let numberOfPoints = positions.length / 3;
108 | for (let i = 0; i < numberOfPoints; i++) {
109 | let vertex = new BABYLON.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
110 | vertex.x += (Math.sin(0.15 * vertex.z + this._sharkAnimationTime * 4 - 1.6) * 0.05);
111 | positions[i * 3] = vertex.x;
112 |
113 | }
114 | vertexData.applyToMesh(mesh as BABYLON.Mesh);
115 | }
116 | );
117 | }
118 | }
119 |
120 | /**
121 | * Prints the coordinates of the first vertex of a mesh
122 | */
123 | public debugFirstMeshCoordinate(mesh: BABYLON.Mesh) {
124 | if(!mesh || !mesh.getChildren()) {
125 | return;
126 | }
127 | let firstMesh = (mesh.getChildren()[0] as BABYLON.Mesh)
128 | let vertexData = BABYLON.VertexData.ExtractFromMesh(firstMesh);
129 | let positions = vertexData.positions;
130 | let firstVertex = new BABYLON.Vector3(positions[0], positions[1], positions[3]);
131 | this.updateCoordinateTexture(firstVertex);
132 | }
133 |
134 | /**
135 | * Prints the given Vector3
136 | * @param coordinates
137 | */
138 | public updateCoordinateTexture(coordinates: BABYLON.Vector3) {
139 | if(!coordinates) {
140 | return;
141 | }
142 | this._txtCoordinates.txtX.text = "X: " + coordinates.x;
143 | this._txtCoordinates.txtY.text = "Y: " + coordinates.y;
144 | this._txtCoordinates.txtZ.text = "Z: " + coordinates.z;
145 | }
146 |
147 | }
--------------------------------------------------------------------------------
/src/game-utils.ts:
--------------------------------------------------------------------------------
1 | import * as BABYLON from 'babylonjs';
2 | import * as MATERIAL from 'babylonjs-materials';
3 | import * as GUI from 'babylonjs-gui';
4 | import { Observable } from 'rxjs';
5 | import { map } from 'rxjs/operators';
6 |
7 | export class GameUtils {
8 |
9 | /**
10 | * Creates a basic ground
11 | * @param scene
12 | */
13 | public static createGround(scene: BABYLON.Scene): BABYLON.Mesh {
14 | // Ground
15 | let groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
16 | groundMaterial.diffuseTexture = new BABYLON.Texture("./assets/texture/ground.jpg", scene);
17 | //groundMaterial.diffuseTexture.uScale = groundMaterial.diffuseTexture.vScale = 4;
18 | let ground = BABYLON.Mesh.CreateGround("ground", 512, 512, 32, scene, false);
19 | ground.position.y = -1;
20 | ground.material = groundMaterial;
21 |
22 | return ground;
23 | }
24 |
25 | /**
26 | * Creates a second ground and adds a watermaterial to it
27 | * @param scene
28 | */
29 | public static createWater(scene: BABYLON.Scene): MATERIAL.WaterMaterial {
30 | // Water
31 | let waterMesh = BABYLON.Mesh.CreateGround("waterMesh", 512, 512, 32, scene, false);
32 | let waterMaterial = GameUtils.createWaterMaterial("water", "./assets/texture/waterbump.png", scene);
33 | waterMesh.material = waterMaterial;
34 | waterMesh.position.y = 4;
35 |
36 | return waterMaterial;
37 | }
38 |
39 | /**
40 | * Creates a Gui Texture
41 | */
42 | public static createGUI() {
43 | return GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
44 | }
45 |
46 | /**
47 | * Creates a Button that tells the Shark to swim or not
48 | * @param guiTexture
49 | * @param btnText
50 | * @param btnClicked
51 | */
52 | public static createButtonSwim(guiTexture: GUI.AdvancedDynamicTexture, btnText: string, btnClicked: (button: GUI.Button) => void) {
53 |
54 | let btnTest = GUI.Button.CreateSimpleButton("but1", btnText);
55 | btnTest.width = "150px";
56 | btnTest.height = "40px";
57 | btnTest.color = "white";
58 | btnTest.background = "grey";
59 | btnTest.onPointerUpObservable.add(() => {
60 | if (btnClicked) {
61 | btnClicked(btnTest);
62 | }
63 | });
64 | btnTest.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
65 | btnTest.verticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
66 | btnTest.left = 12;
67 | btnTest.top = 12;
68 |
69 | guiTexture.addControl(btnTest);
70 | }
71 |
72 | public static createVerticalLine(scene: BABYLON.Scene, position: BABYLON.Vector2) {
73 | //Array of points to construct lines
74 | var myPoints = [
75 | new BABYLON.Vector3(position.x, 0, position.y),
76 | new BABYLON.Vector3(position.x, 100, position.y),
77 | ];
78 | //Create lines
79 | var lines = BABYLON.MeshBuilder.CreateLines("lines", {points: myPoints}, scene);
80 | }
81 |
82 | /**
83 | *
84 | * @param guiTexture
85 | */
86 | public static createCoordinatesText(guiTexture: GUI.AdvancedDynamicTexture): { txtX: GUI.TextBlock, txtY: GUI.TextBlock, txtZ: GUI.TextBlock } {
87 | let txtX = new GUI.TextBlock();
88 | txtX.height = "20px";
89 | txtX.width = "500px";
90 | txtX.fontSize = 20;
91 | txtX.text = "X: ";
92 | txtX.textHorizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
93 | txtX.textVerticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
94 | txtX.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
95 | txtX.verticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
96 | txtX.left = 20;
97 | txtX.top = 60;
98 |
99 | let txtY = new GUI.TextBlock();
100 | txtY.height = "20px";
101 | txtY.width = "500px";
102 | txtY.fontSize = 20;
103 | txtY.text = "Y: ";
104 | txtY.textHorizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
105 | txtY.textVerticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
106 | txtY.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
107 | txtY.verticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
108 | txtY.left = 20;
109 | txtY.top = 90;
110 |
111 | let txtZ = new GUI.TextBlock();
112 | txtZ.height = "20px";
113 | txtZ.width = "500px";
114 | txtZ.fontSize = 20;
115 | txtZ.text = "Z: ";
116 | txtZ.textHorizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
117 | txtZ.textVerticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
118 | txtZ.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
119 | txtZ.verticalAlignment = GUI.Control.VERTICAL_ALIGNMENT_TOP;
120 | txtZ.left = 20;
121 | txtZ.top = 120;
122 |
123 | guiTexture.addControl(txtX);
124 | guiTexture.addControl(txtY);
125 | guiTexture.addControl(txtZ);
126 |
127 | return {
128 | txtX: txtX,
129 | txtY: txtY,
130 | txtZ: txtZ
131 | }
132 | }
133 |
134 | /**
135 | * Returns Observable of mesh array, which are loaded from a file.
136 | * After mesh importing all meshes become given scaling, position and rotation.
137 | * @param fileName
138 | * @param scene
139 | * @param scaling
140 | * @param position
141 | * @param rotationQuaternion
142 | */
143 | public static createMeshFromObjFile(folderName: string, fileName: string, scene: BABYLON.Scene,
144 | scaling?: BABYLON.Vector3, position?: BABYLON.Vector3, rotationQuaternion?: BABYLON.Quaternion): Observable {
145 |
146 | if (!fileName) {
147 | return Observable.throw("GameUtils.createMeshFromObjFile: parameter fileName is empty");
148 | }
149 | if (!scene) {
150 | return Observable.throw("GameUtils.createMeshFromObjFile: parameter scene is empty");
151 | }
152 |
153 | if (!folderName) folderName = "";
154 | if (!scaling) scaling = BABYLON.Vector3.One();
155 | if (!position) position = BABYLON.Vector3.Zero();
156 | if (!rotationQuaternion) rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(0, 0, 0);
157 |
158 | let assetsFolder = './assets/' + folderName;
159 |
160 | return Observable.create(observer => {
161 | BABYLON.SceneLoader.ImportMesh(null, assetsFolder, fileName, scene,
162 | (meshes: BABYLON.AbstractMesh[],
163 | particleSystems: BABYLON.ParticleSystem[],
164 | skeletons: BABYLON.Skeleton[]) => {
165 | meshes.forEach((mesh) => {
166 | mesh.position = position;
167 | mesh.rotationQuaternion = rotationQuaternion;
168 | mesh.scaling = scaling;
169 | });
170 | console.log("Imported Mesh: " + fileName);
171 | observer.next(meshes);
172 | observer.complete();
173 | });
174 | });
175 | }
176 |
177 | /**
178 | * Creates a new skybox with the picttures under fileName.
179 | * @param name
180 | * @param fileName
181 | * @param scene
182 | */
183 | public static createSkybox(name: string, fileName: string, scene: BABYLON.Scene): BABYLON.Mesh {
184 | if (!name) {
185 | console.error("GameUtils.createSkyBox: name is not defined");
186 | return;
187 | }
188 | if (!fileName) {
189 | console.error("GameUtils.createSkyBox: fileName is not defined");
190 | return;
191 | }
192 | if (!scene) {
193 | console.error("GameUtils.createSkyBox: scene is not defined");
194 | return;
195 | }
196 |
197 | // Skybox
198 | let skybox = BABYLON.Mesh.CreateBox(name, 1000.0, scene);
199 | let skyboxMaterial = new BABYLON.StandardMaterial(name, scene);
200 | skyboxMaterial.backFaceCulling = false;
201 | skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("./assets/texture/skybox/TropicalSunnyDay", scene);
202 | skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
203 | skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
204 | skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
205 | skyboxMaterial.disableLighting = true;
206 | skybox.material = skyboxMaterial;
207 | }
208 |
209 | /**
210 | * Creates a new WaterMaterial Object with a given name. The noiseFile descrips the noise in the water,
211 | * @param name
212 | * @param noiseFile
213 | * @param scene
214 | */
215 | public static createWaterMaterial(name: string, noiseFile: string, scene: BABYLON.Scene): MATERIAL.WaterMaterial {
216 | if (!name) {
217 | console.error("GameUtils.createWaterMaterial: name is not defined");
218 | return;
219 | }
220 | if (!noiseFile) {
221 | console.error("GameUtils.createWaterMaterial: noiseFile is not defined");
222 | return;
223 | }
224 | if (!scene) {
225 | console.error("GameUtils.createWaterMaterial: scene is not defined");
226 | return;
227 | }
228 | // Water material
229 | let water = new MATERIAL.WaterMaterial(name, scene);
230 | water.bumpTexture = new BABYLON.Texture(noiseFile, scene);
231 | // Water properties
232 | water.windForce = -15;
233 | water.waveHeight = 0;
234 | water.windDirection = new BABYLON.Vector2(1, 1);
235 | water.waterColor = new BABYLON.Color3(0.25, 0.88, 0.82);
236 | water.colorBlendFactor = 0.3;
237 | water.bumpHeight = 0.1;
238 | water.waveLength = 0.1;
239 |
240 | return water
241 | }
242 |
243 | /**
244 | * Loads a shark model from .obj file and adds it scene.
245 | * @param scene
246 | */
247 | public static createShark(scene: BABYLON.Scene): Observable {
248 | // create a mesh object with loaded from file
249 | let rootMesh = BABYLON.MeshBuilder.CreateBox("rootMesh", {size: 1}, scene);
250 | rootMesh.isVisible = false;
251 | rootMesh.position = new BABYLON.Vector3(0, 0.4, 0);
252 | rootMesh.rotation.y = -3 * Math.PI / 4;
253 |
254 | return GameUtils.createMeshFromObjFile("mesh/", "mesh.obj", scene, new BABYLON.Vector3(1, 1, 1))
255 | .pipe(
256 | map(meshes => {
257 | meshes.forEach((mesh) => {
258 | mesh.parent = rootMesh;
259 | });
260 | return rootMesh;
261 | })
262 | );
263 | }
264 |
265 | }
--------------------------------------------------------------------------------