content/hifi-content/Experiences/Releases/usefulUtilities/avatarScanner/entityResources/entityClientScripts/avatarScannerZoneClient.js
2022-02-13 23:16:46 +01:00

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();
});