From eb11231e78be040102ab3548b4054fb50617fbb7 Mon Sep 17 00:00:00 2001 From: David Rowe <david@ctrlaltstudio.com> Date: Mon, 23 Dec 2019 09:07:35 +1300 Subject: [PATCH] Graphics API JSDoc --- .../src/graphics-scripting/Forward.h | 60 ++--- .../GraphicsScriptingInterface.cpp | 129 ++++++++- .../GraphicsScriptingInterface.h | 84 ++++-- .../GraphicsScriptingUtil.cpp | 18 ++ .../src/graphics-scripting/ScriptableMesh.cpp | 28 +- .../src/graphics-scripting/ScriptableMesh.h | 173 ++++++++++++- .../graphics-scripting/ScriptableMeshPart.h | 244 ++++++++++++++++-- .../src/graphics-scripting/ScriptableModel.h | 51 +++- .../src/graphics/BufferViewHelpers.cpp | 44 ++++ libraries/graphics/src/graphics/Geometry.h | 17 -- .../graphics/src/graphics/GpuHelpers.cpp | 18 ++ 11 files changed, 751 insertions(+), 115 deletions(-) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index acef5a5bd4..29f8079422 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -36,39 +36,6 @@ namespace scriptable { using ModelProviderPointer = std::shared_ptr<scriptable::ModelProvider>; using WeakModelProviderPointer = std::weak_ptr<scriptable::ModelProvider>; - /**jsdoc - * @typedef {object} Graphics.Material - * @property {string} name - * @property {string} model - * @property {number|string} opacity - * @property {number|string} roughness - * @property {number|string} metallic - * @property {number|string} scattering - * @property {boolean|string} unlit - * @propety {Vec3|string} emissive - * @propety {Vec3|string} albedo - * @property {string} emissiveMap - * @property {string} albedoMap - * @property {string} opacityMap - * @property {string} opacityMapMode - * @property {number|string} opacityCutoff - * @property {string} metallicMap - * @property {string} specularMap - * @property {string} roughnessMap - * @property {string} glossMap - * @property {string} normalMap - * @property {string} bumpMap - * @property {string} occlusionMap - * @property {string} lightMap - * @property {string} scatteringMap - * @property {Mat4|string} texCoordTransform0 - * @property {Mat4|string} texCoordTransform1 - * @property {string} lightmapParams - * @property {string} materialParams - * @property {string} cullFaceMode - * @property {boolean} defaultFallthrough - * @property {string} procedural - */ class ScriptableMaterial { public: ScriptableMaterial() {} @@ -110,9 +77,11 @@ namespace scriptable { }; /**jsdoc + * A material layer. * @typedef {object} Graphics.MaterialLayer - * @property {Graphics.Material} material - This layer's material. - * @property {number} priority - The priority of this layer. If multiple materials are applied to a mesh part, only the highest priority layer is used. + * @property {Graphics.Material} material - The layer's material. + * @property {number} priority - The priority of the layer. If multiple materials are applied to a mesh part, only the + * layer with the highest priority is applied, with materials of the same priority randomly assigned. */ class ScriptableMaterialLayer { public: @@ -138,8 +107,29 @@ namespace scriptable { ScriptableMeshBase(const ScriptableMeshBase& other, QObject* parent = nullptr) : QObject(parent) { *this = other; } ScriptableMeshBase& operator=(const ScriptableMeshBase& view); virtual ~ScriptableMeshBase(); + + /**jsdoc + * @function GraphicsMesh.getMeshPointer + * @deprecated This method is deprecated and will be removed. + * @returns {undefined} + */ + // scriptable::MeshPointer is not registered as a JavaScript type. Q_INVOKABLE const scriptable::MeshPointer getMeshPointer() const { return weakMesh.lock(); } + + /**jsdoc + * @function GraphicsMesh.getModelProviderPointer + * @deprecated This method is deprecated and will be removed. + * @returns {undefined} + */ + // scriptable::ModelProviderPointer is not registered as a JavaScript type. Q_INVOKABLE const scriptable::ModelProviderPointer getModelProviderPointer() const { return provider.lock(); } + + /**jsdoc + * @function GraphicsMesh.getModelBasePointer + * @deprecated This method is deprecated and will be removed. + * @returns {undefined} + */ + // scriptable::ScriptableModelBasePointer is not registered as a JavaScript type. Q_INVOKABLE const scriptable::ScriptableModelBasePointer getModelBasePointer() const { return model; } }; diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index 62614ea6e8..9d36cfd91a 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -168,14 +168,15 @@ scriptable::ScriptableMeshPointer GraphicsScriptingInterface::newMesh(const QVar // in the future we want to support a formal C++ structure data type here instead /**jsdoc + * IFS (Indexed-Face Set) data defining a mesh. * @typedef {object} Graphics.IFSData - * @property {string} [name=""] - mesh name (useful for debugging / debug prints). - * @property {string} [topology=""] - * @property {number[]} indices - vertex indices to use for the mesh faces. - * @property {Vec3[]} vertices - vertex positions (model space) - * @property {Vec3[]} [normals=[]] - vertex normals (normalized) - * @property {Vec3[]} [colors=[]] - vertex colors (normalized) - * @property {Vec2[]} [texCoords0=[]] - vertex texture coordinates (normalized) + * @property {string} [name=""] - Mesh name. (Useful for debugging.) + * @property {Graphics.MeshTopology} topology - Element interpretation. <em>Currently only triangles is supported.</em> + * @property {number[]} indices - Vertex indices to use for the mesh faces, in tuples per the <code>topology</code>. + * @property {Vec3[]} positions - Vertex positions, in model coordinates. + * @property {Vec3[]} [normals=[]] - Vertex normals (normalized). + * @property {Vec3[]} [colors=[]] - Vertex colors (normalized). + * @property {Vec2[]} [texCoords0=[]] - Vertex texture coordinates (normalized). */ QString meshName = ifsMeshData.value("name").toString(); QString topologyName = ifsMeshData.value("topology").toString(); @@ -354,6 +355,120 @@ namespace scriptable { qScriptValueToSequence(array, result); } + /**jsdoc + * A material in a {@link GraphicsModel}. + * @typedef {object} Graphics.Material + * @property {string} name - The name of the material. + * @property {string} model - Different material models support different properties and rendering modes. Supported models + * are: <code>"hifi_pbr"</code> and <code>"hifi_shader_simple"</code>. + * @property {Vec3|string} [albedo] - The albedo color. Component values are in the range <code>0.0</code> – + * <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * @property {number|string} [opacity] - The opacity, range <code>0.0</code> – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * + * @property {number|string} [opacityCutoff] - The opacity cutoff threshold used to determine the opaque texels of the + * <code>opacityMap</code> when <code>opacityMapMode</code> is <code>"OPACITY_MAP_MASK"</code>. Range <code>0.0</code> + * – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {number|string} [roughness] - The roughness, range <code>0.0</code> – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {number|string} [metallic] - The metallicness, range <code>0.0</code> – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {number|string} [scattering] - The scattering, range <code>0.0</code> – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {boolean|string} [unlit] - <code>true</code> if the material is unaffected by lighting, <code>false</code> if it + * it is lit by the key light and local lights. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {Vec3|string} [emissive] - The emissive color, i.e., the color that the material emits. Component values are + * in the range <code>0.0</code> – <code>1.0</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [albedoMap] - The URL of the albedo texture image. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [opacityMap] - The URL of the opacity texture image. + * <code>"hifi_pbr"</code> model only. + * @property {string} [opacityMapMode] - The mode defining the interpretation of the opacity map. Values can be: + * <ul> + * <li><code>"OPACITY_MAP_OPAQUE"</code> for ignoring the opacity map information.</li> + * <li><code>"OPACITY_MAP_MASK"</code> for using the <code>opacityMap</code> as a mask, where only the texel greater + * than <code>opacityCutoff</code> are visible and rendered opaque.</li> + * <li><code>"OPACITY_MAP_BLEND"</code> for using the <code>opacityMap</code> for alpha blending the material surface + * with the background.</li> + * </ul> + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [occlusionMap] - The URL of the occlusion texture image. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [lightMap] - The URL of the light map texture image. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [lightmapParams] - Parameters for controlling how <code>lightMap</code> is used. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * <p><em>Currently not used.</em></p> + * @property {string} [scatteringMap] - The URL of the scattering texture image. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [emissiveMap] - The URL of the emissive texture image. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {string} [metallicMap] - The URL of the metallic texture image. + * If <code>"fallthrough"</code> then it and <code>specularMap</code> fall through to the material below. + * Only use one of <code>metallicMap</code> and <code>specularMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [specularMap] - The URL of the specular texture image. + * Only use one of <code>metallicMap</code> and <code>specularMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [roughnessMap] - The URL of the roughness texture image. + * If <code>"fallthrough"</code> then it and <code>glossMap</code> fall through to the material below. + * Only use one of <code>roughnessMap</code> and <code>glossMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [glossMap] - The URL of the gloss texture image. + * Only use one of <code>roughnessMap</code> and <code>glossMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [normalMa]p - The URL of the normal texture image. + * If <code>"fallthrough"</code> then it and <code>bumpMap</code> fall through to the material below. + * Only use one of <code>normalMap</code> and <code>bumpMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [bumpMap] - The URL of the bump texture image. + * Only use one of <code>normalMap</code> and <code>bumpMap</code>. + * <code>"hifi_pbr"</code> model only. + * @property {string} [materialParams] - Parameters for controlling the material projection and repetition. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * <p><em>Currently not used.</em></p> + * @property {string} [cullFaceMode="CULL_BACK"] - Specifies Which faces of the geometry to render. Values can be: + * <ul> + * <li><code>"CULL_NONE"</code> to render both sides of the geometry.</li> + * <li><code>"CULL_FRONT"</code> to cull the front faces of the geometry.</li> + * <li><code>"CULL_BACK"</code> (the default) to cull the back faces of the geometry.</li> + * </ul> + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {Mat4|string} [texCoordTransform0] - The transform to use for all of the maps apart from + * <code>occlusionMap</code> and <code>lightMap</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * @property {Mat4|string} [texCoordTransform1] - The transform to use for <code>occlusionMap</code> and + * <code>lightMap</code>. + * If <code>"fallthrough"</code> then it falls through to the material below. + * <code>"hifi_pbr"</code> model only. + * + * @property {string} procedural - The definition of a procedural shader material. + * <code>"hifi_shader_simple"</code> model only. + * <p><em>Currently not used.</em></p> + * + * @property {boolean} defaultFallthrough - <code>true</code> if all properties fall through to the material below unless + * they are set, <code>false</code> if properties respect their individual fall-through settings. + */ QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material) { QScriptValue obj = engine->newObject(); obj.setProperty("name", material.name); diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h index c1f3be2b3d..9b56433bf6 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h @@ -23,7 +23,10 @@ /**jsdoc - * The experimental Graphics API <em>(experimental)</em> lets you query and manage certain graphics-related structures (like underlying meshes and textures) from scripting. + * The <code>Graphics</code> API enables you to access and manipulate avatar, entity, and overlay models in the rendered scene. + * This includes getting mesh and material information for applying {@link Entities.EntityProperties-Material|Material} + * entities. + * * @namespace Graphics * * @hifi-interface @@ -40,44 +43,83 @@ public: public slots: /**jsdoc - * Returns a model reference object associated with the specified UUID ({@link EntityID} or {@link AvatarID}). - * + * Gets a handle to the model data used for displaying an avatar, 3D entity, or 3D overlay. + * <p>Note: The model data may be used for more than one instance of the item displayed in the scene.</p> * @function Graphics.getModel - * @param {UUID} entityID - The objectID of the model whose meshes are to be retrieved. - * @returns {Graphics.Model} the resulting Model object + * @param {UUID} id - The ID of the avatar, 3D entity, or 3D overlay. + * @returns {GraphicsModel} The model data for the avatar, entity, or overlay, as displayed. This includes the results of + * applying any {@link Entities.EntityProperties-Material|Material} entities to the item. + * @example <caption>Report some details of your avatar's model.</caption> + * var model = Graphics.getModel(MyAvatar.sessionUUID); + * var meshes = model.meshes; + * var numMeshparts = 0; + * for (var i = 0; i < meshes.length; i++) { + * numMeshparts += meshes[i].numParts; + * } + * + * print("Avatar:", MyAvatar.skeletonModelURL); + * print("Number of meshes:", model.numMeshes); + * print("Number of mesh parts:", numMeshparts); + * print("Material names: ", model.materialNames); + * print("Material layers:", Object.keys(model.materialLayers)); */ scriptable::ScriptableModelPointer getModel(const QUuid& uuid); /**jsdoc + * Updates the model for an avatar, 3D entity, or 3D overlay in the rendered scene. * @function Graphics.updateModel - * @param {Uuid} id - * @param {Graphics.Model} model - * @returns {boolean} + * @param {Uuid} id - The ID of the avatar, 3D entity, or 3D overlay to update. + * @param {GraphicsModel} model - The model to update the avatar, 3D entity, or 3D overlay with. + * @returns {boolean} <code>true</code> if the update was completed successfully, <code>false</code> if it wasn't. */ bool updateModel(const QUuid& uuid, const scriptable::ScriptableModelPointer& model); /**jsdoc + * Checks whether the model for an avatar, entity, or overlay can be updated in the rendered scene. Only avatars, + * <code>"Model"</code> entities and <code>"model"</code> overlays can have their meshes updated. * @function Graphics.canUpdateModel - * @param {Uuid} id - * @param {number} [meshIndex=-1] - * @param {number} [partNumber=-1] - * @returns {boolean} + * @param {Uuid} id - The ID of the avatar, entity, or overlay. + * @param {number} [meshIndex=-1] - <em>Not used.</em> + * @param {number} [partNumber=-1] - <em>Not used.</em> + * @returns {boolean} <code>true</code> if the model can be updated, <code>false</code> if it can't. + * @example <caption>Test whether different types of items can be updated.</caption> + * var modelEntityID = Entities.addEntity({ + * type: "Model", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(Camera.orientation, { x: -0.5, y: 0, z: -3 })), + * rotation: MyAvatar.orientation, + * modelURL: "http://content.highfidelity.com/seefo/production/puck-attach/vive_tracker_puck.obj", + * dimensions: { x: 0.945, y: 0.921, z: 0.423 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * var shapeEntityID = Entities.addEntity({ + * type: "Shape", + * shape: "Cylinder", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(Camera.orientation, { x: 0.5, y: 0, z: -3 })), + * dimensions: { x: 0.4, y: 0.6, z: 0.4 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * print("Can update avatar:", Graphics.canUpdateModel(MyAvatar.sessionUUID)); // true + * print("Can update model entity:", Graphics.canUpdateModel(modelEntityID)); // true + * print("Can update shape entity:", Graphics.canUpdateModel(shapeEntityID)); // false + * }, 1000); // Wait for the entities to rez. */ bool canUpdateModel(const QUuid& uuid, int meshIndex = -1, int partNumber = -1); /**jsdoc + * Creates a new graphics model from meshes. * @function Graphics.newModel - * @param {Graphics.Mesh[]} meshes - * @returns {Graphics.Model} + * @param {GraphicsMesh[]} meshes - The meshes to include in the model. + * @returns {GraphicsModel} The new graphics model. */ scriptable::ScriptableModelPointer newModel(const scriptable::ScriptableMeshes& meshes); /**jsdoc - * Create a new Mesh / Mesh Part with the specified data buffers. - * + * Creates a new graphics mesh. * @function Graphics.newMesh - * @param {Graphics.IFSData} ifsMeshData Index-Faced Set (IFS) arrays used to create the new mesh. - * @returns {Graphics.Mesh} the resulting Mesh / Mesh Part object + * @param {Graphics.IFSData} ifsMeshData - Index-Faced Set (IFS) data defining the mesh. + * @returns {GraphicsMesh} The new graphics mesh. */ scriptable::ScriptableMeshPointer newMesh(const QVariantMap& ifsMeshData); @@ -89,10 +131,12 @@ public slots: #endif /**jsdoc + * Exports a model to OBJ format. * @function Graphics.exportModelToOBJ - * @param {Graphics.Model} model - * @returns {string} + * @param {GraphicsModel} model - The model to export. + * @returns {string} The OBJ format representation of the model. */ + // FIXME: If you put the OBJ on the Asset Server and rez it, Interface keeps crashing until the model is removed. QString exportModelToOBJ(const scriptable::ScriptableModelPointer& model); private: diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingUtil.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingUtil.cpp index da582b2d21..d1f419728a 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingUtil.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingUtil.cpp @@ -37,6 +37,14 @@ QVariant toVariant(const Extents& box) { }; } +/**jsdoc + * The extents of a mesh. + * @typedef {object} Graphics.MeshExtents + * @property {Vec3} brn - The bottom right near (minimum axes values) corner of the enclosing box. + * @property {Vec3} tfl - The top far left (maximum axes values) corner of the enclosing box. + * @property {Vec3} center - The center of the enclosing box. + * @property {Vec3} dimensions - The dimensions of the enclosing box. + */ QVariant toVariant(const AABox& box) { return QVariantMap{ { "brn", glmVecToVariant(box.getCorner()) }, @@ -48,6 +56,16 @@ QVariant toVariant(const AABox& box) { }; } +/**jsdoc + * Details of a buffer element's format. + * @typedef {object} Graphics.BufferElementFormat + * @property {string} type + * @property {string} semantic + * @property {string} dimension + * @property {number} scalarCount + * @property {number} byteSize + * @property {number} BYTES_PER_ELEMENT + */ QVariant toVariant(const gpu::Element& element) { return QVariantMap{ { "type", gpu::toString(element.getType()) }, diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp index 72d2adb48f..5f81e2daf7 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp @@ -127,6 +127,16 @@ int scriptable::ScriptableMesh::getSlotNumber(const QString& attributeName) cons return -1; } +/**jsdoc + * Details of buffer's format. + * @typedef {object} Graphics.BufferFormat + * @property {number} slot + * @property {number} length + * @property {number} byteLength + * @property {number} offset + * @property {number} stride + * @property {Graphics.BufferElementFormat} element + */ QVariantMap scriptable::ScriptableMesh::getBufferFormats() const { QVariantMap result; for (const auto& a : buffer_helpers::ATTRIBUTES.toStdMap()) { @@ -247,6 +257,13 @@ bool scriptable::ScriptableMesh::setVertexProperty(glm::uint32 vertexIndex, cons return buffer_helpers::setValue(bufferView, vertexIndex, value); } +/**jsdoc + * Called for each vertex when {@link GraphicsMesh.updateVertexAttributes} is called. + * @callback GraphicsMesh~forEachVertextCallback + * @param {Object<Graphics.BufferTypeName, Graphics.BufferType>} attributes - The attributes of the vertex. + * @param {number} index - The vertex index. + * @param {object} properties - The properties of the mesh, per {@link GraphicsMesh}. + */ glm::uint32 scriptable::ScriptableMesh::forEachVertex(QScriptValue _callback) { auto mesh = getMeshPointer(); if (!mesh) { @@ -275,7 +292,16 @@ glm::uint32 scriptable::ScriptableMesh::forEachVertex(QScriptValue _callback) { return numProcessed; } - +/**jsdoc + * Called for each vertex when {@link GraphicsMesh.updateVertexAttributes} is called. The value returned by the script function + * should be the modified attributes to update the vertex with, or <code>false</code> to not update the particular vertex. + * @callback GraphicsMesh~updateVertexAttributesCallback + * @param {Object<Graphics.BufferTypeName, Graphics.BufferType>} attributes - The attributes of the vertex. + * @param {number} index - The vertex index. + * @param {object} properties - The properties of the mesh, per {@link GraphicsMesh}. + * @returns {Object<Graphics.BufferTypeName, Graphics.BufferType>|boolean} The attribute values to update the vertex with, or + * <code>false</code> to not update the vertex. + */ glm::uint32 scriptable::ScriptableMesh::updateVertexAttributes(QScriptValue _callback) { auto mesh = getMeshPointer(); if (!mesh) { diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h index dcb1c53759..98f496cd9e 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h @@ -1,4 +1,3 @@ -// // Copyright 2018 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -29,17 +28,40 @@ namespace scriptable { /**jsdoc - * @typedef {object} Graphics.Mesh - * @property {Graphics.MeshPart[]} parts - Array of submesh part references. - * @property {string[]} attributeNames - Vertex attribute names (color, normal, etc.) - * @property {number} numParts - The number of parts contained in the mesh. - * @property {number} numIndices - Total number of vertex indices in the mesh. - * @property {number} numVertices - Total number of vertices in the Mesh. - * @property {number} numAttributes - Number of currently defined vertex attributes. - * @property {boolean} valid - * @property {boolean} strong - * @property {object} extents - * @property {object} bufferFormats + * A handle to in-memory mesh data in a {@link GraphicsModel}. + * + * <p>Created using the {@link Graphics} API, {@link GraphicsModel.cloneModel}, or {@link GraphicsMesh.cloneMesh}.</p> + * + * @class GraphicsMesh + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {number} numParts - The number of mesh parts. + * <em>Read-only.</em> + * @property {GraphicsMeshPart[]} parts - The mesh parts. + * <em>Read-only.</em> + * @property {number} numIndices - The total number of vertex indices in the mesh. + * <em>Read-only.</em> + * @property {number} numVertices - The total number of vertices in the mesh. + * <em>Read-only.</em> + * @property {number} numAttributes - The number of vertex attributes. + * <em>Read-only.</em> + * @property {Graphics.BufferTypeName[]} attributeNames - The names of the vertex attributes. + * <em>Read-only.</em> + * @property {boolean} valid - <code>true</code> if the mesh is valid, <code>false</code> if it isn't. + * <em>Read-only.</em> + * @property {boolean} strong - <code>true</code> if the mesh is valid and able to be used, <code>false</code> if it isn't. + * <em>Read-only.</em> + * @property {Graphics.MeshExtents} extents - The mesh extents, in model coordinates. + * <em>Read-only.</em> + * @property {Object<Graphics.BufferTypeName, Graphics.BufferFormat>} bufferFormats - Details of the buffers used for the + * mesh. + * <em>Read-only.</em> + * + * @borrows GraphicsMesh.getVertextAttributes as getVertextAttributes + * @borrows GraphicsMesh.setVertextAttributes as setVertextAttributes */ class ScriptableMesh : public ScriptableMeshBase, QScriptable { Q_OBJECT @@ -82,26 +104,153 @@ namespace scriptable { int getSlotNumber(const QString& attributeName) const; public slots: + + /**jsdoc + * Gets the model the mesh is part of. + * <p><em>Currently doesn't work.</em></p> + * @function GraphicsMesh.getParentModel + * @returns {GraphicsModel} The model the mesh is part of, <code>null</code> if it isn't part of a model. + */ const scriptable::ScriptableModelPointer getParentModel() const { return qobject_cast<scriptable::ScriptableModel*>(model); } + + /**jsdoc + * Gets the vertex indices. + * @function GraphicsMesh.getIndices + * @returns {number[]} The vertex indices. + */ QVector<glm::uint32> getIndices() const; + + /**jsdoc + * Gets the indices of nearby vertices. + * @function GraphicsMesh.findNearbyVertexIndices + * @param {Vec3} origin - The search position, in model coordinates. + * @param {number} [epsilon=1e-6] - The search distance. If a vertex is within this distance from the + * <code>origin</code> it is considered to be "nearby". + * @returns {number[]} The indices of nearby vertices. + */ QVector<glm::uint32> findNearbyVertexIndices(const glm::vec3& origin, float epsilon = 1e-6) const; + /**jsdoc + * Adds an attribute to the (whole) mesh's vertices. + * @function GraphicsMesh.addAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute. + * @param {Graphics.BufferType} [defaultValue] - The value to give the attributes added to the vertices. + * @returns {number} The number of vertices the attribute was added to, <code>0</code> if the <code>name</code> was + * invalid or all vertices already had the attribute. + */ glm::uint32 addAttribute(const QString& attributeName, const QVariant& defaultValue = QVariant()); + + /**jsdoc + * Sets the value of an attribute for all vertices. + * @function GraphicsMesh.fillAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute. The attribute is added to the vertices if not + * already present. + * @param {Graphics.BufferType} value - The value to give the attributes. + * @returns {number} <code>1</code> if the attribute name was valid and the attribute values were set, <code>0</code> + * otherwise. + */ glm::uint32 fillAttribute(const QString& attributeName, const QVariant& value); + + /**jsdoc + * Removes an attribute from all vertices. + * <p>Note: The <code>"position"</code> attribute cannot be removed.</p> + * @function GraphicsMesh.removeAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute to remove. + * @returns {boolean} <code>true</code> if the attribute existed and was removed, <code>false</code> otherwise. + */ bool removeAttribute(const QString& attributeName); + /**jsdoc + * Gets the value of an attribute for all vertices. + * @function GraphicsMesh.queryVertexAttributes + * @param {Graphics.BufferTypeName} name - The name of the attribute to get the vertex values of. + * @throws Throws an error if the <code>name</code> is invalid or isn't used in the mesh. + * @returns {Graphics.BufferType[]} The attribute values for all vertices. + */ QVariantList queryVertexAttributes(QVariant selector) const; + + /**jsdoc + * Gets the attributes and attribute values of a vertex. + * @function GraphicsMesh.getVertexAttributes + * @param {number} index - The vertex to get the attributes for. + * @returns {Object<Graphics.BufferTypeName,Graphics.BufferType>} The attribute names and values for the vertex. + * @throws Throws an error if the <code>index</code> is invalid. + */ QVariantMap getVertexAttributes(glm::uint32 vertexIndex) const; + + /**jsdoc + * Updates attribute values of a vertex. + * @function GraphicsMesh.setVertexAttributes + * @param {number} index - The vertex to set the attributes for. + * @param {Object<Graphics.BufferTypeNAme,Graphics.BufferType>} values - The attribute names and values. Need not + * specify unchanged values. + * @returns {boolean} <code>true</code> if the index and the attribute names and values were valid and the vertex was + * updated, <code>false</code> otherwise. + * @throws Throws an error if the <code>index</code> is invalid or one of the attribute names is invalid or isn't used + * in the mesh. + */ + // @borrows jsdoc from GraphicsMesh bool setVertexAttributes(glm::uint32 vertexIndex, const QVariantMap& attributeValues); + /**jsdoc + * Gets the value of a vertex's attribute. + * @function GraphicsMesh.getVertexProperty + * @param {number} index - The vertex index. + * @param {Graphics.BufferTypeName} name - The name of the vertex attribute to get. + * @returns {Graphics.BufferType} The value of the vertex attribute. + * @throws Throws an error if the <code>index</code> is invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ QVariant getVertexProperty(glm::uint32 vertexIndex, const QString& attributeName) const; + + /**jsdoc + * Sets the value of a vertex's attribute. + * @function GraphicsMesh.setVertexProperty + * @param {number} index - The vertex index. + * @param {Graphics.BufferTypeName} name - The name of the vertex attribute to set. + * @param {Graphics.BufferType} value - The vertex attribute value to set. + * @returns {boolean} <code>true</code> if the vertex attribute value was set, <code>false</code> if it wasn't. + * @throws Throws an error if the <code>index</code> is invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ bool setVertexProperty(glm::uint32 vertexIndex, const QString& attributeName, const QVariant& value); + /**jsdoc + * Makes a copy of the mesh. + * @function GraphicsMesh.cloneMesh + * @returns {GraphicsMesh} A copy of the mesh. + */ scriptable::ScriptableMeshPointer cloneMesh(); // QScriptEngine-specific wrappers + + /**jsdoc + * Updates vertex attributes by calling a function for each vertex. The function can return modified attributes to + * update the vertex with. + * @function GraphicsMesh.updateVertexAttributes + * @param {GraphicsMesh~updateVertexAttributesCallback} callback - The function to call for each vertex. + * @returns {number} The number of vertices the callback was called for. + */ glm::uint32 updateVertexAttributes(QScriptValue callback); + + /**jsdoc + * Calls a function for each vertex. + * @function GraphicsMesh.forEachVertex + * @param {GraphicsMesh~forEachVertexCallback} callback - The function to call for each vertex. + * @returns {number} The number of vertices the callback was called for. + */ glm::uint32 forEachVertex(QScriptValue callback); + + /**jsdoc + * Checks if an index is valid and, optionally, that vertex has a particular attribute. + * @function GraphicsMesh.isValidIndex + * @param {number} index - The index to check. + * @param {Graphics.BufferTypeName} [attribute] - The attribute to check. + * @returns {boolean} <code>true</code> if the index is valid and that vertex has the attribute if specified. + * @throws Throws an error if the <code>index</code> if invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ + // FIXME: Should return false rather than throw an error. bool isValidIndex(glm::uint32 vertexIndex, const QString& attributeName = QString()) const; }; diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h index 7352fcd0f6..00645145c5 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h @@ -11,23 +11,49 @@ namespace scriptable { /**jsdoc - * @typedef {object} Graphics.MeshPart - * @property {boolean} valid - * @property {number} partIndex - The part index (within the containing Mesh). - * @property {number} firstVertexIndex - * @property {number} baseVertexIndex - * @property {number} lastVertexIndex - * @property {Graphics.Topology} topology - element interpretation (currently only 'triangles' is supported). - * @property {string[]} attributeNames - Vertex attribute names (color, normal, etc.) - * @property {number} numIndices - Number of vertex indices that this mesh part refers to. - * @property {number} numVerticesPerFace - Number of vertices per face (eg: 3 when topology is 'triangles'). - * @property {number} numFaces - Number of faces represented by the mesh part (numIndices / numVerticesPerFace). - * @property {number} numVertices - Total number of vertices in the containing Mesh. - * @property {number} numAttributes - Number of currently defined vertex attributes. - * @property {object} extents - * @property {object} bufferFormats - */ + * A handle to in-memory mesh part data in a {@link GraphicsModel}. + * + * <p>Created using the {@link Graphics} API, {@link GraphicsModel.cloneModel}, {@link GraphicsMesh.cloneMesh}, or + * {@link GraphicsMeshPart.cloneMeshPart}.</p> + * + * @class GraphicsMeshPart + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {boolean} valid - <code>true</code> if the mesh part is valid, <code>false</code> if it isn't. + * <em>Read-only.</em> + * @property {number} partIndex - The index of the part within the <em>whole</em> mesh (i.e., parent and mesh parts). + * <em>Read-only.</em> + * @property {number} firstVertexIndex - The index of the first vertex. + * @property {number} baseVertexIndex - The index of the base vertex. + * @property {number} lastVertexIndex - The index of the last vertex. + * @property {Graphics.MeshTopology} topology - The element interpretation. <em>Currently only triangles is supported.</em> + * @property {number} numIndices - The number of vertex indices in the mesh part. + * @property {number} numVertices - The number of vertices in the <em>whole</em> mesh (i.e., parent and mesh parts). + * <em>Read-only.</em> + * @property {number} numVerticesPerFace - The number of vertices per face, per the <code>topology</code> (e.g., 3 for + * triangles). + * <em>Read-only.</em> + * @property {number} numFaces - The number of faces represented by the mesh part. + * <em>Read-only.</em> + * @property {number} numAttributes - The number of vertex attributes in the <em>whole</em> mesh (i.e., parent and mesh + * parts). + * <em>Read-only.</em> + * @property {Graphics.BufferTypeName[]} attributeNames - The names of the vertex attributes in the <em>whole</em> mesh + * (i.e., parent and mesh parts). + * <em>Read-only.</em> + * @property {Graphics.MeshExtents} extents - The mesh part extents, in model coordinates. + * <em>Read-only.</em> + * @property {Object<Graphics.BufferTypeName, Graphics.BufferFormat>} bufferFormats - Details of the buffers used for the + * <em>whole</em> mesh (i.e., parent and mesh parts). + * <em>Read-only.</em> + * @borrows GraphicsMesh.addAttribute as addAttribute + * @borrows GraphicsMesh.getVertexAttributes as getVertextAttributes + * @borrows GraphicsMesh.setVertexAttributes as setVertextAttributes + */ class ScriptableMeshPart : public QObject, QScriptable { Q_OBJECT Q_PROPERTY(bool valid READ isValid) @@ -55,42 +81,228 @@ namespace scriptable { bool isValid() const { auto mesh = getMeshPointer(); return mesh && partIndex < mesh->getNumParts(); } public slots: + + /**jsdoc + * Gets the vertex indices. + * @function GraphicsMeshPart.getIndices + * @returns {number[]} The vertex indices. + */ QVector<glm::uint32> getIndices() const; + + /**jsdoc + * Sets the vertex indices. + * @function GraphicsMeshPart.setIndices + * @param {number[]} indices - The vertex indices. + * @returns {boolean} <code>true</code> if successful, <code>false</code> if not. + * @throws Throws an error if the number of indices isn't the same, or an index is invalid. + */ bool setIndices(const QVector<glm::uint32>& indices); + + /**jsdoc + * Gets the indices of nearby vertices in the mesh part. + * @function GraphicsMeshPart.findNearbyPartVertexIndices + * @param {Vec3} origin - The search position, in model coordinates. + * @param {number} [epsilon=1e-6] - The search distance. If a vertex is within this distance from the + * <code>origin</code> it is considered to be "nearby". + * @returns {number[]} The indices of nearby vertices. + */ QVector<glm::uint32> findNearbyPartVertexIndices(const glm::vec3& origin, float epsilon = 1e-6) const; + + /**jsdoc + * Gets the value of an attribute for all vertices in the <em>whole</em> mesh (i.e., parent and mesh parts). + * @function GraphicsMeshPArt.queryVertexAttributes + * @param {Graphics.BufferTypeName} name - The name of the attribute to get the vertex values of. + * @throws Throws an error if the <code>name</code> is invalid or isn't used in the mesh. + * @returns {Graphics.BufferType[]} The attribute values for all vertices. + */ QVariantList queryVertexAttributes(QVariant selector) const; + + // @borrows jsdoc from GraphicsMesh. QVariantMap getVertexAttributes(glm::uint32 vertexIndex) const; + + // @borrows jsdoc from GraphicsMesh. bool setVertexAttributes(glm::uint32 vertexIndex, const QVariantMap& attributeValues); + /**jsdoc + * Gets the value of a vertex's attribute. + * @function GraphicsMeshPart.getVertexProperty + * @param {number} index - The vertex index. + * @param {Graphics.BufferTypeName} name - The name of the vertex attribute to get. + * @returns {Graphics.BufferType} The value of the vertex attribute. + * @throws Throws an error if the <code>index</code> is invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ QVariant getVertexProperty(glm::uint32 vertexIndex, const QString& attributeName) const; + + /**jsdoc + * Sets the value of a vertex's attribute. + * @function GraphicsMeshPart.setVertexProperty + * @param {number} index - The vertex index. + * @param {Graphics.BufferTypeName} name - The name of the vertex attribute to set. + * @param {Graphics.BufferType} value - The vertex attribute value to set. + * @returns {boolean} <code>true</code> if the vertex attribute value was set, <code>false</code> if it wasn't. + * @throws Throws an error if the <code>index</code> is invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ bool setVertexProperty(glm::uint32 vertexIndex, const QString& attributeName, const QVariant& attributeValues); + /**jsdoc + * Gets the vertex indices that make up a face. + * @function GraphicsMeshPart.getFace + * @param {number} index - The index of the face. + * @returns {number[]} The vertex indices that make up the face, of number per the mesh <code>topology</code>. + */ QVector<glm::uint32> getFace(glm::uint32 faceIndex) const; + /**jsdoc + * Scales the mesh to so that it's maximum model coordinate dimension is a specified length. + * @function GraphicsMeshPart.scaleToFit + * @param {number} scale - The target dimension. + * @returns {Graphics.MeshExtents} The resulting mesh extents, in model coordinates. + */ QVariantMap scaleToFit(float unitScale); + + /**jsdoc + * Translates the mesh part. + * @function GraphicsMeshPart.translate + * @param {Vec3} translation - The translation to apply, in model coordinates. + * @returns {Graphics.MeshExtents} The rseulting mesh extents, in model coordinates. + */ QVariantMap translate(const glm::vec3& translation); + + /**jsdoc + * Scales the mesh part. + * @function GraphicsMeshPart.scale + * @param {Vec3} scale - The scale to apply in each model coordinate direction. + * @param {Vec3} [origin] - The origin to scale about. If not specified, the center of the mesh part is used. + * @returns {Graphics.MeshExtents} The resulting mesh extents, in model coordinates. + */ QVariantMap scale(const glm::vec3& scale, const glm::vec3& origin = glm::vec3(NAN)); + + /**jsdoc + * Rotates the mesh part, using Euler angles. + * @function GraphicsMeshPart.rotateDegrees + * @param {Vec3} eulerAngles - The rotation to perform, in mesh coordinates, as Euler angles in degrees. + * @param {Vec3} [origin] - The point about which to rotate, in model coordinates. + * <p><strong>Warning:</strong> Currently doesn't work as expected.</p> + * @returns {Graphics.MeshExtents} The resulting mesh extents, in model coordinates. + */ QVariantMap rotateDegrees(const glm::vec3& eulerAngles, const glm::vec3& origin = glm::vec3(NAN)); + + /**jsdoc + * Rotates the mesh part, using a quaternion. + * @function GraphicsMeshPart.rotate + * @param {Quat} rotation - The rotation to perform, in model coordinates. + * @param {Vec3} [origin] - The point about which to rotate, in model coordinates. + * <p><strong>Warning:</strong> Currently doesn't work as expected.</p> + * @returns {Graphics.MeshExtents} The resulting mesh extents, in model coordinates. + */ QVariantMap rotate(const glm::quat& rotation, const glm::vec3& origin = glm::vec3(NAN)); + + /**jsdoc + * Scales, rotates, and translates the mesh. + * @function GraphicsMeshPart.transform + * @param {Mat4} transform - The scale, rotate, and translate transform to apply. + * @returns {Graphics.MeshExtents} The resulting mesh extents, in model coordinates. + */ QVariantMap transform(const glm::mat4& transform); + // @borrows jsdoc from GraphicsMesh. glm::uint32 addAttribute(const QString& attributeName, const QVariant& defaultValue = QVariant()); + + /**jsdoc + * Sets the value of an attribute for all vertices in the <em>whole</em> mesh (i.e., parent and mesh parts). + * @function GraphicsMeshPart.fillAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute. The attribute is added to the vertices if not + * already present. + * @param {Graphics.BufferType} value - The value to give the attributes. + * @returns {number} <code>1</code> if the attribute name was valid and the attribute values were set, <code>0</code> + * otherwise. + */ glm::uint32 fillAttribute(const QString& attributeName, const QVariant& value); + + /**jsdoc + * Removes an attribute from all vertices in the <em>whole</em> mesh (i.e., parent and mesh parts). + * <p>Note: The <code>"position"</code> attribute cannot be removed.</p> + * @function GraphicsMeshPArt.removeAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute to remove. + * @returns {boolean} <code>true</code> if the attribute existed and was removed, <code>false</code> otherwise. + */ bool removeAttribute(const QString& attributeName); + + /**jsdoc + * Deduplicates vertices. + * @function GraphicsMeshPart.dedupeVertices + * @param {number} [epsilon=1e-6] - The deduplicadtion distance. If a pair of vertices is within this distance of each + * other they are combined into a single vertex. + * @returns {boolean} <code>true</code> if the deduplication succeeded, <code>false</code> if it didn't. + */ bool dedupeVertices(float epsilon = 1e-6); + /**jsdoc + * Gets the parent mesh. + * @function GraphicsMeshPart.getParentMesh + * @returns {GraphicsMesh} The parent mesh. + */ scriptable::ScriptableMeshPointer getParentMesh() const { return parentMesh; } + /**jsdoc + * Replaces a mesh part with a copy of another mesh part. + * @function GraphicsMeshPart.replaceMeshPartData + * @param {GrphicsMeshPart} source - The mesh part to copy. + * @param {Graphics.BufferTypeName[]} [attributes] - The attributes to copy. If not specified, all attributes are + * copied from the source. + * @throws Throws an error if the mesh part of source mesh part aren't valid. + * @returns {boolean} <code>true</code> if the mesh part was successfully replaced, <code>false</code> if it wasn't. + */ bool replaceMeshPartData(scriptable::ScriptableMeshPartPointer source, const QVector<QString>& attributeNames = QVector<QString>()); + + /**jsdoc + * Makes a copy of the mesh part. + * @function GraphicsMeshPart.cloneMeshPart + * @returns {GraphicsMeshPart} A copy of the mesh part. + */ scriptable::ScriptableMeshPartPointer cloneMeshPart(); + /**jsdoc + * Exports the mesh part to OBJ format. + * @function GraphicsMeshPart.toOBJ + * @returns {string} The OBJ format representation of the mesh part. + */ QString toOBJ(); + // QScriptEngine-specific wrappers + + /**jsdoc + * Updates vertex attributes by calling a function for each vertex in the <em>whole</em> mesh (i.e., the parent and + * mesh parts). The function can return modified attributes to update the vertex with. + * @function GraphicsMeshPart.updateVertexAttributes + * @param {GraphicsMesh~updateVertexAttributesCallback} callback - The function to call for each vertex. + * @returns {number} The number of vertices the callback was called for. + */ glm::uint32 updateVertexAttributes(QScriptValue callback); + + /**jsdoc + * Calls a function for each vertex in the <em>whole</em> mesh (i.e., parent and mesh parts). + * @function GraphicsMeshPArt.forEachVertex + * @param {GraphicsMesh~forEachVertexCallback} callback - The function to call for each vertex. + * @returns {number} The number of vertices the callback was called for. + */ glm::uint32 forEachVertex(QScriptValue callback); + /**jsdoc + * Checks if an index is valid and, optionally, that vertex has a particular attribute. + * @function GraphicsMeshPart.isValidIndex + * @param {number} index - The index to check. + * @param {Graphics.BufferTypeName} [attribute] - The attribute to check. + * @returns {boolean} <code>true</code> if the index is valid and that vertex has the attribute if specified. + * @throws Throws an error if the <code>index</code> if invalid or <code>name</code> is invalid or isn't used in the + * mesh. + */ + // FIXME: Should return false rather than throw an error. bool isValidIndex(glm::uint32 vertexIndex, const QString& attributeName = QString()) const; + public: scriptable::ScriptableMeshPointer parentMesh; glm::uint32 partIndex; diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h index 7d1ca5f560..faa65f8bf6 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h @@ -17,14 +17,35 @@ namespace scriptable { using ScriptableMeshes = QVector<scriptable::ScriptableMeshPointer>; /**jsdoc - * @typedef {object} Graphics.Model - * @property {Uuid} objectID - UUID of corresponding inworld object (if model is associated) - * @property {number} numMeshes - The number of submeshes contained in the model. - * @property {Graphics.Mesh[]} meshes - Array of submesh references. - * @property {Object.<string,Graphics.MaterialLayer[]>} materialLayers - Map of materials layer lists. You can look up a material layer list by mesh part number or by material name. - * @property {string[]} materialNames - Array of all the material names used by the mesh parts of this model, in order (e.g. materialNames[0] is the name of the first mesh part's material). + * A handle to in-memory model data such as may be used in displaying avatars, 3D entities, or 3D overlays in the rendered + * scene. Changes made to the model are visible only to yourself; they are not persisted. + * <p>Note: The model may be used for more than one instance of an item displayed in the scene. Modifying the model updates + * all instances displayed.</p> + * + * <p>Created using the {@link Graphics} API or {@link GraphicsModel.cloneModel}.</p> + * + * @class GraphicsModel + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {Uuid} objectID - The ID of the entity or avatar that the model is associated with, if any; <code>null</code> + * if the model is not associated with an entity or avatar. + * <em>Read-only.</em> + * @property {number} numMeshes - The number of meshes contained in the model. + * <em>Read-only.</em> + * @property {GraphicsMesh[]} meshes - The meshes in the model. Each mesh may have more than one mesh part. + * <em>Read-only.</em> + * @property {string[]} materialNames - The names of the materials used by each mesh part in the model. The names are in + * the order of the <code>meshes</code> and their mesh parts. + * <em>Read-only.</em> + * @property {Object.<string,Graphics.MaterialLayer[]>} materialLayers - The mapping from mesh parts and material + * names to material layers. The mesh parts are numbered from <code>"0"</code> per the array indexes of + * <code>materialNames</code>. The material names are those used in <code>materialNames</code>. (You can look up a + * material layer by mesh part number or by material name.) + * <em>Read-only.</em> */ - class ScriptableModel : public ScriptableModelBase { Q_OBJECT Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT) @@ -49,7 +70,23 @@ namespace scriptable { QVector<QString> getMaterialNames() { return materialNames; } public slots: + + /**jsdoc + * Makes a copy of the model. + * @function GraphicsModel.cloneModel + * @param {object} [options] - <em>Not used.</em> + * @returns {GraphicsModel} A copy of the model. + */ scriptable::ScriptableModelPointer cloneModel(const QVariantMap& options = QVariantMap()); + + /**jsdoc + * Gets a string description of the model. + * @function GraphicsModel.toString + * @returns {string} A string description of the model. + * @example <caption>Report the string description of your avatar's model.</caption> + * var model = Graphics.getModel(MyAvatar.sessionUUID); + * print("Avatar model info:", model.toString()); + */ QString toString() const; protected: diff --git a/libraries/graphics/src/graphics/BufferViewHelpers.cpp b/libraries/graphics/src/graphics/BufferViewHelpers.cpp index 301f5d8d73..076cb92dcf 100644 --- a/libraries/graphics/src/graphics/BufferViewHelpers.cpp +++ b/libraries/graphics/src/graphics/BufferViewHelpers.cpp @@ -34,6 +34,50 @@ namespace buffer_helpers { const std::array<const char*, 4> XYZW = { { "x", "y", "z", "w" } }; const std::array<const char*, 4> ZERO123 = { { "0", "1", "2", "3" } }; +/**jsdoc + * <p>The type name of a graphics buffer.</p> + * <table> + * <thead> + * <tr><th>Value</th><th>Description</th></tr> + * </thead> + * <tbody> + * <tr><td><code>"position"</code></td><td>Position buffer.</td></tr> + * <tr><td><code>"normal"</code></td><td>normal buffer.</td></tr> + * <tr><td><code>"tangent"</code></td><td>Tangent buffer.</td></tr> + * <tr><td><code>"color"</code></td><td>Color buffer.</td></tr> + * <tr><td><code>"skin_cluster_index"</code></td><td>Skin cluster index buffer.</td></tr> + * <tr><td><code>"skin_cluster_weight"</code></td><td>Skin cluster weight buffer.</td></tr> + * <tr><td><code>"texcoord0"</code></td><td>First UV coordinates buffer.</td></tr> + * <tr><td><code>"texcoord1"</code></td><td>Second UV coordinates buffer.</td></tr> + * <tr><td><code>"texcoord2"</code></td><td>Third UV coordinates buffer.</td></tr> + * <tr><td><code>"texcoord3"</code></td><td>Fourth UV coordinates buffer.</td></tr> + * <tr><td><code>"texcoord4"</code></td><td>Fifth UV coordinates buffer.</td></tr> + * </tbody> + * </table> + * @typedef {string} Graphics.BufferTypeName + */ +/**jsdoc + * <p>The type of a graphics buffer value as accessed by JavaScript.</p> + * <table> + * <thead> + * <tr><th>Type</th><th>Name</th><th>Description</th></tr> + * </thead> + * <tbody> + * <tr><td>{@link Vec3}</td><td><code>"position"</code></td><td>Position buffer.</td></tr> + * <tr><td>{@link Vec3}</td><td><code>"normal"</code></td><td>normal buffer.</td></tr> + * <tr><td>{@link Vec3}</td><td><code>"tangent"</code></td><td>Tangent buffer.</td></tr> + * <tr><td>{@link Vec4}</td><td><code>"color"</code></td><td>Color buffer.</td></tr> + * <tr><td>{@link Vec4}</td><td><code>"skin_cluster_index"</code></td><td>Skin cluster index buffer.</td></tr> + * <tr><td>{@link Vec4}</td><td><code>"skin_cluster_weight"</code></td><td>Skin cluster weight buffer.</td></tr> + * <tr><td>{@link Vec2}</td><td><code>"texcoord0"</code></td><td>First UV coordinates buffer.</td></tr> + * <tr><td>{@link Vec2}</td><td><code>"texcoord1"</code></td><td>Second UV coordinates buffer.</td></tr> + * <tr><td>{@link Vec2}</td><td><code>"texcoord2"</code></td><td>Third UV coordinates buffer.</td></tr> + * <tr><td>{@link Vec2}</td><td><code>"texcoord3"</code></td><td>Fourth UV coordinates buffer.</td></tr> + * <tr><td>{@link Vec2}</td><td><code>"texcoord4"</code></td><td>Fifth UV coordinates buffer.</td></tr> + * </tbody> + * </table> + * @typedef {Vec3|vec2} Graphics.BufferType + */ QMap<QString,int> ATTRIBUTES{ {"position", gpu::Stream::POSITION }, {"normal", gpu::Stream::NORMAL }, diff --git a/libraries/graphics/src/graphics/Geometry.h b/libraries/graphics/src/graphics/Geometry.h index 20018ba71b..fe1981c0e9 100755 --- a/libraries/graphics/src/graphics/Geometry.h +++ b/libraries/graphics/src/graphics/Geometry.h @@ -79,23 +79,6 @@ public: // Access vertex position value const Vec3& getPos(Index index) const { return _vertexBuffer.get<Vec3>(index); } - /**jsdoc - * <table> - * <thead> - * <tr><th>Value</th><th>Description</th></tr> - * </thead> - * <tbody> - * <tr><td><code>0</code></td><td>Points.</td></tr> - * <tr><td><code>1</code></td><td>Lines.</td></tr> - * <tr><td><code>2</code></td><td>Line strip.</td></tr> - * <tr><td><code>3</code></td><td>Triangles.</td></tr> - * <tr><td><code>4</code></td><td>Triangle strip.</td></tr> - * <tr><td><code>5</code></td><td>Quads.</td></tr> - * <tr><td><code>6</code></td><td>Quad strip.</td></tr> - * </tbody> - * </table> - * @typedef {number} Graphics.Topology - */ enum Topology { POINTS = 0, LINES, diff --git a/libraries/graphics/src/graphics/GpuHelpers.cpp b/libraries/graphics/src/graphics/GpuHelpers.cpp index b864b0f040..dd911e33c2 100644 --- a/libraries/graphics/src/graphics/GpuHelpers.cpp +++ b/libraries/graphics/src/graphics/GpuHelpers.cpp @@ -8,6 +8,24 @@ #include "GpuHelpers.h" +/**jsdoc + * <p>The interpretation of mesh elements.</p> + * <table> + * <thead> + * <tr><th>Value</th><th>Description</th></tr> + * </thead> + * <tbody> + * <tr><td><code>"points"</code></td><td>Points.</td></tr> + * <tr><td><code>"lines"</code></td><td>Lines.</td></tr> + * <tr><td><code>"line_strip"</code></td><td>Line strip.</td></tr> + * <tr><td><code>"triangles"</code></td><td>Triangles.</td></tr> + * <tr><td><code>"triangle_strip"</code></td><td>Triangle strip.</td></tr> + * <tr><td><code>"quads"</code></td><td>Quads.</td></tr> + * <tr><td><code>"quad_strip"</code></td><td>Quad strip.</td></tr> + * </tbody> + * </table> + * @typedef {string} Graphics.MeshTopology + */ namespace graphics { DebugEnums<Mesh::Topology> TOPOLOGIES{ { Mesh::Topology::POINTS, "points" },