-
Notifications
You must be signed in to change notification settings - Fork 1
/
pngToGlbUtility.js
132 lines (118 loc) · 4.01 KB
/
pngToGlbUtility.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
var assetDetails = {
baseTexture: "baseImage",
roughnessTexture: "",
normalTexture: "",
tile: [1, 1],
type: "glb"
}
*/
let repeatTexture = false;
async function createGLFTAsset(assetDetails) {
assetDetails.tile == null ? assetDetails.tile = [1, 1] : assetDetails.tile
repeatTexture = assetDetails.tile.some(el => el > 1);
// create GLTF asset, scene and node
const asset = new GLTFUtils.GLTFAsset({ "number": 0, "index": 0 });
const scene = new GLTFUtils.Scene("");
asset.addScene(scene);
const node = new GLTFUtils.Node("PngGlb");
scene.addNode(node);
var vertices = [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0]
let vertex_hash = [];
for (let i = 0; i < vertices.length; i += 5) {
const vertex = new GLTFUtils.Vertex();
var widthTile = assetDetails.tile[0];
var heightTile = assetDetails.tile[1];
vertex.x = vertices[i] * widthTile;
vertex.y = vertices[i + 1] * heightTile;
vertex.z = vertices[i + 2];
vertex.u = vertices[i + 3] * widthTile; // texture co-ord
vertex.v = vertices[i + 4] * heightTile; // texture co-ord
vertex_hash.push(vertex);
}
// create mesh and add faces
var triangles = [0, 1, 2, 2, 3, 0];
const mesh = new GLTFUtils.Mesh();
for (let i = 0; i < triangles.length; i += 3) {
v1 = vertex_hash[triangles[i]];
v2 = vertex_hash[triangles[i + 1]];
v3 = vertex_hash[triangles[i + 2]];
mesh.addFace(v1, v2, v3, { r: 1, g: 1, b: 1 }, 0);
}
// create material
const material = await createMaterial(assetDetails.baseTexture, assetDetails.roughnessTexture, assetDetails.normalTexture);
mesh.material = [material];
node.mesh = mesh;
console.log(asset);
// export asset as GLB or GLTF
if (assetDetails.type == 'gltf') {
exportGltf(asset);
} else {
exportGlb(asset);
}
}
async function createMaterial(baseImage, textureImage, normalImage) {
const material = new GLTFUtils.Material();
// Base texture handling
let baseTexture = "";
try {
baseTexture = new GLTFUtils.Texture(baseImage);
} catch (err) {
console.log(err);
}
let wrapMode = repeatTexture ? GLTFUtils.WrappingMode.REPEAT : GLTFUtils.WrappingMode.CLAMP_TO_EDGE;
baseTexture.wrapS = wrapMode;
baseTexture.wrapT = GLTFUtils.WrappingMode.REPEAT;
material.pbrMetallicRoughness.baseColorTexture = baseTexture;
// Roughness texture handling
let roughnessTexture = "";
if (textureImage != "") {
try {
roughnessTexture = new GLTFUtils.Texture(textureImage);
} catch (err) {
console.log(err);
}
roughnessTexture.wrapS = wrapMode;
roughnessTexture.wrapT = GLTFUtils.WrappingMode.REPEAT;
material.pbrMetallicRoughness.metallicRoughnessTexture = roughnessTexture;
}
// Normal texture handling
let normalTexture = "";
if (normalImage != "") {
try {
normalTexture = new GLTFUtils.Texture(normalImage);
} catch (err) {
console.log(err);
}
normalTexture.wrapS = wrapMode;
normalTexture.wrapT = GLTFUtils.WrappingMode.REPEAT;
material.normalTexture = normalTexture;
}
// other material properties
material.pbrMetallicRoughness.roughnessFactor = 0.5;
material.pbrMetallicRoughness.metallicFactor = 0.5;
material.doubleSided = true;
return material;
}
async function exportGltf(asset) {
let files = await GLTFUtils.exportGLTF(asset, {
bufferOutputType: GLTFUtils.BufferOutputType.DataURI,
imageOutputType: GLTFUtils.BufferOutputType.DataURI
});
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + files['model.gltf']);
element.setAttribute('download', "file.gltf");
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
async function exportGlb(asset) {
let files = await GLTFUtils.exportGLB(asset);
const arrayBuffer = files;
const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'file.glb';
a.click();
}