diff --git a/package.json b/package.json index 63296bff9d3db05f684c3305fb106b30bf770dcc..9ff615051caf0a14600e83c5fc8faaa8dce4769a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "easyrtc": "^1.1.0", "express": "^4.15.5", "networked-aframe": "https://github.com/netpro2k/networked-aframe#dev", + "pleasejs": "^0.4.2", "socket.io": "^2.0.3" }, "devDependencies": { diff --git a/public/assets/avatars/dodec/DodecAvatarGLTF/AvatarDodeca_Texture.png b/public/assets/avatars/dodec/DodecAvatarGLTF/AvatarDodeca_Texture.png index d0f89bc1497e8bc97c7c035abde9705e1316b613..3f7585fbd2ec32b717296daedb765cad19b9daa7 100644 Binary files a/public/assets/avatars/dodec/DodecAvatarGLTF/AvatarDodeca_Texture.png and b/public/assets/avatars/dodec/DodecAvatarGLTF/AvatarDodeca_Texture.png differ diff --git a/public/index.html b/public/index.html index 3125bcf20e2c8b88ba8cb019d4f982f16c6da954..956d5c4c2b1a76e02aafddaf1a6d93088fd5e5fc 100644 --- a/public/index.html +++ b/public/index.html @@ -26,7 +26,14 @@ <!-- Templates --> <script id="head-template" type="text/html"> - <a-entity class="head" gltf-model="#dodec-avatar-head" position="0 0 0" networked-audio-source audio-feedback></a-entity> + <a-entity + class="head" + gltf-model="#dodec-avatar-head" + position="0 0 0" + networked-audio-source + audio-feedback + avatar-customization + ></a-entity> </script> <script id="hand-template" type="text/html"> diff --git a/src/components/avatar-customization.js b/src/components/avatar-customization.js new file mode 100644 index 0000000000000000000000000000000000000000..8346b8e821ac904d8711dffe6563643f7628ba09 --- /dev/null +++ b/src/components/avatar-customization.js @@ -0,0 +1,49 @@ +import Please from "pleasejs"; + +// @TODO this whole thing is a bit of a hack. This should probably just be setting some uniforms on a sharder. +// @TODO the palate should be indexed by alpha channel instead of the red channel. +// @TODO color should be multiplied with the texture value to allow for texture to provide surface detail. +// @TODO texture should be regenerated whenever headColor/LidColor values change to allow for networking, though arguably these will eventually be fetched from a users "profile" anywya, so might not be worth trying to network through NAF. +AFRAME.registerComponent("avatar-customization", { + schema: { + headColor: { type: "color", default: null }, + lidColor: { type: "color", default: null } + }, + + init: function() { + const colors = Please.make_color({ + format: "rgb-string", + colors_returned: 2 + }); + + this.colorMap = new Map(); + this.colorMap.set(128, this.data.headColor || new THREE.Color(colors[0])); + this.colorMap.set(115, this.data.lidColor || new THREE.Color(colors[1])); + + this.el.addEventListener("model-loaded", () => { + const map = this.el.object3D.getObjectByName("DodecAvatar_Head_0") + .material.map; + const img = map.image; + + const canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0, img.width, img.height); + const imageData = ctx.getImageData(0, 0, img.width, img.height); + const pixelData = imageData.data; + + for (let i = 0; i < pixelData.length; i += 4) { + // @TODO check alpha channel and multiply colors to preserver surface detail + if (this.colorMap.has(pixelData[i])) { + const color = this.colorMap.get(pixelData[i]); + pixelData[i] = color.r * 255; + pixelData[i + 1] = color.g * 255; + pixelData[i + 2] = color.b * 255; + } + } + ctx.putImageData(imageData, 0, 0); + map.image = canvas; + }); + } +}); diff --git a/src/index.js b/src/index.js index e1f40da052dd2b4d1952513e8fefbdc9a9c1065e..1c226e589b3834306ff95f6863abe2dc1065365d 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import "./components/snap-rotation"; import "./components/mute-mic"; import "./components/audio-feedback"; import "./components/nametag-transform"; +import "./components/avatar-customization"; import { generateName } from "./utils"; diff --git a/yarn.lock b/yarn.lock index f7eeb63a0b1fa7ef544bb06a86574af7ea0904bf..5a60e56feafd47abeaacb4bbe63c2799df114c51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2090,6 +2090,10 @@ pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pleasejs@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/pleasejs/-/pleasejs-0.4.2.tgz#aaaa1a5fa6902518de7e51e3c63b5f537f823164" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"