From 5fd9f1daf580c94b7c6c9b3ae76c0c0fb4e658f0 Mon Sep 17 00:00:00 2001 From: M-II-R Date: Sun, 16 Mar 2025 16:01:52 +0000 Subject: [PATCH 1/2] Automated Extension submission for issue #1599 --- extensions/community/SkeletonTools3D.json | 913 ++++++++++++++++++++++ 1 file changed, 913 insertions(+) create mode 100644 extensions/community/SkeletonTools3D.json diff --git a/extensions/community/SkeletonTools3D.json b/extensions/community/SkeletonTools3D.json new file mode 100644 index 000000000..50855020a --- /dev/null +++ b/extensions/community/SkeletonTools3D.json @@ -0,0 +1,913 @@ +{ + "author": "", + "category": "Game mechanic", + "extensionNamespace": "", + "fullName": "Skeleton tools 3D", + "gdevelopVersion": "", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTIyLjcsMTguN2wtOS40LTkuNEMxNC4zLDgsMTQuMiw2LjIsMTMsNWMtMS4zLTEuMy0zLjQtMS4zLTQuNywwYy0wLjcsMC43LTEsMS41LTEsMi40Yy0wLjksMC0xLjcsMC4zLTIuNCwxDQoJQzMuNyw5LjYsMy43LDExLjcsNSwxM2MxLjIsMS4yLDMsMS4zLDQuMywwLjNsOS40LDkuNGMtMSwxLjMtMC45LDMuMSwwLjMsNC4zYzEuMywxLjMsMy40LDEuMyw0LjcsMGMwLjctMC43LDEtMS41LDEtMi40DQoJYzAuOSwwLDEuNy0wLjMsMi40LTFjMS4zLTEuMywxLjMtMy40LDAtNC43QzI1LjgsMTcuOCwyNCwxNy43LDIyLjcsMTguN3oiLz4NCjwvc3ZnPg0K", + "name": "SkeletonTools3D", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/Line Hero Pack/Master/SVG/Halloween/938d86fd5abd2ebe02981106c2beda2d653a1d53cc5439cc609f70ac5a983f22_Halloween_bone.svg", + "shortDescription": "This extension adds functions for manipulating the skeleton of a 3D model.", + "version": "0.7.2", + "description": "Manipulate 3D model's bones, change its position, scale and rotation. It can be useful for creating procedural animations etc.", + "tags": [ + "3d", + "bones", + "skeleton" + ], + "authorIds": [ + "iCuOTzgvSYOOXr4HW0sFJLIaP082" + ], + "dependencies": [], + "globalVariables": [], + "sceneVariables": [], + "eventsFunctions": [ + { + "description": "Change 3D model's bone position.", + "fullName": "Change bone position", + "functionType": "Action", + "name": "ChangePosition", + "sentence": "Change the bone's number _PARAM2_ of _PARAM1_ position on _PARAM3_ _PARAM4_ axis: _PARAM5_ _PARAM6_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " const mode = eventsFunctionContext.getArgument(\"Mode\"); // Set || Add", + " const position = eventsFunctionContext.getArgument(\"Position\"); // Position", + " let pos = new THREE.Vector3(); // Position || World position", + "", + " objects.forEach((obj) => {", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + " if (axis == \"Local\") {", + "", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " bone.position.x = position;", + " if (mode == \"Add\")", + " bone.position.x += position;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " bone.position.y = position;", + " if (mode == \"Add\")", + " bone.position.y += position;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " bone.position.z = position;", + " if (mode == \"Add\")", + " bone.position.z += position;", + " }", + "", + " }", + " if (axis == \"Global\") {", + " pos = bone.position.clone();", + " bone.localToWorld(pos);", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " pos.x = position;", + " if (mode == \"Add\")", + " pos.x += position;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " pos.y = position;", + " if (mode == \"Add\")", + " pos.y += position;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " pos.z = position;", + " if (mode == \"Add\")", + " pos.z += position;", + " }", + " pos = bone.worldToLocal(pos);", + " bone.position.set(pos.x, pos.y, pos.z);", + "", + " }", + "", + " })", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in ChangePosition action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (global or local)", + "name": "Axis", + "supplementaryInformation": "[\"Global\",\"Local\"]", + "type": "stringWithSelector" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + }, + { + "description": "Mode", + "name": "Mode", + "supplementaryInformation": "[\"Set\",\"Add\"]", + "type": "stringWithSelector" + }, + { + "description": "Position", + "name": "Position", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change 3D model's bone rotation.", + "fullName": "Change bone rotation", + "functionType": "Action", + "name": "ChangeRotation", + "sentence": "Change the bone's number _PARAM2_ of _PARAM1_ rotation on _PARAM3_ _PARAM4_ axis: _PARAM5_ _PARAM6_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " let iter = 0;", + " function getScene(obj = new THREE.Object3D) {", + " if (obj.type == \"Scene\") {", + " return obj;", + " }", + " else {", + " if (iter <= 100) {", + " iter += 1;", + " return getScene(obj.parent);", + " }", + " else {", + " console.log(\"Couldn't get a 3d scene.\");", + " return new THREE.Object3D();", + " }", + " }", + " }", + " let scene;", + " if (objects.length > 0) {", + " scene = getScene(objects[0].get3DRendererObject());", + " }", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " const mode = eventsFunctionContext.getArgument(\"Mode\"); // Set || Add", + " const rotation = eventsFunctionContext.getArgument(\"Rotation\") * Math.PI / 180; // Position", + "", + " objects.forEach((obj) => {", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + "", + " if (axis == \"Local\") {", + "", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " bone.rotation.x = rotation;", + " if (mode == \"Add\")", + " bone.rotation.x += rotation;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " bone.rotation.y = rotation;", + " if (mode == \"Add\")", + " bone.rotation.y += rotation;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " bone.rotation.z = rotation;", + " if (mode == \"Add\")", + " bone.rotation.z += rotation;", + " }", + "", + " }", + "", + " if (axis == \"Global\") {", + "", + " let vec = new THREE.Vector3();", + " const par = bone.parent;", + " scene.attach(bone);", + "", + " if (mode == \"Set\") {", + " let quat = new THREE.Quaternion();", + " bone.getWorldQuaternion(quat);", + " let eu = new THREE.Euler();", + " eu.setFromQuaternion(quat);", + " if (axis2 == \"X\") {", + " vec.set(1, 0, 0);", + " bone.rotateOnWorldAxis(vec, rotation - eu.x);", + " }", + " if (axis2 == \"Y\") {", + " vec.set(0, 1, 0);", + " bone.rotateOnWorldAxis(vec, rotation - eu.y);", + " }", + " if (axis2 == \"Z\") {", + " vec.set(0, 0, 1);", + " bone.rotateOnWorldAxis(vec, rotation - eu.z);", + " }", + " }", + "", + " if (mode == \"Add\") {", + "", + " if (axis2 == \"X\") {", + " vec.set(1, 0, 0);", + " }", + " if (axis2 == \"Y\") {", + " vec.set(0, 1, 0);", + " }", + " if (axis2 == \"Z\") {", + " vec.set(0, 0, 1);", + " }", + " bone.rotateOnWorldAxis(vec, rotation);", + " }", + "", + " par.attach(bone);", + "", + " }", + "", + " })", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in ChangeRotation action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (global or local)", + "name": "Axis", + "supplementaryInformation": "[\"Global\",\"Local\"]", + "type": "stringWithSelector" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + }, + { + "description": "Mode", + "name": "Mode", + "supplementaryInformation": "[\"Set\",\"Add\"]", + "type": "stringWithSelector" + }, + { + "description": "Rotation", + "name": "Rotation", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change 3D model's bone scale.", + "fullName": "Change bone scale", + "functionType": "Action", + "name": "ChangeScale", + "sentence": "Change the bone's number _PARAM2_ of _PARAM1_ scale on _PARAM3_ _PARAM4_ axis: _PARAM5_ _PARAM6_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " const mode = eventsFunctionContext.getArgument(\"Mode\"); // Set || Add", + " const scale = eventsFunctionContext.getArgument(\"Scale\"); // Scale", + "", + "", + " objects.forEach((obj) => {", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + "", + "", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " bone.scale.x = scale;", + " if (mode == \"Add\")", + " bone.scale.x += scale;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " bone.scale.y = scale;", + " if (mode == \"Add\")", + " bone.scale.y += scale;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " bone.scale.z = scale;", + " if (mode == \"Add\")", + " bone.scale.z += scale;", + " }", + "", + "", + " })", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in ChangeScale action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (global or local)", + "name": "Axis", + "supplementaryInformation": "[\"Local\"]", + "type": "stringWithSelector" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + }, + { + "description": "Mode", + "name": "Mode", + "supplementaryInformation": "[\"Set\",\"Add\"]", + "type": "stringWithSelector" + }, + { + "description": "Scale", + "name": "Scale", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Attach 3D object to bone.", + "fullName": "Attach 3D object to bone ", + "functionType": "Action", + "name": "Attach", + "sentence": "Attach _PARAM3_ to the bone number _PARAM2_ of _PARAM1_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const targ = eventsFunctionContext.getObjects(\"Target\");", + "", + " const obj = objects[0];", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + " targ.forEach((target) => {", + " const t = target.get3DRendererObject();", + " bone.attach(t);", + " });", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in Attach action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Target 3D object", + "name": "Target", + "type": "objectList" + }, + { + "description": "3D capability", + "name": "Behavior", + "supplementaryInformation": "Scene3D::Base3DBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Detach 3D object from bone.", + "fullName": "Detach 3D object from bone ", + "functionType": "Action", + "name": "Detach", + "sentence": "Detach _PARAM2_ from the bone of _PARAM1_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " let iter = 0;", + " function getScene(obj = new THREE.Object3D) {", + " if (obj.type == \"Scene\") {", + " return obj;", + " }", + " else {", + " if (iter <= 100) {", + " iter += 1;", + " return getScene(obj.parent);", + " }", + " else {", + " console.log(\"Couldn't get a 3d scene.\");", + " return new THREE.Object3D();", + " }", + " }", + " }", + " let scene;", + " if (objects.length > 0) {", + " scene = getScene(objects[0].get3DRendererObject());", + "", + " const targ = eventsFunctionContext.getObjects(\"Target\");", + "", + " const obj = objects[0];", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + "", + " targ.forEach((target) => {", + " const t = target.get3DRendererObject();", + " if (t.parent.type == \"Bone\") {", + " scene.attach(t);", + " }", + " });", + " }", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in Detach action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Target 3D object", + "name": "Target", + "type": "objectList" + }, + { + "description": "3D capability", + "name": "Behavior", + "supplementaryInformation": "Scene3D::Base3DBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the position of bone.", + "fullName": "Bone position", + "functionType": "Expression", + "name": "BonePosition", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " let iter = 0;", + " function getScene(obj = new THREE.Object3D) {", + " if (obj.type == \"Scene\") {", + " return obj;", + " }", + " else {", + " if (iter <= 100) {", + " iter += 1;", + " return getScene(obj.parent);", + " }", + " else {", + " console.log(\"Couldn't get a 3d scene.\");", + " return new THREE.Object3D();", + " }", + " }", + " }", + " let scene;", + " if (objects.length > 0) {", + " scene = getScene(objects[0].get3DRendererObject());", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " let pos = new THREE.Vector3(); // Position || World position", + " const obj = objects[0];", + "", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + " if (axis == \"Local\") {", + "", + " if (axis2 == \"X\") {", + " eventsFunctionContext.returnValue = bone.position.x;", + " }", + " if (axis2 == \"Y\") {", + " eventsFunctionContext.returnValue = bone.position.y;", + " }", + " if (axis2 == \"Z\") {", + " eventsFunctionContext.returnValue = bone.position.z;", + " }", + "", + " }", + " if (axis == \"Global\") {", + " const par = bone.parent;", + " pos = bone.position.clone();", + "", + " bone.getWorldPosition(pos);", + "", + " if (axis2 == \"X\") {", + " eventsFunctionContext.returnValue = pos.x;", + " }", + " if (axis2 == \"Y\") {", + " eventsFunctionContext.returnValue = pos.y;", + " }", + " if (axis2 == \"Z\") {", + " eventsFunctionContext.returnValue = pos.z;", + " }", + " }", + " }", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in BonePosition expression. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (global or local)", + "name": "Axis", + "supplementaryInformation": "[\"Global\",\"Local\"]", + "type": "stringWithSelector" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the rotation of bone.", + "fullName": "Bone rotation", + "functionType": "Expression", + "name": "BoneRotation", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " let iter = 0;", + " function getScene(obj = new THREE.Object3D) {", + " if (obj.type == \"Scene\") {", + " return obj;", + " }", + " else {", + " if (iter <= 100) {", + " iter += 1;", + " return getScene(obj.parent);", + " }", + " else {", + " console.log(\"Couldn't get a 3d scene.\");", + " return new THREE.Object3D();", + " }", + " }", + " }", + " let scene;", + " if (objects.length > 0) {", + " scene = getScene(objects[0].get3DRendererObject());", + "", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " const obj = objects[0];", + "", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + "", + " if (axis == \"Local\") {", + "", + " if (axis2 == \"X\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.x);", + " }", + " if (axis2 == \"Y\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.y);", + " }", + " if (axis2 == \"Z\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.z);", + " }", + "", + " }", + " if (axis == \"Global\") {", + " const par = bone.parent;", + " scene.attach(bone);", + "", + " let eu = new THREE.Euler();", + "", + " bone.updateWorldMatrix();", + " eu.setFromRotationMatrix(bone.matrixWorld)", + "", + " if (axis2 == \"X\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.x);", + " }", + " if (axis2 == \"Y\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.y);", + " }", + " if (axis2 == \"Z\") {", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.z);", + " }", + " par.attach(bone);", + " }", + " }", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in BoneRotation expression. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (global or local)", + "name": "Axis", + "supplementaryInformation": "[\"Global\",\"Local\"]", + "type": "stringWithSelector" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "3D model's bone scale.", + "fullName": "Bone scale", + "functionType": "Expression", + "name": "BoneScale", + "sentence": "Change the bone's number _PARAM2_ of _PARAM1_ scale on _PARAM3_ _PARAM4_ axis: _PARAM5_ _PARAM6_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + "", + " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", + " if (objects.length > 0) {", + " const obj = objects[0];", + "", + "", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + "", + "", + " if (axis2 == \"X\") {", + " eventsFunctionContext.returnValue = bone.scale.x;", + " }", + " if (axis2 == \"Y\") {", + " eventsFunctionContext.returnValue = bone.scale.y;", + " }", + " if (axis2 == \"Z\") {", + " eventsFunctionContext.returnValue = bone.scale.y;", + " }", + "", + " }", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in BoneScale expression. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "Axis (X, Y, Z)", + "name": "Axis2", + "supplementaryInformation": "[\"X\",\"Y\",\"Z\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of object's bones.", + "fullName": "Bones number", + "functionType": "Expression", + "name": "BonesNumber", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {\r", + " if (objects.length > 0) {\r", + " const obj = objects[0];\r", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());\r", + " eventsFunctionContext.returnValue = skel.bones.length;\r", + " }\r", + "}\r", + "catch (err) {\r", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in BonesNumber expression. Error: \" + err);\r", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Return the name of object's bone.", + "fullName": "Bone name", + "functionType": "StringExpression", + "name": "BoneName", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {\r", + "if (objects.length > 0) {\r", + " const numb = eventsFunctionContext.getArgument(\"Bone\");\r", + " let number = 0; number += numb.valueOf();\r", + " let obj = objects[0];\r", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());\r", + " eventsFunctionContext.returnValue = skel.bones[number].name;\r", + "}\r", + "}\r", + "catch (err) {\r", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in BoneName expression. Error: \" + err);\r", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] +} \ No newline at end of file From 29f33b980a049946f689dc6fdbe76e8c5c81c0b7 Mon Sep 17 00:00:00 2001 From: M-II-R Date: Wed, 19 Mar 2025 05:42:46 +0000 Subject: [PATCH 2/2] Updated extension --- extensions/community/SkeletonTools3D.json | 210 ++++++++++++++++++---- 1 file changed, 180 insertions(+), 30 deletions(-) diff --git a/extensions/community/SkeletonTools3D.json b/extensions/community/SkeletonTools3D.json index 50855020a..43bf99fdd 100644 --- a/extensions/community/SkeletonTools3D.json +++ b/extensions/community/SkeletonTools3D.json @@ -9,7 +9,7 @@ "name": "SkeletonTools3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/Line Hero Pack/Master/SVG/Halloween/938d86fd5abd2ebe02981106c2beda2d653a1d53cc5439cc609f70ac5a983f22_Halloween_bone.svg", "shortDescription": "This extension adds functions for manipulating the skeleton of a 3D model.", - "version": "0.7.2", + "version": "0.7.3", "description": "Manipulate 3D model's bones, change its position, scale and rotation. It can be useful for creating procedural animations etc.", "tags": [ "3d", @@ -34,6 +34,26 @@ "type": "BuiltinCommonInstructions::JsCode", "inlineCode": [ "try {", + " let iter = 0;", + " function getScene(obj = new THREE.Object3D) {", + " if (obj.type == \"Scene\") {", + " return obj;", + " }", + " else {", + " if (iter <= 100) {", + " iter += 1;", + " return getScene(obj.parent);", + " }", + " else {", + " console.log(\"Couldn't get a 3d scene.\");", + " return new THREE.Object3D();", + " }", + " }", + " }", + " let scene;", + " if (objects.length > 0) {", + " scene = getScene(objects[0].get3DRendererObject());", + " }", " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", " let numb = 0;", " numb += number;", @@ -69,8 +89,9 @@ "", " }", " if (axis == \"Global\") {", + " const par = bone.parent;", + " scene.attach(bone);", " pos = bone.position.clone();", - " bone.localToWorld(pos);", " if (axis2 == \"X\") {", " if (mode == \"Set\")", " pos.x = position;", @@ -89,8 +110,8 @@ " if (mode == \"Add\")", " pos.z += position;", " }", - " pos = bone.worldToLocal(pos);", " bone.position.set(pos.x, pos.y, pos.z);", + " par.attach(bone);", "", " }", "", @@ -211,41 +232,33 @@ "", " if (axis == \"Global\") {", "", - " let vec = new THREE.Vector3();", " const par = bone.parent;", " scene.attach(bone);", "", " if (mode == \"Set\") {", - " let quat = new THREE.Quaternion();", - " bone.getWorldQuaternion(quat);", - " let eu = new THREE.Euler();", - " eu.setFromQuaternion(quat);", + " ", " if (axis2 == \"X\") {", - " vec.set(1, 0, 0);", - " bone.rotateOnWorldAxis(vec, rotation - eu.x);", + " bone.rotation.x = rotation;", " }", " if (axis2 == \"Y\") {", - " vec.set(0, 1, 0);", - " bone.rotateOnWorldAxis(vec, rotation - eu.y);", + " bone.rotation.y = rotation;", " }", " if (axis2 == \"Z\") {", - " vec.set(0, 0, 1);", - " bone.rotateOnWorldAxis(vec, rotation - eu.z);", + " bone.rotation.z = rotation;", " }", " }", "", " if (mode == \"Add\") {", "", " if (axis2 == \"X\") {", - " vec.set(1, 0, 0);", + " bone.rotation.x += rotation;", " }", " if (axis2 == \"Y\") {", - " vec.set(0, 1, 0);", + " bone.rotation.y += rotation;", " }", " if (axis2 == \"Z\") {", - " vec.set(0, 0, 1);", + " bone.rotation.z += rotation;", " }", - " bone.rotateOnWorldAxis(vec, rotation);", " }", "", " par.attach(bone);", @@ -324,7 +337,7 @@ " objects.forEach((obj) => {", " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", " let bone = skel.bones[numb];", - "", + " //if (axis == \"Local\") {", "", " if (axis2 == \"X\") {", " if (mode == \"Set\")", @@ -345,6 +358,41 @@ " bone.scale.z += scale;", " }", "", + " //}", + " /*if (axis == \"Global\") {", + " const par = bone.parent;", + " let scl = new THREE.Vector3();", + " scl = bone.scale.clone();", + " bone.localToWorld(scl);", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " scl.x = scale;", + " if (mode == \"Add\")", + " scl.x += scale;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " scl.y = scale;", + " if (mode == \"Add\")", + " scl.y += scale;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " scl.z = scale;", + " if (mode == \"Add\")", + " scl.z += scale;", + " }", + " bone.worldToLocal(scl);", + " bone.scale.copy(scl);", + " ", + " ", + " //bone.scale.copy(scl);", + " //bone.matrixWorld.scale(scl);", + " //bone.matrixWorld.multiply(mtr);", + " //pos = bone.worldToLocal(pos);", + " //bone.position.set(pos.x, pos.y, pos.z);", + " //bone.updateWorldMatrix();", + " }*/", "", " })", "}", @@ -395,6 +443,71 @@ ], "objectGroups": [] }, + { + "description": "Change 3D model's bone rotation to look at position.", + "fullName": "Look at 3D object", + "functionType": "Action", + "name": "LookAtPosition", + "private": true, + "sentence": "Change the rotation of bone number _PARAM2_ of _PARAM1_ to look at _PARAM3_; _PARAM4_; _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "try {", + " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", + " let numb = 0;", + " numb += number;", + " const x = eventsFunctionContext.getArgument(\"X\");", + " const y = eventsFunctionContext.getArgument(\"Y\");", + " const z = eventsFunctionContext.getArgument(\"Z\");", + "", + " objects.forEach((obj) => {", + " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", + " let bone = skel.bones[numb];", + " bone.lookAt(new THREE.Vector3(x, y, z));", + " })", + "}", + "catch (err) {", + " console.log(\"Something went wrong in the Skeleton tools 3D extension, in LookAtPosition action. Error: \" + err);", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "3D model", + "name": "Object", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "objectList" + }, + { + "description": "Bone index (minimum - 0)", + "name": "Bone", + "type": "expression" + }, + { + "description": "X", + "name": "X", + "supplementaryInformation": "Scene3D::Model3DObject", + "type": "expression" + }, + { + "description": "Y", + "name": "Y", + "type": "expression" + }, + { + "description": "Z", + "name": "Z", + "type": "expression" + } + ], + "objectGroups": [] + }, { "description": "Attach 3D object to bone.", "fullName": "Attach 3D object to bone ", @@ -583,6 +696,7 @@ " }", " if (axis == \"Global\") {", " const par = bone.parent;", + " //scene.attach(bone);", " pos = bone.position.clone();", "", " bone.getWorldPosition(pos);", @@ -596,6 +710,7 @@ " if (axis2 == \"Z\") {", " eventsFunctionContext.returnValue = pos.z;", " }", + " //par.attach(bone);", " }", " }", "}", @@ -696,19 +811,14 @@ " const par = bone.parent;", " scene.attach(bone);", "", - " let eu = new THREE.Euler();", - "", - " bone.updateWorldMatrix();", - " eu.setFromRotationMatrix(bone.matrixWorld)", - "", " if (axis2 == \"X\") {", - " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.x);", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.x);", " }", " if (axis2 == \"Y\") {", - " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.y);", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.y);", " }", " if (axis2 == \"Z\") {", - " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(eu.z);", + " eventsFunctionContext.returnValue = THREE.MathUtils.radToDeg(bone.rotation.z);", " }", " par.attach(bone);", " }", @@ -767,15 +877,15 @@ " const number = eventsFunctionContext.getArgument(\"Bone\"); // Bone index", " let numb = 0;", " numb += number;", - "", + " //const axis = eventsFunctionContext.getArgument(\"Axis\"); // Global || Local", " const axis2 = eventsFunctionContext.getArgument(\"Axis2\"); // X || Y || Z", " if (objects.length > 0) {", " const obj = objects[0];", "", - "", + " //objects.forEach((obj) => {", " const skel = new THREE.SkeletonHelper(obj.get3DRendererObject());", " let bone = skel.bones[numb];", - "", + " //if (axis == \"Local\") {", "", " if (axis2 == \"X\") {", " eventsFunctionContext.returnValue = bone.scale.x;", @@ -787,6 +897,46 @@ " eventsFunctionContext.returnValue = bone.scale.y;", " }", "", + " //}", + " /*if (axis == \"Global\") {", + " const par = bone.parent;", + " //scene.attach(bone);", + " //pos = bone.position.clone();", + " //bone.localToWorld(pos);", + " let scl = new THREE.Vector3();", + " scl = bone.scale.clone();", + " bone.localToWorld(scl);", + " if (axis2 == \"X\") {", + " if (mode == \"Set\")", + " scl.x = scale;", + " if (mode == \"Add\")", + " scl.x += scale;", + " }", + " if (axis2 == \"Y\") {", + " if (mode == \"Set\")", + " scl.y = scale;", + " if (mode == \"Add\")", + " scl.y += scale;", + " }", + " if (axis2 == \"Z\") {", + " if (mode == \"Set\")", + " scl.z = scale;", + " if (mode == \"Add\")", + " scl.z += scale;", + " }", + " bone.worldToLocal(scl);", + " bone.scale.copy(scl);", + " ", + " ", + " //bone.scale.copy(scl);", + " //bone.matrixWorld.scale(scl);", + " //bone.matrixWorld.multiply(mtr);", + " //pos = bone.worldToLocal(pos);", + " //bone.position.set(pos.x, pos.y, pos.z);", + " //bone.updateWorldMatrix();", + " //par.attach(bone);", + " //par.attach(bone);", + " }*/", " }", "}", "catch (err) {",