Sorry, I spent a little time looking over your code, but I couldn't immediately 
pick out what was wrong with it. For simplicity's sake, you could avoid the 
creation of rot_mat by just using osg::Quat's multiplication operator, and then 
setting the new value of top_of_prev_unrotated_cylinder directly to 
top_of_new_unrotated_cylinder (saves you an inverse matrix calculation). Is 
there any reason you're not using osg::Quat's makeRotate() function?

osg::PositionAttitudeTransform allows you to declare a pivot point (in local 
space), around which the rotation will occur. Perhaps adjusting the pivot point 
to be the bottom of each cylinder would fix it? Another idea might be to setup 
each cylinder so that they share a pivot point (the bottom of the first 
cylinder). If you position each cylinder by using its center point instead of 
using the position value of the osg::PositionAttitudeTransform, you just need 
to apply the same rotation to each cylinder and they will line up. Either way, 
I'd recommend testing your method with zero rotation first as a quick sanity 
check, and then adding pivot points and rotation. 

Hope that helps!

Alex

-----Original Message-----
From: osg-users [mailto:[email protected]] On Behalf 
Of Laura Mac
Sent: Wednesday, May 28, 2014 10:47 AM
To: [email protected]
Subject: Re: [osg-users] Finding position of top of rotated cylinder


Bush, Alex W. wrote:
> What exactly is wrong with the cylinders? Without seeing a short code sketch 
> or at least a picture it's hard to tell what is wrong with your method.
> 
> If I had to guess, I'd probably take a look at the order of your 
> transformations. Make sure your displacement of the second cylinder is 
> happening before the transformation (if you reverse these you will get two 
> parallel cylinders positioned on top of each other vertically).
> 
> Alex
> 


Thanks for the response! I will provide a short sketch of a function which is 
recursively called for each cylinder rendered. I am also attaching a picture of 
what this function renders when recursively called four times. Thank you very 
much.


Code:

void Stem::make_stem_segments(float stem_len, int num_segments, int seg_index, 
float base_radius, float head_radius, osg::Vec3 top_of_prev_unrotated_cylinder, 
osg::Vec3 top_of_prev_rotated_cylinder, float rotate_degrees_second_half, float 
rotate_degrees_first_half, float random_degrees_rotation, int left) {
        if (num_segments == 0)
                return;

        float rotation_amount;
        float seg_length = stem_len / this->num_segments;

        // Determine whether segment is in first or second half of stem.
        if (seg_index >= (this->num_segments / 2)) {
                rotation_amount = rotate_degrees_second_half + 
random_degrees_rotation;
        } else {
                rotation_amount = rotate_degrees_first_half + 
random_degrees_rotation;
        }

        // Render vertical cylinder
        osg::Geode* stem_geode = new osg::Geode();
        osg::PositionAttitudeTransform* stem_transform =
                new osg::PositionAttitudeTransform();
        stem_transform->addChild(stem_geode);   
        osg::Cylinder * cylinder = new osg::Cylinder(osg::Vec3(0.0, 0.0, 
seg_length / 2), base_radius, seg_length);
        osg::ShapeDrawable* cylinder_drawable = new 
osg::ShapeDrawable(cylinder);
        stem_geode->addDrawable(cylinder_drawable);

        // Position new cylinder.
        
stem_transform->setPosition(osg::Vec3(top_of_prev_unrotated_cylinder.x(), 
top_of_prev_unrotated_cylinder.y(), top_of_prev_unrotated_cylinder.z()));

        osg::Vec3 top_of_new_unrotated_cylinder = 
osg::Vec3(top_of_prev_unrotated_cylinder.x(), 
top_of_prev_unrotated_cylinder.y(), top_of_prev_unrotated_cylinder.z() + 
seg_length);

        // Rotate cylinder.
        osg::Quat rot_quat = osg::Quat(osg::DegreesToRadians(0.0f),
                osg::Vec3d(0, 0, 
1)))*(osg::Quat(osg::DegreesToRadians(rotation_amount),
                osg::Vec3d(1, 0, 0)))*(osg::Quat(osg::DegreesToRadians(0.0),
                osg::Vec3d(0, 1, 0));

        stem_transform->setAttitude(rot_quat);

        const osg::Matrixd &rot_mat = osg::Matrixd(rot_quat);

        top_of_prev_rotated_cylinder = rot_mat * top_of_new_unrotated_cylinder;
        osg::Matrixd inverse;
        if (!inverse.invert(rot_mat))
                std::cout << "COULD NOT COMPUTE INVERSE" << std::endl;

        top_of_prev_unrotated_cylinder = inverse * top_of_prev_rotated_cylinder;

        this->stem->addChild(stem_transform);

        // Recursively make another stem segment
        make_stem_segments(stem_len, num_segments - 1, seg_index + 1, 
base_radius, head_radius, top_of_prev_unrotated_cylinder, 
top_of_prev_rotated_cylinder, rotate_degrees_second_half, 
rotate_degrees_first_half, random_degrees_rotation, 1); }


[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=59591#59591



_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to