221 lines
10 KiB
JavaScript
221 lines
10 KiB
JavaScript
//
|
|
// avatarScannerZoneClient.js
|
|
//
|
|
// created by Rebecca Stankus on 03/1/19
|
|
// Copyright 2019 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function() {
|
|
var _this;
|
|
|
|
/* TEXT ENTITIES WILL BE IN THIS ORDER:
|
|
0-OVERALL SCORE
|
|
1-NUMBER OF MATERIALS
|
|
2-SIZE OF MATERIALS TEXTURES IN PIXELS
|
|
3-NUMBER OF MATERIALS TEXTURES
|
|
4-NUMBER OF TRIANGLES
|
|
5-MATERIAL ENTITIES
|
|
6-WEARABLES
|
|
7-NUMBER OF PARTS
|
|
8-FLOW JOINTS
|
|
9-BLENDSHAPES
|
|
10-SKINNING JOINTS
|
|
*/
|
|
|
|
var TEXT_NUMBER_INDEX = 24;
|
|
var AVATAR_COPY_Y_OFFSET_M = 0.7;
|
|
var SEARCH_RADIUS_M = 20;
|
|
var MIN_COPY_HEIGHT_M = 0.7;
|
|
var NINETY_PERCENT = 0.9;
|
|
var WAIT_TO_GET_DATA_MS = 200;
|
|
var WAIT_TO_DISPLAY_SCORES_MS = 1000;
|
|
var scannerZoneMarker;
|
|
var textEntityIDs = [];
|
|
var textToShow = [];
|
|
var avatarCopy;
|
|
var avatarCopyShelf;
|
|
var wearables = [];
|
|
var materialEntities = [];
|
|
var graphicsModel;
|
|
var flowJointNames = [];
|
|
var numberSkinningJoints = [];
|
|
|
|
var AvatarScannerZone = function() {
|
|
_this = this;
|
|
};
|
|
|
|
AvatarScannerZone.prototype = {
|
|
|
|
/* ON PRELOAD: Save a reference to this */
|
|
preload: function(entityID) {
|
|
_this.entityID = entityID;
|
|
scannerZoneMarker = Entities.getEntityProperties(_this.entityID, 'parentID').parentID;
|
|
},
|
|
|
|
/* ENTER ENTITY: Upon entering this zone */
|
|
enterEntity: function() {
|
|
Entities.getChildrenIDs(scannerZoneMarker).forEach(function(childOfZoneMarker) {
|
|
var name = Entities.getEntityProperties(childOfZoneMarker, 'name').name;
|
|
if (name.indexOf("FeedBack") !== -1) {
|
|
var indexNumber = +name.substr(TEXT_NUMBER_INDEX);
|
|
textEntityIDs[indexNumber] = childOfZoneMarker;
|
|
} else if (name.indexOf("Shelf") !== -1) {
|
|
avatarCopyShelf = childOfZoneMarker;
|
|
}
|
|
});
|
|
MyAvatar.useFlow(true,true);
|
|
_this.showAvatarData();
|
|
// play sound
|
|
// light on
|
|
},
|
|
|
|
/* LEAVE ENTITY: Upon leaving this zone */
|
|
leaveEntity: function() {
|
|
for ( var i = 0; i < textEntityIDs.length; i++) {
|
|
Entities.editEntity(textEntityIDs[i], {
|
|
visible: false,
|
|
text: ""
|
|
});
|
|
}
|
|
var scannerPosition = Entities.getEntityProperties(_this.entityID, 'position').position;
|
|
Entities.findEntities(scannerPosition, SEARCH_RADIUS_M).forEach(function(entity) {
|
|
var name = Entities.getEntityProperties(entity, 'name').name;
|
|
if (name === "Avatar Scanner Copy") {
|
|
Entities.deleteEntity(entity);
|
|
}
|
|
});
|
|
// light off
|
|
},
|
|
|
|
/* Get all avatar entities and separate wearables from materials */
|
|
separateAvatarEntities: function() {
|
|
wearables = [];
|
|
materialEntities = [];
|
|
var entityAttachments = MyAvatar.getAvatarEntitiesVariant();
|
|
entityAttachments.forEach(function(avatarEntity) {
|
|
if (avatarEntity.properties.type === "Material") {
|
|
materialEntities.push(avatarEntity);
|
|
} else {
|
|
wearables.push(avatarEntity);
|
|
}
|
|
});
|
|
},
|
|
|
|
/* Get number of avtar parts */
|
|
getPartsCount: function() {
|
|
var partsCount = 0;
|
|
graphicsModel.meshes.forEach(function(mesh) {
|
|
partsCount += mesh.numParts;
|
|
});
|
|
return partsCount;
|
|
},
|
|
|
|
/* Return number of triangles */
|
|
getNumberTriangles: function() {
|
|
var trianglesCount = 0;
|
|
graphicsModel.meshes.forEach(function(mesh) {
|
|
var parts = mesh.parts;
|
|
parts.forEach(function(part) {
|
|
trianglesCount += part.numFaces;
|
|
});
|
|
});
|
|
return trianglesCount;
|
|
},
|
|
|
|
/* Create miniature copy of avatar and a graphics model copy. */
|
|
showAvatarData: function() {
|
|
var avatarScore, avatarMaterialsScore, avatarMaterialsSize, avatarMaterialsSizeScore,
|
|
textures, texturesScore, wearablesScore, materialEntitiesScore, parts, partsScore, triangles,
|
|
trianglesScore, numberflowJoints, flowJointsScore, blendShapesScore, skinningJointsScore;
|
|
var blendShapes = [];
|
|
var avatarMaterials = [];
|
|
var renderInfo;
|
|
// Entities.findEntities(MyAvatar.position, 1000).forEach(function(entity) {
|
|
// var parentID =
|
|
// });
|
|
var spawnPosition = Entities.getEntityProperties(avatarCopyShelf, 'position').position;
|
|
spawnPosition.y += AVATAR_COPY_Y_OFFSET_M;
|
|
var numberAvatarMaterials;
|
|
avatarCopy = Entities.addEntity({
|
|
type: 'Model',
|
|
name: "Avatar Scanner Copy",
|
|
modelURL: MyAvatar.skeletonModelURL,
|
|
position: spawnPosition,
|
|
lifetime: 300, // backup just in case
|
|
grab: { grabbable: false },
|
|
parentID: scannerZoneMarker,
|
|
visible: false
|
|
}, 'avatarEntity');
|
|
Script.setTimeout(function() { // Natural dimensions are not available immediately
|
|
var dimensions = Entities.getEntityProperties(avatarCopy, 'naturalDimensions').naturalDimensions;
|
|
while (dimensions.y > MIN_COPY_HEIGHT_M) {
|
|
dimensions = Vec3.multiply(dimensions, NINETY_PERCENT);
|
|
Entities.editEntity(avatarCopy, {
|
|
visible: true,
|
|
dimensions: dimensions
|
|
});
|
|
renderInfo = Entities.getEntityProperties(avatarCopy, 'renderInfo').renderInfo;
|
|
}
|
|
graphicsModel = Graphics.getModel(MyAvatar.sessionUUID);
|
|
parts = _this.getPartsCount();
|
|
avatarMaterials = graphicsModel.materialLayers["mat::Bodymat"];
|
|
triangles = _this.getNumberTriangles();
|
|
numberAvatarMaterials = avatarMaterials ? avatarMaterials.length : 0;
|
|
_this.separateAvatarEntities();
|
|
flowJointNames = Object.keys(MyAvatar.getFlowData().threads);
|
|
print(Object.keys(MyAvatar.getFlowData().threads));
|
|
numberflowJoints = flowJointNames ? flowJointNames.length : 0;
|
|
var skinningJoints = MyAvatar.getJointNames();
|
|
if (skinningJoints) {
|
|
flowJointNames.forEach(function(flowJointName) {
|
|
var flowJointIndex = skinningJoints.indexOf(flowJointName);
|
|
if (flowJointIndex > -1) {
|
|
skinningJoints.splice(flowJointIndex, 1);
|
|
}
|
|
});
|
|
}
|
|
numberSkinningJoints = skinningJoints ? skinningJoints.length : 0;
|
|
}, WAIT_TO_GET_DATA_MS); // render info and natural dimensions are not immediately available
|
|
Script.setTimeout(function() {
|
|
textToShow[0] = JSON.stringify("Hello " + MyAvatar.displayName + " Your overall avatar score is " +
|
|
avatarScore);
|
|
textToShow[1] = JSON.stringify("Your avatar has " + numberAvatarMaterials +
|
|
" avatar materials. Your avatar materials score is " + avatarMaterialsScore);
|
|
// textToShow[2] = JSON.stringify("The size of all of your avatar materials is " + avatarMaterialsSize +
|
|
// " pixels. Your avatar materials size score is " + avatarMaterialsSizeScore);
|
|
textToShow[3] = JSON.stringify("Your avatar has " + renderInfo.texturesCount +
|
|
" textures. Your textures score is " + texturesScore);
|
|
textToShow[4] = JSON.stringify("Your avatar has " + triangles + " triangles. Your triangles score is " +
|
|
trianglesScore);
|
|
textToShow[5] = JSON.stringify("Your avatar has " + materialEntities.length + " material entities. Your " +
|
|
"total material entities score is " + materialEntitiesScore);
|
|
textToShow[6] = JSON.stringify("Your avatar has " + wearables.length + " wearables. Your total wearables " +
|
|
"score is " + wearablesScore);
|
|
textToShow[7] = JSON.stringify("Your avatar has " + parts + " parts. Your parts score is " +
|
|
partsScore);
|
|
textToShow[8] = JSON.stringify("Your avatar has " + numberflowJoints +
|
|
" flow joints. Your flow joints score is " + flowJointsScore);
|
|
// textToShow[9] = JSON.stringify("Your avatar has " + blendShapes.length + " blend shapes. Your blend " +
|
|
// "shapes score is " + blendShapesScore);
|
|
textToShow[10] = JSON.stringify("Your avatar has " + numberSkinningJoints + " skinning joints. Your " +
|
|
"skinning joints score is " + skinningJointsScore);
|
|
for ( var i = 0; i < textEntityIDs.length; i++) {
|
|
Entities.editEntity(textEntityIDs[i], {
|
|
text:textToShow[i],
|
|
visible: true
|
|
});
|
|
}
|
|
}, WAIT_TO_DISPLAY_SCORES_MS); // allows time for all values to be calculated
|
|
|
|
},
|
|
|
|
/* ON UNLOADING THE SCRIPT: Make sure the avatar leaves the zone so extra entities are deleted and intervals ended */
|
|
unload: function(){
|
|
_this.leaveEntity();
|
|
}
|
|
};
|
|
return new AvatarScannerZone();
|
|
});
|