Jump to content

Arcrotate target offset?


JCPalmer
 Share

Recommended Posts

I have run into this multiple times, so thought I would mention it.  If you set a mesh as the target of an arcrotate camera, it pints to the origin.  The origin is not always the center, especially for characters.  There is good reason to put the origin so that their feet are on the ground.

You can set the target as an absolute Vector3, but then it will not follow the character.  Is there some way to get the camera to point to the bounds center?  Or at least calculate an offset at the point of the target set?  Pointing at a character's feet makes things difficult. 

Link to comment
Share on other sites

@JCPalmer : Well Jeff, you might want to try this:

1. Select character rig - put it in rest position.

2. In Rig Edit mode - Select the Hip bone (or higher up the bone chain if you want a different point of focus for the camera)

3.Armature->Snap->Cursor to Selected.

4.Exit Rig Edit and Add ->Mesh ->Cube ans scale cube so it is hidden inside the hips. Apply Scale.

5 Parent the Cube to the Rig - will of course add 8 vertices.

6. Now use the Cube to set up your arcRotate camera.

I have not tried exporting it but see image below

But maybe you are looking for something more generic.

cheers, gryff :)

arc_camera1.png

Link to comment
Share on other sites

@Deltakosh, think you could have an optional argument as well:

public setTarget(target: Vector3, toBoundingCenter = false): void {

Implementation wise, computing a fixed offset when setting target might be good.  Sit, squat, jumping jacks would have the camera bobbing.  (Could look weird especially if breast shape keys are going the other way).  Either way much better than a situation where the feet are the center.  When you zoom, the head disappears.

Selection_004.jpg

@gryff, your solution is good in that I do not have to run alpha code.  Too many variables to deal with while getting my own code to run.  Might be able to do with an empty (zero verts / no draw) as well.

Link to comment
Share on other sites

5 hours ago, JCPalmer said:

Might be able to do with an empty (zero verts / no draw) as well.

@JCPalmer : Actally Jeff, it seems that you can set an armature as a target - and if you do, then chose a specific bone like Hip or Chest. So maybe no need for the cube.

5 hours ago, JCPalmer said:

Sit, squat, jumping jacks would have the camera bobbing.

And somersaults may induce vomiting :o

cheers, gryff :)

Link to comment
Share on other sites

Why would you just not add a certain number of units up y to the root of the target and make that your target?

 

that way the camera does not move if the characters hips move or what ever else your choosing to target on the mesh.  The root of it should be on the ground and dead center, and only come off the ground if the character jumps, I mean if you want the camera to sway around with the animation then yeah putting a point as a child and tracking that is cool, but all that can be simulated with sway variables when you target the root.

Link to comment
Share on other sites

@gryff, That is only in Blender.  A bone is just a Matrix on the BJS side.  Target must have Vector3 position property.

Anyway, I did not want to have to change my blends later, when moving to 2.5, so I did it all on the javascript in the html.  I added an AbstractMesh, called cameraTarget & used it in the camera constructor.  I actually have 3 models, but only 1 is active at a time.  This provides good testing of pose scaling across skeletons with bone lengths.  Each model is its own .JS file.  The .JS are not in html header right now, so they are dynamically brought in.

After an instance is made of a model, I register an afterWorldMatrixUpdate callback to transfer the x & z.  The y is set to the center in a different place (prepModel), so you can keep switching back and forth.

cameraTarget.position.y = currentModel.getBoundingInfo().boundingBox.center.y;

I also have since realized that animating a skeleton will not change the bounding box, even if you request it be refreshed.  It is based on vertices, and the final position after applying the skeleton are only known on GPU.

This works fine, & a major improvement.  I have been so frustrated at trying to get a good look at the head.  I still cannot believe I can!

FYI, hear is the code which does registration:

function jsPostLoad(){
    var type = modeltype.options[modeltype.selectedIndex].value;
    if (type === 'Female Jogger'){
    	joggerModel = new female_runner.Female_runner_Body("Jogger", scene, materialsRootDir);
      	joggerModel.entranceMethod = QI.Mesh.GATHER;
       	joggerModel.assignPoseLibrary("game_rig_library");
       	joggerModel.registerAfterWorldMatrixUpdate(
	    function(){
   		cameraTarget.position.x = joggerModel.position.x;
   		cameraTarget.position.z = joggerModel.position.z;
   	    }
         );

       	joggerModel.assignPoseImmediately("standing");
            
    }else if (type === 'Toddler'){
       	toddlerModel = new dead_baby.Baby_Body("toddler", scene, materialsRootDir);
       	toddlerModel.entranceMethod = QI.Mesh.GATHER;
       	toddlerModel.assignPoseLibrary("game_rig_library");
       	toddlerModel.registerAfterWorldMatrixUpdate(
       	    function(){
       		cameraTarget.position.x = toddlerModel.position.x;
       		cameraTarget.position.z = toddlerModel.position.z;
            }
  	);

       	toddlerModel.assignPoseImmediately("standing");

   }else{
	meterScaledmodel = new meter_scaled.Meter_Model_Body("inMeters", scene, materialsRootDir);
	meterScaledmodel.entranceMethod = QI.Mesh.GATHER;
	meterScaledmodel.assignPoseLibrary("game_rig_library");
	meterScaledmodel.registerAfterWorldMatrixUpdate(
       	    function(){
       		cameraTarget.position.x = meterScaledmodel.position.x;
       		cameraTarget.position.z = meterScaledmodel.position.z;
       	    }
       	);

	meterScaledmodel.assignPoseImmediately("standing");
    }
    // remove loadToken, though the textures have added their own
    scene._removePendingData(loadingToken);
        
    prepModel(type);
}

 

@Pryme8, because then the target is just a vector.  If the mesh moves camera would not follow.  There was a recent topic about a ArcFollow camera.  I neither knew this existed, nor see the need for it.  ArcRotate follows provided the target is a mesh.

Link to comment
Share on other sites

add the meshes position to the camera position.  3d arc follow cams are easy.

x = r*cos(phi)*sin(theta);
y = r*sin(phi)*sin(theta);
z = r*cos(theta);

x+= mesh.position.x, y+=mesh.position.y, z+=mesh.position.z;

just remember cos, sin, sin, sin, cos; and phi theta phi theta theta

 

Link to comment
Share on other sites

All this talk is about temporary solutions until the toBoundingCenter argument is added (for 2.5, I presume) :

public setTarget(target: Vector3, toBoundingCenter = false): void {

Since, I already implemented my temp code, I can continue to finish my tasks without using alpha code which might be problematic.  No more help is required, but thanks Guys!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...