From e3a29a2945ac7f936d6313cf91508f896ad47e78 Mon Sep 17 00:00:00 2001 From: netpro2k <netpro2k@gmail.com> Date: Fri, 13 Oct 2017 12:57:45 -0700 Subject: [PATCH] Randomize avatar color --- package.json | 1 + .../DodecAvatarGLTF/AvatarDodeca_Texture.png | Bin 20775 -> 5591 bytes public/index.html | 9 +++- src/components/avatar-customization.js | 49 ++++++++++++++++++ src/index.js | 1 + yarn.lock | 4 ++ 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/components/avatar-customization.js diff --git a/package.json b/package.json index 63296bff9..9ff615051 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 GIT binary patch literal 5591 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&zE~RK2WrGmv6S@^*J&_z!{$_AZ|c6yYrJ zh%9Dc;1&j9Muu5)B!GhKC7!;n><_uP8Q2u3`FZ_kU=U65ba4!+xb^ndM&1Jo0xXWn z7Y}duX1uQ}$+_;(q>tyP6g+%&OCmX*!9lawPnp5Na62c^90wqVID;@#0IZe~L=t3z zJVw|=2aqZT;!H%cl17F@Tr&s^NAfChOj2A<oQaS~AtfxpYH4LSB8fC?E)`~Qu$`I7 z!k}@C8I*iTaU{YVf~k(QF!cesgb73_fCz%j2Cym)5J`}!08&NJM2G_7Ol$y~2v(~A zW)kOeQVb`~L?qj3WOxJEe}lkqB(D<3B*o>#nK+t6u%=2<0ve(gt1;MfC@F@M5{qE9 zv@#q|b~&(m7bnAlc^w8!3?h%g#pxgj3=Rf01|XnW=}x@iq*O+9sxgTS7E)YJqkwh* zg)@=P1-CRH8i;c_Qq#mDCOSLU7--dj{goga8$bjDo<xtNKmnu_dsfE~CC<bKh=~oO z&2dmbAd;2?I9!N}T!>nPUL<3%Gf6QVDdiByq?O^MgaueFan6N=5GjU}5YRL=oRokb zO(F~+fF8}GNdyrr0t}<wI8bOH)mtPq?nv)lkYIQNIF^tcMvzG(!@=$tB}QZj9B8*~ WlNK_p-Td@3$p4<MelF{r5}E+9kf?kB literal 20775 zcmeI4UuYaf9LImVw|8tVIozgak~T=U(UNFV?<#_{d2kahnkXb!Db(7U9BMEv5&}Yq z0m)vPYN}$>pm|Z~1rhYY&;}n$ZDGk%O;OXAA{rq`2!%!qc}W5i{O$eOnTd}@jPQNB zVQyx2@4LT0pZU#l=hL0f$D(_qL=@|2PrXEBaMK_&!XG1#G@d20sUy{LY)D)EW%}Vc zC!V?;s}JYeWAP8BTjnV{*L39I>UUR{R(?GG_TXnf9eRJCrW>YZPgD-QJM;DRxk}q{ zNz-3HWm|=o|7E`GUU?1Ox&Lx&et5pe|7t1h)@~aZ))Evwc&puCCz$<?7IL->QWkYu zJWBVScutJs;Wzm*YxSf|HlljOZN2qW@#YGPI^7;kJgZS~3BQrHk`#Ys>Y{vUV~uD3 zRYuBfW=CBuw=nyWGJB#rNy}ZNOg7_21)ZDfeJuFN+{j*cHG4#-k~aBOa(0FqzHNF` z`qhTH9Il|v-6T)e^e~Gt-MgnuR>MwY=;kFNMT`cs22z%u8>Ezs6;>%Z3LIP#1F=#H zz(_li7)U!Jvm=8`g!Qk$(B<mZ`62^;9{%&f`sPDDh5Y5M>D|=SbH$a?8Iw?^BIGuf za($7EGzO*I8@m)xa$U`f$>hX1#(j2rc3fT1qos%fXs+XUWHp>fNzsxAWN09y&a}DD z{G_Q)@*N(Kq^oL&ZE>IRLX}FJjBJa-&hj%%?$Zx^s1h+_Wxw<c{DB7dWhdJd)YS9{ zJ)`2Ip)=4r-`6QPOj_t4Bo6ubK|nrOADkDl&rcah9Y`IVXpwmVF5o_3bAGo0Y{ss` zz@`m*UIs*z3{Wya$-uN8tYFow7Yb~-`hmrdyZg@P%XiKxuiV|x#=Df7SBwjMU%dIa zQsA?n%+UBgcSEVkEikb@Jv=q3RMvjyIvAEL)i@O`yT)EyFTD#;tXe|Xl2X29!Jvv} zk@rV<k{nnRPlER#9E)QqgbjoZRsivG=fumOSME309{qCLsp+fy7UH$vUhGtGb3fze zS8p9va5LAKp}T{L!?InQV_XxNo^3lIAG~H~_?5w5Z!9ZZYE>p_Y`*GKSq|eGb7}wj z<Zcl*9M@^*v*#yH9#hVq??!8IlSS#Eq%bzvq;Oj}j)*M?K~j`PFc+B!8At5xk-Np) zaR3a#U;qpN2I3^*BsO9JM1dy*DKs5C37$kPDA;Ub-yKLnh?9tu|KIIH{F^iH5m|Tq z{{;X51Aqa*K{P{P52OG9OH$wnPwWM77%EbRwbKf!f>CAbm2OznKSlLV9IjzH^pQMW z92`Iv$b#SiFMt=o3;s(l*!pAP3jehsdG^S?)2j_*6*b9>=W3xyp^^Q;sqWa7XdJ$r P@JDsDb*5%oGoyb4Aj~<0 diff --git a/public/index.html b/public/index.html index 3125bcf20..956d5c4c2 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 000000000..8346b8e82 --- /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 e1f40da05..1c226e589 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 f7eeb63a0..5a60e56fe 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" -- GitLab