AB4D Forum

Full Version: Kinematic Chain
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I have a question if it is possible to build up a kinematic chain with Ab3d.


Imagine you have two 3D Models.
The first one is positioned at a fix point. You have the length and a specific angle (e.g. around the Y-Axis)  of the first 3D Model.
The question is: Has Ab3D a possibility to place the second 3D Model by only getting the lenght and the angle of the first 3D Model?

I have here some handmade illustration which, hopefully, makes it more understandable, what I try to do.

I'm looking forward to any replies.

Best Regards,
Nick

[attachment=75][attachment=76]
WPF 3D object model supports transformations on hierarchies. This means that if you organize your objects in a hierarchical way you can apply transformation to parent objects and the child objects will be also transformed.

In WPF 3D you can organize objects with using Model3D objects or ModelVisual3D objects.

With using ModelVisual3D objects, you can group the objects with adding child ModelVisual3D to another ModelVisual3D.
The following sample is using BoxVisual3D objects from Ab3d.PowerToys library to group 3 boxes (similar to your schema):

Code:
<Viewport3D Name="MainViewport">

   <visuals:BoxVisual3D x:Name="BlueBox" CenterPosition="0 0 0" Size="100 10 10" Material="LightBlue">
       <visuals:BoxVisual3D.Transform>
           <Transform3DGroup>
               <!-- The first translate is used to adjust the center of rotation -->
               <TranslateTransform3D OffsetX="40" />
               <RotateTransform3D>
                   <RotateTransform3D.Rotation>
                       <AxisAngleRotation3D Axis="0 1 0" Angle="20" />
                   </RotateTransform3D.Rotation>
               </RotateTransform3D>
               <!-- The second translate is used move the rotate object -->
               <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0" />
           </Transform3DGroup>
       </visuals:BoxVisual3D.Transform>

       <visuals:BoxVisual3D x:Name="OrangeBox" CenterPosition="0 0 0" Size="40 5 10" Material="Orange">
           <visuals:BoxVisual3D.Transform>
               <Transform3DGroup>
                   <!-- The first translate is used to adjust the center of rotation -->
                   <TranslateTransform3D OffsetX="20" />
                   <RotateTransform3D>
                       <RotateTransform3D.Rotation>
                           <AxisAngleRotation3D Axis="0 1 0" Angle="30" />
                       </RotateTransform3D.Rotation>
                   </RotateTransform3D>
                   <!-- The second translate is used move the rotate object -->
                   <TranslateTransform3D OffsetX="40" OffsetY="7.5" OffsetZ="0" />
               </Transform3DGroup>
           </visuals:BoxVisual3D.Transform>

           <visuals:BoxVisual3D x:Name="GreenBox" CenterPosition="0 0 0" Size="30 5 5" Material="Green" >
               <visuals:BoxVisual3D.Transform>
                   <Transform3DGroup>
                       <!-- The first translate is used to adjust the center of rotation -->
                       <TranslateTransform3D OffsetX="15" />
                       <RotateTransform3D>
                           <RotateTransform3D.Rotation>
                               <AxisAngleRotation3D Axis="0 1 0" Angle="-110" />
                           </RotateTransform3D.Rotation>
                       </RotateTransform3D>
                       <!-- The second translate is used move the rotate object -->
                       <TranslateTransform3D OffsetX="15" OffsetY="5" OffsetZ="0" />
                   </Transform3DGroup>
               </visuals:BoxVisual3D.Transform>
           </visuals:BoxVisual3D>
       </visuals:BoxVisual3D>
   </visuals:BoxVisual3D>
               
</Viewport3D>


As you see the each BoxVisual3D is transformed with 3 transformations. The first TranslateTransform3D is used to move the object before it is rotated - this acts as adjustment to the center of rotation. Without this transformation, the object would be rotated around (0,0,0) position - this is also the center position of each Box. Note that the amount of translation is around half the object size - this moves the center of rotation to the edge of the object. Then the object is rotated and finally translated to its final position.

You can copy this XAML into some existing XAML (for example into the Objects3D/AllVisualsSample.xaml from the Ab3d.PowerToys samples) and play with different rotation angles and translations in Visual Studio designer.


Another option is to use Model3D objects instead of ModelVisual3D objects. With Model3D objects you create Model3DGroups (that contain other Model3D objects in the Children collection) and GeometryModel3D objects that represent the 3D models. Then you apply transformations to the Model3DGroups. 

For example:
Code:
var blueModelTransformGroup = new Transform3DGroup();
blueModelTransformGroup.Children.Add(new TranslateTransform3D(40, 0, 0));
blueModelTransformGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 20)));
blueModelTransformGroup.Children.Add(new TranslateTransform3D(0, 0, 0));

var blueModel3DGroup = new Model3DGroup();
blueModel3DGroup.Transform = blueModelTransformGroup;

var blueModel3D = Ab3d.Models.Model3DFactory.CreateBox(new Point3D(0, 0, 0), new Size3D(100, 10, 10), new DiffuseMaterial(Brushes.LightBlue));
blueModel3DGroup.Children.Add(blueModel3D);


var orangeModel3DGroup = new Model3DGroup();
blueModel3DGroup.Children.Add(orangeModel3DGroup);



var orangeModelTransformGroup = new Transform3DGroup();
orangeModelTransformGroup.Children.Add(new TranslateTransform3D(20, 0, 0));
orangeModelTransformGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 30)));
orangeModelTransformGroup.Children.Add(new TranslateTransform3D(40, 7.5, 0));

orangeModel3DGroup.Transform = orangeModelTransformGroup;

var orangeModel3D = Ab3d.Models.Model3DFactory.CreateBox(new Point3D(0, 0, 0), new Size3D(40, 5, 10), new DiffuseMaterial(Brushes.Orange));
orangeModel3DGroup.Children.Add(orangeModel3D);



var greenModel3DGroup = new Model3DGroup();
orangeModel3DGroup.Children.Add(greenModel3DGroup);


var greenModelTransformGroup = new Transform3DGroup();
greenModelTransformGroup.Children.Add(new TranslateTransform3D(15, 0, 0));
greenModelTransformGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), -110)));
greenModelTransformGroup.Children.Add(new TranslateTransform3D(15, 5, 0));

greenModel3DGroup.Transform = greenModelTransformGroup;

var greenModel3D = Ab3d.Models.Model3DFactory.CreateBox(new Point3D(0, 0, 0), new Size3D(30, 5, 5), new DiffuseMaterial(Brushes.Green));
greenModel3DGroup.Children.Add(greenModel3D);


var modelVisual3D = new ModelVisual3D();
modelVisual3D.Content = blueModel3DGroup;
MainViewport.Children.Add(modelVisual3D);

// To see the hierarchical structure of the models,
// you can put breakpoint in the next line
// and then run the following in the Visual Studio Immediate Window:
// blueModel3DGroup.DumpHierarchy()


If you are using 3D modelling application to create your models, you can also organize your objects into hierarchies. Then you need to export the object into a 3D file format that support hierarchies - for example 3ds, collada or fbx (obj and some other text file formats do not support hierarchies ). Then you can use Assimp importer or Reader3ds (for 3ds files) to import the models.

To see an example of that, please open the Ab3d.PowerToys.Reader3dsSamples solution (comes with Ab3d.PowerToys) and check how a robot arm model is transformed after it is read from 3ds file.