Scripts and Bones


#1

It just came to my mind while going through the code debugging the Leap Motion issue,

How come Entities do not have Bones as well? It seems the only objects there are with Bones is Avatars, even though we should completely be able to control bones within Entities, if they have been set.

Forexample, we should be able to make NPCs, that pretty much are entities with a model that has a skeleton. We could also make objects, which are animated via bones, or procedurally:

Such as rings on a teleporter, or making floaty stuff animate around an attached object without resorting to too many individual scripts, Animating trees (procedurally), etc and etc.

Currently, however we are only able to animate in-directly through setting an animation file for them. ( I have yet to test these after the pre-rotation switch, but there are reports that it breaks them now)


#2

Good question. One of my goals is to create creature vehicles, but I planned to do that via a scripted avatar, the script is the motion AI. This then begs the question whether one avatar can then sit upon another avatar.


#3

@Menithal, have a look at createDoll.js. The doll is created as entity, has bones and can be animated with doll.js.


#4

The doll.js doesnt cover what I am trying to discuss here; it shows the use of the animation object parameter:

While we can set animations for Entities, What I meant by the Topic that
we have no control over the joints them selves, similar to, forexample:

MyAvatar.setJointData( "joinName", <vec3>, <quaternion>)
should have an alternative

Entity.setJointData(uuid,jointName,vec3,quaternion)
for entity manipulation.

It also brings in a question of the lack of “context”,
How come any of the Entities cannot be bound to a variable that is the context of the object?


var entityVar = Entity.getEntity("uuid");
entityVar.setJointData("jointName",vec3,quaternion);

This way we could do procedural animation for Entities, or allow more advanced “puppeteering” of entities using controllers. Or have wheels of a car spin at the rate at which its traveling at / turn the direction its facing, without having to create, speed up / slow down specific animations.


#5

This is probably because the avatar animations are handled by the AvatarMixer assignment client, and the entities are handled by the EntityServer. Streaming animation data for entities might probably be overkill. You could try asking one of the devs.


#6

Ah, this explains the reason why Translation in entity animations do not work the same as the way as Avatar Animations even thought the change was made to Avatars.


#7

Many objects have ‘bones’. Leaf springs, coil springs, struts, wishbone suspensions, hinges, sliders, that sort of thing. However will these kinds of constructs get simulated with high fidelity articulation and/or constrained movement if there is no architecture in entities or assemblies of entities to describe the attachment points, the force and damping kinematics, or the rip force limits?


#8

You make an Entity into an Avatar (bot/npc/etc) by setting IsAvatar = true;

Now you can use all the Avatar functions on the entity.


#9

Oh cool.

Although that doesn’t sound very intuitive in naming. As it implies anything with bones is an avatar


#10

I am necroing this thread because it is coming back around to this with the pet competition, as this is not sufficient.

IsAvatar only applies to AC driven NPCs, it does not apply to just client scripts.
There still needs to be a way to allow for entities to have a bone animation system that runs on its own instance. It should also be able to stack animations to create animation blends (walking, running while looking at a direction, or doing an animation action while doing something else, etc).

Forexample, I cannot make an pet, that can be created in any domain (thus non-AC) glances back nearby people sometimes when they are looking at it, without rotating the entire entity to face you. Instead I should be able to control a neck bone to make the head turn.

For now though, it can be worked around with, by decapitating the head and reattaching it as a separate entity, ala SL primitive style. However I feel the animation quality of this wouldnt be as great as just rotating a bone.

Maybe there should be a new type of Entity (maybe even called a Daemon ala Snow Crash, or just a Puppet) which can be controlled by scripts running in the interface (not entity scripts). Limiting factor could be it so that a client can only update a certain amount of bones per second, something that is settable by the permissions on the domain side.

These would be also distributed in the Avatar mixer instead of Entities.


#11

heya – you can already set joint data for models. we did a doppelganger a while back, which was an FBX of your avatar that has joints that move with your avatar joints. check out the github repo and look at script-archive/dressing_room/doppelganger.js, specifically these two functions:

function getJointData(avatar) {
var allJointData = [];
var jointNames = MyAvatar.jointNames;
jointNames.forEach(function(joint, index) {
    var translation = MyAvatar.getJointTranslation(index);
    var rotation = MyAvatar.getJointRotation(index)
    allJointData.push({
        joint: joint,
        index: index,
        translation: translation,
        rotation: rotation
    });
});

return allJointData;
}

function setJointData(doppelganger, relativeXforms) {
var jointRotations = [];
var i, l = relativeXforms.length;
for (i = 0; i < l; i++) {
    jointRotations.push(relativeXforms[i].rot);
}
Entities.setAbsoluteJointRotationsInObjectFrame(doppelganger.id, jointRotations);

return true;
}

#12

Ive been careful with looking into the script-archives because I am not sure what works and what doesnt work after finding the Assets example over there.

Ill give it a shot though


#13

Yeah, I just checked that out. Seems to work interestingly, althought It would be preferable if it had priority over the entity animation. clear/set rotation if enabled or disabled., Which… even when added to an update thread, cannot keep up.


Is there a way to do … in HiFi?
#14

interesting – you’re trying to play an animation on the .fbx at the same time as you manipulate its bones? i haven’t tried that. only manipulating bones on the static .fbx


#15

the javascript update thread maxes at 60hz


#16

Yes, the entity has an animation set to it, Id like to be able to override specific parts of the regular animations and combine it to create reactive animations (such as entity looks at owner, etc) It wont make it to this version, But I can imagine it being useful in future npc creations that do not use AC.


#17

I started trying that because that is how many of my SL creations are made, but the sheer level of scripting complexity and not implemented features here makes this something several months down the road for me.


#18

took a dive into the code with a co-worker – unfortunately it looks like model animation and setting model joints do fight. we’ll add a task to improve this – the avatar animation system is more sophisticated and can handle blending etc, we’d like to get models to the same level. in the meantime, i’d recommend using only one system at a time when maniupulating models: either setting the joints manually, or playing an animation.

thanks for pointing this out!


#19

OK, what has happened here in the last two years? Many methods like Entities.setAbsoluteJointRotationsInObjectFrame and setAbsoluteJointRotationInObjectFrame are no longer defined, although they are still listed in the API reference. Some of the other Entities joint functions are still there, some work (like Entities.getJointNames) but when I call Entities.setLocalJointRotation to try to rotate a joint, it has no effect.
Sample script, for testing a rippling flag animation:

(function ()
{
print("hello world");
var mps=1.0;        //number of moves per second
var ang=0.0;        //position in the phase of movement
var dang=0.017;     //how much to change the phase every time
var self = this;    //save this for later
var myID;           //place to store my entityID for Wave

function Wave()     //function to wave a mesh flag back and forth
{
    var w = Math.cos(ang);  //generate a number [-1,1]
    ang += dang;            //change the phase
    var rot=Quat.fromPitchYawRollRadians(0.0,0.0,w);
    print(JSON.stringify(rot));
    for (var i=4;i<=6;i++)
    {
        Entities.setLocalJointRotation(myID,i,rot);
//          setAbsoluteJointRotationInObjectFrame(myID,i,rot);
    }
} //end Wave

this.preload = function(entityID)
{
    myID = entityID;        //save the entity id for Wave
                                    //set a timer to run Wave often
    var joints= Entities.getJointNames(entityID);
//      print(JSON.stringify(joints,null,4));
    for (var i=0;i<joints.length;i++)
        print(Entities.getJointIndex(entityID,joints[i])+" : "+joints[i]);
    self.intervalID = Script.setInterval(Wave,1000/mps);
}; //end loading preload

this.unload = function()    //this never gets called if you remove the script....
{
    Script.clearInterval(self.intervalID);
}

Script.scriptEnding.connect(
    function()
    {
        Script.clearInterval(self.intervalID);
    }
);
} //end main function
)

Typical output looks like this:

    hello world
    0 : Camera
    1 : Lamp
    2 : Plane
    3 : Armature
    4 : Armature|Bone
    5 : Armature|Bone.001
    6 : Armature|Bone.002
    {"x":0,"y":0,"z":0.4794255495071411,"w":0.8775825500488281}
    {"x":0,"y":0,"z":0.4793621301651001,"w":0.8776171803474426}
    {"x":0,"y":0,"z":0.4791719317436218,"w":0.8777210712432861}
    {"x":0,"y":0,"z":0.4788549244403839,"w":0.8778940439224243}
    {"x":0,"y":0,"z":0.47841113805770874,"w":0.8781359791755676}
    {"x":0,"y":0,"z":0.4778405725955963,"w":0.8784465789794922}
    {"x":0,"y":0,"z":0.4771433174610138,"w":0.8788254857063293}

#20

Look carefully at your output. You have a Camera, a Light, a Plane… Probably a default settings .fbx export from Blender, yeah?

Try this:

Remove everything in your Blender scene except the armature and the mesh. (or set your export settings properly)

Do be certain to rename your bones without dots in the name.

in the words of famous Chris

‘good luck’