Generate a Three.js skeleton using code

I am trying to load a model of a mechanism, like a robot arm, into Three.js. Unfortunately, the models I have do not come with a skeleton, but I do have the information about joint locations, axes, and orientations. I want to use inverse kinematic solvers like Three-IK, so I need to create a skeleton based on these parameters. Since I plan on using various models, I would rather generate the skeletons programmatically instead of manually creating them.

Despite my efforts for more than a week, I have not been successful in creating a valid bone structure that accurately represents the model. For example, when I attempt to create a chain of bones using joint positions, the resulting skeleton is long and does not match the intended positions.

let boneParent;
let bonepos = [];
let bones = [];
model.traverse(child => {
    switch(child.type) {
        case "joint":
            let p = new Vector3();
            child.getWorldPosition(p);
            bonepos.push(p);

            let bone = new Bone();
            boneParent && boneParent.add(p);
            bone.worldToLocal(p.clone());
            bone.position.copy(p);
            bone.rotation.copy(child.rotation);
            bone.scale.copy(child.scale);

            boneParent = bone;
            bones.push(bone);
            break;
    }
});
showPoints(scene, bonepos, 0xff0000);

const skeletonHelper = new SkeletonHelper(bones[0]);
skeletonHelper.visible = true;
scene.add(skeletonHelper);

The code snippet above produces the screenshot depicted below. The red markers represent the joint positions obtained from the robot, while the line extending into the distance showcases the visualized skeleton through the SkeletonHelper tool.

https://i.sstatic.net/HFkIc.png

My dilemma is this: it appears I may not have a deep enough understanding of how bones are managed within Three.js. How can I go about generating a skeleton that accurately mirrors my existing model based on its joint coordinates and orientations?

Thank you in advance!

Attention future visitors: Rocksi is an open-source project!

Answer №1

After experimenting with different approaches, I finally came up with a solution:

let rootBone = new Bone();
let parentBone = rootBone;
let position = new Vector3();

for (let currentJoint of robot.arm.movable) {
    let correspondingLink = robot.getLinkForJoint(currentJoint);
    correspondingLink.getWorldPosition(position);
    
    let newBone = new Bone();
    parentBone.add(newBone);
    parentBone.lookAt(position);
    parentBone.updateMatrixWorld();  // make sure to include this step for worldToLocal to work properly!
    newBone.position.copy(newBone.worldToLocal(position));
        
    parentBone = newBone;
}

The key takeaway is to execute updateMatrixWorld() after lookAt() in order for bone.worldToLocal() to function as expected. Additionally, using lookAt() simplifies handling matrices significantly :)

Answer №2

When using child.getWorldPosition(p), be cautious as it may not accurately reflect the position in local space of Bone.position.

In addition, setting boneParent = bone might cause issues if a bone has multiple child elements. Make sure to consider this scenario in your code implementation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to display additional text with a "Read More" link after three lines of content without relying on a

I am currently working on an application where I need to display text in a limited space of 3 lines. If the text exceeds this limit, I want to show either "Read More" or "Hide". Below is the code snippet that I am using for this functionality. class Cust ...

Find the value of the closest HTML thead element upon clicking a td cell

I am having an issue with my HTML table layout, here is the code: jQuery(document).ready(function($) { $('#reservationtable tbody tr td').on('click', function () { var reservationtime = $( this ).siblings('th&a ...

Try implementing in conjunction with the NPM package bootstrap-markdown

For my project, I have incorporated the NPM package bootstrap-markdown. To implement it, I included these lines in my JS file: var $ = require('jquery/dist/jquery.min.js'); require('bootstrap-markdown/js/bootstrap-markdown.js') The p ...

I'm attempting to install React, but I keep encountering the error mentioned below. What steps can I take to resolve this issue?

Having trouble installing using the command: view image description here PS D:\Programming\Js\React> npx create-react-app my-app npm ERR! code ENOENT npm ERR! syscall lstat npm ERR! path C:\Users\NGUYEN THI PHUC&bsol ...

Sort data by various categories using Vue.js

I need help filtering my JSON data based on multiple categories using Vuejs, specifically with Vue 3 and collect.js. Here's the template I'm working with: <select v-model="selectedCategory" multiple> <option :value="n ...

Trigger a function upon the initial keypress event detected on an input field

I am facing an issue with an input element that has an onkeypress event triggering a function called change(). Strangely, the function does not execute on the very first keypress. I notice that I have to input 55 instead of just 5 for the function to updat ...

Angular's parent div height can be adjusted using CSS transitions

I have implemented a CSS transition to create a sliding effect in my pagination. However, I am facing an issue where the height of the containing div changes even when I set the position of the transitioned elements. Here is a snippet of my CSS: .slide { ...

Control the line height in DataTables

Is there a way to adjust the line height for a tr using either DataTables settings or CSS? I've attempted different methods, but nothing seems to change the line-height. https://i.sstatic.net/GwFaD.png Table CSS ...

Having trouble with the response function not functioning properly within an AJAX autocomplete

I have implemented an autocomplete feature using the jQuery UI plugin from http://jqueryui.com/autocomplete/#remote-jsonp. $("#city" ).autocomplete({ source: function( request, response ) { $.ajax({ url: 'index.php?secController= ...

ASP.NET jQuery .load method failing to invoke controller action

I'm currently working on a project that involves displaying a list in a partial view using AJAX and JQuery with Entity Framework. The goal is to allow the user to click on an action link in the navbar, triggering a JQuery event that fetches a list fro ...

Tips for enhancing the presentation of JSON information

I recently ventured into the world of JSON and JS, managing to create a JSON file to showcase data using .onclick event. While I have successfully generated and displayed the JSON data on screen, my next goal is to present it in a table format for better c ...

Issue arising due to incorrect array index placement following the axios request

I am currently utilizing vue js and axios for my project. Here is the challenge I am facing: Typically, my "outlines" array contains anywhere from 3 to 9 entries. I want to send an axios request (runSecondFunction()) for each entry, but execute only one ...

"Encountering a JavaScript Issue While Displaying an iFrame

Having trouble displaying an iframe on a ColdFusion website when passing values in the URL. A similar method worked fine on a non-ColdFusion site, so I suspect the issue is with ColdFusion itself. Unfortunately, I have no experience with ColdFusion. If I ...

Troubleshooting Date Errors in Typescript with VueJS

Encountering a peculiar issue with Typescript while attempting to instantiate a new Date object. <template> <div> Testing Date</div> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ name: ...

Combine all elements into a single array using the map method in JavaScript

In my possession, I have an array of objects with IDs and names: [ { "id": 10, "name": "comedy" }, { "id": 12, "name": "documentary" }, { ...

Swap out a component for another using a higher order component (HOC perhaps?)

I have noticed that certain libraries like "framer-motion" in react utilize this syntax, for instance to include an animated H1: <motion.h1> where the h1 tag is enhanced with animations specified in the component's props. What confuses me is ho ...

Issue with debugging capabilities in Javascript on VSCode has been detected

UPDATE: I'm seeking guidance on configuring VSCode for debugging Javascript. While I'm familiar with JavaScript functioning in a browser, I find it tedious to rely solely on console.log(). I am looking to debug and step through my code effectivel ...

Tips for utilizing the download stream with StreamSaver.js in Axios?

Within my server-side application, constructed using the Spring Boot framework, I have implemented a method that returns a stream resembling the following: public ResponseEntity<StreamingResponseBody> downloadFiles(@RequestBody DownloadRequest payloa ...

Utilizing JavaScript to sift through JSON data

Looking to efficiently parse a large JSON file based on its values. This is an excerpt from my extensive JSON code (with over 1000 entries). var jsonObject = [ { "UserId":10259, "FullName":"hello world", "CustomerId":"10165" ...

ACL - Utilize ACL in conjunction with the passport authentication system

I am experimenting with node_acl in combination with passport-local. Unfortunately, I am facing an issue when trying to secure the route for the admin-user '/admin', as it keeps redirecting me to the /login page. Below is a simplified version of ...