Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Community] [3D sprite] Animated sprite in 3D #1208

Merged
merged 5 commits into from Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
198 changes: 198 additions & 0 deletions extensions/community/Sprite3D.json
@@ -0,0 +1,198 @@
{
"author": "",
"category": "General",
"extensionNamespace": "",
"fullName": "3D sprite",
"helpPath": "/objects/sprite/",
"iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWdob3N0LW91dGxpbmUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTIgMkM3LjAzIDIgMyA2LjAzIDMgMTFWMjJMNiAxOUw5IDIyTDEyIDE5TDE1IDIyTDE4IDE5TDIxIDIyVjExQzIxIDYuMDMgMTYuOTcgMiAxMiAyTTE5IDE3LjE3TDE4IDE2LjE3TDE2LjU5IDE3LjU5TDE1IDE5LjE3TDEzLjQxIDE3LjU5TDEyIDE2LjE3TDEwLjU5IDE3LjU5TDkgMTkuMTdMNy40MSAxNy41OUw2IDE2LjE3TDUgMTcuMTdWMTFDNSA3LjE0IDguMTQgNCAxMiA0UzE5IDcuMTQgMTkgMTFWMTcuMTdNMTEgMTBDMTEgMTEuMTEgMTAuMTEgMTIgOSAxMlM3IDExLjExIDcgMTAgNy45IDggOSA4IDExIDguOSAxMSAxME0xNyAxMEMxNyAxMS4xMSAxNi4xMSAxMiAxNSAxMlMxMyAxMS4xMSAxMyAxMCAxMy45IDggMTUgOCAxNyA4LjkgMTcgMTBaIiAvPjwvc3ZnPg==",
"name": "Sprite3D",
"previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/3bd33ec77ed20d3f631c6c92884728b375aa2879174bc9f289c864d0e0383d59_ghost-outline.svg",
"shortDescription": "An animated sprite in 3D.",
"version": "0.1.0",
"description": "The 3D sprite is an object that can be moved and rotated in 3D.",
"tags": [
"3d"
],
"authorIds": [
"IWykYNRvhCZBN3vEgKEbBPOR3Oc2"
],
"dependencies": [],
"eventsFunctions": [
{
"description": "Define helper classes JavaScript code.",
"fullName": "Define helper classes",
"functionType": "Action",
"name": "DefineHelperClasses",
"private": true,
"sentence": "Define helper classes JavaScript code",
"events": [
{
"type": "BuiltinCommonInstructions::JsCode",
"inlineCode": [
"if (gdjs.__sprite3DExtension) {",
" return;",
"}",
"",
"class Sprite3DRenderer {",
" /** @type {gdjs.CustomRuntimeObject} */",
" object;",
" /** @type {THREE.Mesh} */",
" mesh;",
"",
" /**",
" * @param object {gdjs.CustomRuntimeObject}",
" */",
" constructor(object) {",
" this.object = object;",
" ",
" const geometry = new THREE.PlaneGeometry(1, -1);",
" const animationFrame = object.getAnimator().getCurrentFrame();",
" const material = animationFrame.texture;",
" this.mesh = new THREE.Mesh(geometry, material);",
" this.mesh.rotation.order = 'ZYX';",
" object.get3DRendererObject().add(this.mesh);",
"",
" this.updateFrame();",
" object.getAnimator().setOnFrameChangeCallback(() => this.updateFrame());",
" }",
"",
" updateFrame() {",
" const frame = this.object.getAnimator().getCurrentFrame();",
" const material = frame.texture;",
"",
" const image = material.map.image;",
" const width = image.width;",
" const height = image.height;",
" const origin = frame.origin;",
" this.mesh.position.set(-origin.x + width / 2, -origin.y + height / 2, 0);",
" this.mesh.scale.set(width, height, 1);",
"",
" const center = frame.center;",
" this.object.setRotationCenter(center.x - origin.x, center.y - origin.y);",
"",
" this.mesh.material = material;",
"",
" const hitBoxes = this.object._untransformedHitBoxes;",
" if (frame.hasCustomCollisionMask) {",
" let i = 0;",
" for (let len = frame.customCollisionMask.length; i < len; ++i) {",
" const polygonData = frame.customCollisionMask[i];",
"",
" // Add a polygon, if necessary (Avoid recreating a polygon if it already exists).",
" if (i >= hitBoxes.length) {",
" hitBoxes.push(new gdjs.Polygon());",
" }",
" let j = 0;",
" for (const len2 = polygonData.length; j < len2; ++j) {",
" const pointData = polygonData[j];",
"",
" // Add a point, if necessary (Avoid recreating a point if it already exists).",
" if (j >= hitBoxes[i].vertices.length) {",
" hitBoxes[i].vertices.push([0, 0]);",
" }",
" hitBoxes[i].vertices[j][0] = pointData.x - origin.x;",
" hitBoxes[i].vertices[j][1] = pointData.y - origin.y;",
" }",
" hitBoxes[i].vertices.length = j;",
" }",
" hitBoxes.length = i;",
" }",
" else if (hitBoxes.length === 0) {",
" const hitBox = new gdjs.Polygon();",
" hitBoxes.push(hitBox);",
" const vertices = hitBox.vertices;",
" vertices.push([-origin.x, -origin.y]);",
" vertices.push([-origin.x + width, -origin.y]);",
" vertices.push([-origin.x + width, -origin.y + height]);",
" vertices.push([-origin.x, -origin.y + height]);",
" }",
"",
" const aabb = this.object._unrotatedAABB;",
" aabb.min[0] = -origin.x;",
" aabb.min[1] = -origin.y;",
" aabb.max[0] = -origin.x + width;",
" aabb.max[1] = -origin.y + height;",
"",
" this.object._isUntransformedHitBoxesDirty = false;",
" }",
"}",
"",
"gdjs.__sprite3DExtension = {",
" Sprite3DRenderer",
"};",
""
],
"parameterObjects": "",
"useStrict": true,
"eventsSheetExpanded": true
}
],
"parameters": [],
"objectGroups": []
}
],
"eventsBasedBehaviors": [],
"eventsBasedObjects": [
{
"defaultName": "",
"description": "An animated sprite in 3D.",
"fullName": "3D sprite",
"is3D": true,
"isAnimatable": true,
"name": "Sprite3D",
"eventsFunctions": [
{
"fullName": "",
"functionType": "Action",
"name": "onCreated",
"sentence": "",
"events": [
{
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"value": "Sprite3D::DefineHelperClasses"
},
"parameters": [
"",
""
]
}
]
},
{
"type": "BuiltinCommonInstructions::JsCode",
"inlineCode": [
"/** @type {gdjs.CustomRuntimeObject} */\r",
"const object = objects[0];\r",
"\r",
"object.__sprite3DExtension = {};\r",
"object.__sprite3DExtension.sprite3DRenderer = new gdjs.__sprite3DExtension.Sprite3DRenderer(object)\r",
""
],
"parameterObjects": "Object",
"useStrict": true,
"eventsSheetExpanded": true
}
],
"parameters": [
{
"description": "Object",
"name": "Object",
"supplementaryInformation": "Sprite3D::Sprite3D",
"type": "object"
}
],
"objectGroups": []
}
],
"propertyDescriptors": [],
"objects": [],
"objectsFolderStructure": {
"folderName": "__ROOT"
}
}
]
}
10 changes: 10 additions & 0 deletions scripts/lib/ExtensionsValidatorExceptions.js
Expand Up @@ -432,6 +432,16 @@ const extensionsAllowedProperties = {
runtimeSceneAllowedProperties: [],
javaScriptObjectAllowedProperties: [],
},
Sprite3D: {
gdjsAllowedProperties: [
'__sprite3DExtension',
'CustomRuntimeObject',
'Polygon',
],
gdjsEvtToolsAllowedProperties: [],
runtimeSceneAllowedProperties: [],
javaScriptObjectAllowedProperties: [],
},
Sticker: {
gdjsAllowedProperties: [
'_stickerExtension',
Expand Down