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; using WeakModelProviderPointer = std::weak_ptr; - /**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. Currently only triangles is supported. + * @property {number[]} indices - Vertex indices to use for the mesh faces, in tuples per the topology. + * @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: "hifi_pbr" and "hifi_shader_simple". + * @property {Vec3|string} [albedo] - The albedo color. Component values are in the range 0.0 – + * 1.0. + * If "fallthrough" then it falls through to the material below. + * @property {number|string} [opacity] - The opacity, range 0.01.0. + * If "fallthrough" then it falls through to the material below. + * + * @property {number|string} [opacityCutoff] - The opacity cutoff threshold used to determine the opaque texels of the + * opacityMap when opacityMapMode is "OPACITY_MAP_MASK". Range 0.0 + * – 1.0. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {number|string} [roughness] - The roughness, range 0.01.0. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {number|string} [metallic] - The metallicness, range 0.01.0. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {number|string} [scattering] - The scattering, range 0.01.0. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {boolean|string} [unlit] - true if the material is unaffected by lighting, false if it + * it is lit by the key light and local lights. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {Vec3|string} [emissive] - The emissive color, i.e., the color that the material emits. Component values are + * in the range 0.01.0. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [albedoMap] - The URL of the albedo texture image. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [opacityMap] - The URL of the opacity texture image. + * "hifi_pbr" model only. + * @property {string} [opacityMapMode] - The mode defining the interpretation of the opacity map. Values can be: + * + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [occlusionMap] - The URL of the occlusion texture image. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [lightMap] - The URL of the light map texture image. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [lightmapParams] - Parameters for controlling how lightMap is used. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + *

Currently not used.

+ * @property {string} [scatteringMap] - The URL of the scattering texture image. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [emissiveMap] - The URL of the emissive texture image. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {string} [metallicMap] - The URL of the metallic texture image. + * If "fallthrough" then it and specularMap fall through to the material below. + * Only use one of metallicMap and specularMap. + * "hifi_pbr" model only. + * @property {string} [specularMap] - The URL of the specular texture image. + * Only use one of metallicMap and specularMap. + * "hifi_pbr" model only. + * @property {string} [roughnessMap] - The URL of the roughness texture image. + * If "fallthrough" then it and glossMap fall through to the material below. + * Only use one of roughnessMap and glossMap. + * "hifi_pbr" model only. + * @property {string} [glossMap] - The URL of the gloss texture image. + * Only use one of roughnessMap and glossMap. + * "hifi_pbr" model only. + * @property {string} [normalMa]p - The URL of the normal texture image. + * If "fallthrough" then it and bumpMap fall through to the material below. + * Only use one of normalMap and bumpMap. + * "hifi_pbr" model only. + * @property {string} [bumpMap] - The URL of the bump texture image. + * Only use one of normalMap and bumpMap. + * "hifi_pbr" model only. + * @property {string} [materialParams] - Parameters for controlling the material projection and repetition. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + *

Currently not used.

+ * @property {string} [cullFaceMode="CULL_BACK"] - Specifies Which faces of the geometry to render. Values can be: + * + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {Mat4|string} [texCoordTransform0] - The transform to use for all of the maps apart from + * occlusionMap and lightMap. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * @property {Mat4|string} [texCoordTransform1] - The transform to use for occlusionMap and + * lightMap. + * If "fallthrough" then it falls through to the material below. + * "hifi_pbr" model only. + * + * @property {string} procedural - The definition of a procedural shader material. + * "hifi_shader_simple" model only. + *

Currently not used.

+ * + * @property {boolean} defaultFallthrough - true if all properties fall through to the material below unless + * they are set, false 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 (experimental) lets you query and manage certain graphics-related structures (like underlying meshes and textures) from scripting. + * The Graphics 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. + *

Note: The model data may be used for more than one instance of the item displayed in the scene.

* @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 Report some details of your avatar's model. + * 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} true if the update was completed successfully, false 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, + * "Model" entities and "model" 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] - Not used. + * @param {number} [partNumber=-1] - Not used. + * @returns {boolean} true if the model can be updated, false if it can't. + * @example Test whether different types of items can be updated. + * 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} 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 false to not update the particular vertex. + * @callback GraphicsMesh~updateVertexAttributesCallback + * @param {Object} 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|boolean} The attribute values to update the vertex with, or + * false 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}. + * + *

Created using the {@link Graphics} API, {@link GraphicsModel.cloneModel}, or {@link GraphicsMesh.cloneMesh}.

+ * + * @class GraphicsMesh + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {number} numParts - The number of mesh parts. + * Read-only. + * @property {GraphicsMeshPart[]} parts - The mesh parts. + * Read-only. + * @property {number} numIndices - The total number of vertex indices in the mesh. + * Read-only. + * @property {number} numVertices - The total number of vertices in the mesh. + * Read-only. + * @property {number} numAttributes - The number of vertex attributes. + * Read-only. + * @property {Graphics.BufferTypeName[]} attributeNames - The names of the vertex attributes. + * Read-only. + * @property {boolean} valid - true if the mesh is valid, false if it isn't. + * Read-only. + * @property {boolean} strong - true if the mesh is valid and able to be used, false if it isn't. + * Read-only. + * @property {Graphics.MeshExtents} extents - The mesh extents, in model coordinates. + * Read-only. + * @property {Object} bufferFormats - Details of the buffers used for the + * mesh. + * Read-only. + * + * @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. + *

Currently doesn't work.

+ * @function GraphicsMesh.getParentModel + * @returns {GraphicsModel} The model the mesh is part of, null if it isn't part of a model. + */ const scriptable::ScriptableModelPointer getParentModel() const { return qobject_cast(model); } + + /**jsdoc + * Gets the vertex indices. + * @function GraphicsMesh.getIndices + * @returns {number[]} The vertex indices. + */ QVector 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 + * origin it is considered to be "nearby". + * @returns {number[]} The indices of nearby vertices. + */ QVector 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, 0 if the name 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} 1 if the attribute name was valid and the attribute values were set, 0 + * otherwise. + */ glm::uint32 fillAttribute(const QString& attributeName, const QVariant& value); + + /**jsdoc + * Removes an attribute from all vertices. + *

Note: The "position" attribute cannot be removed.

+ * @function GraphicsMesh.removeAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute to remove. + * @returns {boolean} true if the attribute existed and was removed, false 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 name 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} The attribute names and values for the vertex. + * @throws Throws an error if the index 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} values - The attribute names and values. Need not + * specify unchanged values. + * @returns {boolean} true if the index and the attribute names and values were valid and the vertex was + * updated, false otherwise. + * @throws Throws an error if the index 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 index is invalid or name 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} true if the vertex attribute value was set, false if it wasn't. + * @throws Throws an error if the index is invalid or name 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} true if the index is valid and that vertex has the attribute if specified. + * @throws Throws an error if the index if invalid or name 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}. + * + *

Created using the {@link Graphics} API, {@link GraphicsModel.cloneModel}, {@link GraphicsMesh.cloneMesh}, or + * {@link GraphicsMeshPart.cloneMeshPart}.

+ * + * @class GraphicsMeshPart + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {boolean} valid - true if the mesh part is valid, false if it isn't. + * Read-only. + * @property {number} partIndex - The index of the part within the whole mesh (i.e., parent and mesh parts). + * Read-only. + * @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. Currently only triangles is supported. + * @property {number} numIndices - The number of vertex indices in the mesh part. + * @property {number} numVertices - The number of vertices in the whole mesh (i.e., parent and mesh parts). + * Read-only. + * @property {number} numVerticesPerFace - The number of vertices per face, per the topology (e.g., 3 for + * triangles). + * Read-only. + * @property {number} numFaces - The number of faces represented by the mesh part. + * Read-only. + * @property {number} numAttributes - The number of vertex attributes in the whole mesh (i.e., parent and mesh + * parts). + * Read-only. + * @property {Graphics.BufferTypeName[]} attributeNames - The names of the vertex attributes in the whole mesh + * (i.e., parent and mesh parts). + * Read-only. + * @property {Graphics.MeshExtents} extents - The mesh part extents, in model coordinates. + * Read-only. + * @property {Object} bufferFormats - Details of the buffers used for the + * whole mesh (i.e., parent and mesh parts). + * Read-only. + * @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 getIndices() const; + + /**jsdoc + * Sets the vertex indices. + * @function GraphicsMeshPart.setIndices + * @param {number[]} indices - The vertex indices. + * @returns {boolean} true if successful, false if not. + * @throws Throws an error if the number of indices isn't the same, or an index is invalid. + */ bool setIndices(const QVector& 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 + * origin it is considered to be "nearby". + * @returns {number[]} The indices of nearby vertices. + */ QVector findNearbyPartVertexIndices(const glm::vec3& origin, float epsilon = 1e-6) const; + + /**jsdoc + * Gets the value of an attribute for all vertices in the whole 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 name 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 index is invalid or name 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} true if the vertex attribute value was set, false if it wasn't. + * @throws Throws an error if the index is invalid or name 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 topology. + */ QVector 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. + *

Warning: Currently doesn't work as expected.

+ * @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. + *

Warning: Currently doesn't work as expected.

+ * @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 whole 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} 1 if the attribute name was valid and the attribute values were set, 0 + * otherwise. + */ glm::uint32 fillAttribute(const QString& attributeName, const QVariant& value); + + /**jsdoc + * Removes an attribute from all vertices in the whole mesh (i.e., parent and mesh parts). + *

Note: The "position" attribute cannot be removed.

+ * @function GraphicsMeshPArt.removeAttribute + * @param {Graphics.BufferTypeName} name - The name of the attribute to remove. + * @returns {boolean} true if the attribute existed and was removed, false 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} true if the deduplication succeeded, false 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} true if the mesh part was successfully replaced, false if it wasn't. + */ bool replaceMeshPartData(scriptable::ScriptableMeshPartPointer source, const QVector& attributeNames = QVector()); + + /**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 whole 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 whole 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} true if the index is valid and that vertex has the attribute if specified. + * @throws Throws an error if the index if invalid or name 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; /**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.} 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. + *

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.

+ * + *

Created using the {@link Graphics} API or {@link GraphicsModel.cloneModel}.

+ * + * @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; null + * if the model is not associated with an entity or avatar. + * Read-only. + * @property {number} numMeshes - The number of meshes contained in the model. + * Read-only. + * @property {GraphicsMesh[]} meshes - The meshes in the model. Each mesh may have more than one mesh part. + * Read-only. + * @property {string[]} materialNames - The names of the materials used by each mesh part in the model. The names are in + * the order of the meshes and their mesh parts. + * Read-only. + * @property {Object.} materialLayers - The mapping from mesh parts and material + * names to material layers. The mesh parts are numbered from "0" per the array indexes of + * materialNames. The material names are those used in materialNames. (You can look up a + * material layer by mesh part number or by material name.) + * Read-only. */ - class ScriptableModel : public ScriptableModelBase { Q_OBJECT Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT) @@ -49,7 +70,23 @@ namespace scriptable { QVector getMaterialNames() { return materialNames; } public slots: + + /**jsdoc + * Makes a copy of the model. + * @function GraphicsModel.cloneModel + * @param {object} [options] - Not used. + * @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 Report the string description of your avatar's model. + * 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 XYZW = { { "x", "y", "z", "w" } }; const std::array ZERO123 = { { "0", "1", "2", "3" } }; +/**jsdoc + *

The type name of a graphics buffer.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDescription
"position"Position buffer.
"normal"normal buffer.
"tangent"Tangent buffer.
"color"Color buffer.
"skin_cluster_index"Skin cluster index buffer.
"skin_cluster_weight"Skin cluster weight buffer.
"texcoord0"First UV coordinates buffer.
"texcoord1"Second UV coordinates buffer.
"texcoord2"Third UV coordinates buffer.
"texcoord3"Fourth UV coordinates buffer.
"texcoord4"Fifth UV coordinates buffer.
+ * @typedef {string} Graphics.BufferTypeName + */ +/**jsdoc + *

The type of a graphics buffer value as accessed by JavaScript.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
TypeNameDescription
{@link Vec3}"position"Position buffer.
{@link Vec3}"normal"normal buffer.
{@link Vec3}"tangent"Tangent buffer.
{@link Vec4}"color"Color buffer.
{@link Vec4}"skin_cluster_index"Skin cluster index buffer.
{@link Vec4}"skin_cluster_weight"Skin cluster weight buffer.
{@link Vec2}"texcoord0"First UV coordinates buffer.
{@link Vec2}"texcoord1"Second UV coordinates buffer.
{@link Vec2}"texcoord2"Third UV coordinates buffer.
{@link Vec2}"texcoord3"Fourth UV coordinates buffer.
{@link Vec2}"texcoord4"Fifth UV coordinates buffer.
+ * @typedef {Vec3|vec2} Graphics.BufferType + */ QMap 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(index); } - /**jsdoc - * - * - * - * - * - * - * - * - * - * - * - * - * - *
ValueDescription
0Points.
1Lines.
2Line strip.
3Triangles.
4Triangle strip.
5Quads.
6Quad strip.
- * @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 + *

The interpretation of mesh elements.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDescription
"points"Points.
"lines"Lines.
"line_strip"Line strip.
"triangles"Triangles.
"triangle_strip"Triangle strip.
"quads"Quads.
"quad_strip"Quad strip.
+ * @typedef {string} Graphics.MeshTopology + */ namespace graphics { DebugEnums TOPOLOGIES{ { Mesh::Topology::POINTS, "points" },