Skip to content

Commit

Permalink
Merge pull request #2841 from webaverse/header
Browse files Browse the repository at this point in the history
User icon in header
  • Loading branch information
Avaer Kazmer authored Apr 21, 2022
2 parents 376df93 + 76b07bf commit 65a7654
Show file tree
Hide file tree
Showing 32 changed files with 2,677 additions and 384 deletions.
186 changes: 186 additions & 0 deletions avatar-iconer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import * as THREE from 'three';
import metaversefile from 'metaversefile'
import {emotions} from './src/components/general/character/Emotions';
import {screenshotPlayer} from './avatar-screenshotter.js';
import npcManager from './npc-manager.js';

const allEmotions = [''].concat(emotions);
const cameraOffset = new THREE.Vector3(0, 0.05, -0.35);

class AvatarIconer extends EventTarget {
constructor(player, {
width = 150,
height = 150,
} = {}) {
super();

this.player = player;
this.width = width;
this.height = height;

this.emotionCanvases = [];
this.emotion = '';
this.lastRenderedEmotion = null;

this.enabled = false;

this.canvases = [];

const avatarApp = player.getAvatarApp();
this.renderAvatarApp(avatarApp);

const avatarchange = e => {
this.renderAvatarApp(e.app);
};
player.addEventListener('avatarchange', avatarchange);

const actionupdate = e => {
this.updateEmotionFromActions();
};
player.addEventListener('actionadd', actionupdate);
player.addEventListener('actionremove', actionupdate);

this.cleanup = () => {
player.removeEventListener('avatarchange', avatarchange);
player.removeEventListener('actionadd', actionupdate);
player.removeEventListener('actionremove', actionupdate);
};
}
async renderAvatarApp(srcAvatarApp) {
const lastEnabled = this.enabled;

if (srcAvatarApp) {
const start_url = srcAvatarApp.contentId;
const dstAvatarApp = await metaversefile.createAppAsync({
start_url,
});

const player = npcManager.createNpc({
name: 'avatar-iconer-npc',
avatarApp: dstAvatarApp,
detached: true,
});

const emotionCanvases = await Promise.all(allEmotions.map(async emotion => {
const canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;

await screenshotPlayer({
player,
canvas,
cameraOffset,
emotion,
});

return canvas;
}));
this.emotionCanvases = emotionCanvases;

player.destroy();
dstAvatarApp.destroy();

this.enabled = true;
} else {
this.emotionCanvases.length = 0;
this.enabled = false;
}

this.lastRenderedEmotion = null;

if (lastEnabled !== this.enabled) {
this.dispatchEvent(new MessageEvent('enabledchange', {
data: {
enabled: this.enabled,
},
}));
}
}
addCanvas(canvas) {
canvas.ctx = canvas.getContext('2d');
this.canvases.push(canvas);
}
updateEmotionFromActions() {
const emotion = (() => {
const faceposeAction = this.player.getAction('facepose');
if (faceposeAction) {
return faceposeAction.emotion;
}

const hurtAction = this.player.getAction('hurt');
if (hurtAction) {
return 'sorrow';
}

const useAction = this.player.getAction('use');
if (useAction) {
if (
useAction.animation === 'eat' ||
useAction.animation === 'drink'
) {
return 'joy';
}
if (
useAction.behavior === 'sword' ||
useAction.ik === 'pistol' ||
useAction.ik === 'bow'
) {
return 'angry';
}
}

const jumpAction = this.player.getAction('jump');
if (jumpAction) {
return 'fun';
}

const narutoRunAction = this.player.getAction('narutoRun');
if (narutoRunAction) {
return 'angry';
}

const danceAction = this.player.getAction('dance');
if (danceAction) {
return 'joy';
}

return '';
})();
this.emotion = emotion;
}
update() {
if (this.emotion !== this.lastRenderedEmotion) {
const emotionIndex = allEmotions.indexOf(this.emotion);

if (emotionIndex !== -1) {
const sourceCanvas = this.emotionCanvases[emotionIndex];

if (sourceCanvas) {
for (const dstCanvas of this.canvases) {
const {ctx} = dstCanvas;
ctx.clearRect(0, 0, dstCanvas.width, dstCanvas.height);
ctx.drawImage(
sourceCanvas,
0,
0,
this.width,
this.height,
0,
0,
dstCanvas.width,
dstCanvas.height
);
}
}
}

this.lastRenderedEmotion = this.emotion;
}
}
destroy() {
this.cleanup();
}
}
export {
AvatarIconer,
};
67 changes: 51 additions & 16 deletions avatar-screenshotter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as THREE from 'three';
import metaversefile from './metaversefile-api.js';
import Avatar from './avatars/avatars.js';
// import Avatar from './avatars/avatars.js';
import npcManager from './npc-manager.js';
import dioramaManager from './diorama.js';

Expand All @@ -20,6 +20,9 @@ export const screenshotAvatarUrl = async ({
start_url,
width = 300,
height = 300,
canvas,
cameraOffset,
emotion,
}) => {
const app = await metaversefile.createAppAsync({
start_url,
Expand All @@ -28,27 +31,49 @@ export const screenshotAvatarUrl = async ({
app,
width,
height,
canvas,
cameraOffset,
emotion,
});
};
export const screenshotAvatarApp = async ({
app,
width = 300,
height = 300,
canvas,
cameraOffset,
emotion,
}) => {
await Avatar.waitForLoad();
// await Avatar.waitForLoad();

const position = new THREE.Vector3(0, 1.5, 0);
const quaternion = new THREE.Quaternion();
const scale = new THREE.Vector3(1, 1, 1);
const player = npcManager.createNpc({
name: 'npc',
name: 'sceenshot-npc',
avatarApp: app,
position,
quaternion,
scale,
detached: true,
});

return await screenshotPlayer({
player,
width,
height,
canvas,
cameraOffset,
emotion,
});
};
export const screenshotPlayer = async ({
player,
width = 300,
height = 300,
canvas,
cameraOffset,
emotion,
}) => {
player.position.set(0, 1.5, 0);
player.quaternion.identity();
player.scale.set(1, 1, 1);
player.updateMatrixWorld();

let now = 0;
const timeDiff = 1000/FPS;

Expand All @@ -66,10 +91,13 @@ export const screenshotAvatarApp = async ({
player.avatar.inputs.hmd.position.y = player.avatar.height;
player.avatar.inputs.hmd.quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
player.avatar.inputs.hmd.updateMatrixWorld();
player.addAction({
type: 'facepose',
emotion: 'angry',
});
if (emotion) {
player.clearActions();
player.addAction({
type: 'facepose',
emotion,
});
}
};
const _preAnimate = () => {
for (let i = 0; i < FPS*2; i++) {
Expand All @@ -88,9 +116,14 @@ export const screenshotAvatarApp = async ({
};

// rendering
const writeCanvas = document.createElement('canvas');
writeCanvas.width = width;
writeCanvas.height = height;
let writeCanvas;
if (canvas) {
writeCanvas = canvas;
} else {
writeCanvas = document.createElement('canvas');
writeCanvas.width = width;
writeCanvas.height = height;
}

const localLights = _makeLights();
const objects = localLights.concat([
Expand All @@ -100,6 +133,7 @@ export const screenshotAvatarApp = async ({
const diorama = dioramaManager.createPlayerDiorama({
// target: player,
target,
cameraOffset,
objects,
lights: false,
// label: true,
Expand All @@ -120,6 +154,7 @@ export const screenshotAvatarApp = async ({
_render();

diorama.destroy();
player.destroy();

return writeCanvas;
};
2 changes: 1 addition & 1 deletion avatars/avatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,7 @@ class Avatar {
}
}
if (index !== -1) {
morphTargetInfluences[index] = facepose.value;
morphTargetInfluences[index] = facepose.value ?? 1;
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions blockchain-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as ethers from 'ethers';
// window.ethers = ethers;

const infuraProjectId = '9962763ddd1a453795d5ad09f10bb818';
const infuraProjectSecret = 'c1c6c5227c13423fbba1c977e25352e1';

class BlockchainManager {
constructor() {
// this.provider = ethers.getDefaultProvider();
this.provider = new ethers.providers.InfuraProvider('homestead', {
projectId: infuraProjectId,
// projectSecret: infuraProjectSecret
});
}
async getEnsName(address) {
return await this.provider.lookupAddress(address);
}
async getAvatarUrl(ensName) {
const resolver = await this.provider.getResolver(ensName);
const avatar = await resolver.getAvatar();
if (avatar) {
return avatar.url;
} else {
return null;
}
}
}
const blockchainManager = new BlockchainManager();
export default blockchainManager;
Loading

0 comments on commit 65a7654

Please sign in to comment.