Click here to Skip to main content
15,886,518 members

How to rotate 3D objects

R2d1 asked:

Open original thread
Hello everybody.
In my application I have 3D cube.
On cube sides I will place any controls.
At the borders I have a buttons for rotate this cube to +-90 degree.
But in fact I have rotate the camera, not cube. And I'd like to rotate exactly Cube.
<Window.Resources>
        <DiffuseMaterial x:Key="CubeSideMaterial" Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="LimeGreen"/>
        <LinearGradientBrush x:Key="BlackBackground" EndPoint="1,0" StartPoint="0,0.3">
            <GradientStop Color="LightGray" Offset="0.8"/>
            <GradientStop Color="DarkGray" Offset="0.7"/>
            <GradientStop Color="Black" Offset="0"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="GreenBackground" EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="GreenYellow" Offset="0.824"/>
            <GradientStop Color="DarkGreen" Offset="0"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="PressedButton" EndPoint="0.5,1" StartPoint="0.5,0" MappingMode="RelativeToBoundingBox">
            <GradientStop Color="Blue" Offset="0"/>
            <GradientStop Color="White" Offset="0.816"/>
            <GradientStop Color="Violet" Offset="0.744"/>
        </LinearGradientBrush>
        <ControlTemplate x:Key="ButtonLook">
            <Grid Background="Khaki" ShowGridLines="True" >
                <Rectangle x:Name="Rect" Width="20" Height="11">
                    <Rectangle.Stroke>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Black" Offset="1"/>
                            <GradientStop Color="Green"/>
                        </LinearGradientBrush>
                    </Rectangle.Stroke>
                    <Rectangle.Fill>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Gray" Offset="1"/>
                            <GradientStop Color="Green"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
            </Grid>
        </ControlTemplate>
    </Window.Resources>
    <Grid Background="Black">
        <Viewport3D x:Name="view" Margin="0,0,0,-139"  ClipToBounds="False" RenderOptions.EdgeMode="Aliased" IsHitTestVisible="True">
            <Viewport3D.Camera>
                <PerspectiveCamera x:Name="camera" FieldOfView="60" Position="0,-0.2,6" LookDirection="0.000001,-0.0005,-0.08" UpDirection="0,1,0">
                    <PerspectiveCamera.Transform>
                        <RotateTransform3D x:Name="rot" CenterY="0" CenterX="0" CenterZ="0">
                            <RotateTransform3D.Rotation>
                                <!-- rotation -->
                                <AxisAngleRotation3D x:Name="camRotation" Axis="0,1,0" Angle="0"/>
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>
                    </PerspectiveCamera.Transform>                
                </PerspectiveCamera>
            </Viewport3D.Camera>
            <ModelVisual3D x:Name="model">
                <ModelVisual3D.Content>
                    <Model3DGroup x:Name="group">
                        <AmbientLight Color="White" />
                        <DirectionalLight Color="White" Direction="-1,-1,-10"></DirectionalLight>
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
            <Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
                <Viewport2DVisual3D.Geometry>
                    <MeshGeometry3D Positions="-1.77,-1,1.77 1.77,-1,1.77 1.77,1,1.77 -1.77,1,1.77"
                                    TextureCoordinates="0,1 1,1 1,0 0,0"
                                    TriangleIndices="0,2,3 0,1,2"/>
                </Viewport2DVisual3D.Geometry>
                <Grid x:Name="FrontPanel" ShowGridLines="False" IsHitTestVisible="True" Margin="0" Background="{StaticResource BlackBackground}">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="15"/>
                        <RowDefinition Height="15" MaxHeight="15"/>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="20"/>
                        <ColumnDefinition />
                        <ColumnDefinition/>
                        <ColumnDefinition Width="20"/>
                    </Grid.ColumnDefinitions>
                    <Label Content="Front" Grid.Row="0" Grid.Column="2" Foreground="LightBlue"/>
                    <Button Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2" 
                            Content="+90" 
                            Foreground="Black" 
                            FlowDirection="LeftToRight" 
                            FontSize="3" 
                            VerticalContentAlignment= "Center"
                            HorizontalAlignment="Right"
                            Width="20"
                            Height="10"
                            Margin="0,2,0,2"
                            ToolTip="Типа ткни сюда и Опа!" 
                            Click="SeeOthers_Click" />
                    <!--<Image Grid.Column="4" Grid.Row="4" Grid.RowSpan="2" HorizontalAlignment="Right" Margin="2,1,2,12" Name="image1" Stretch="Fill" Width="25" Height="20" Source="monitor2.jpg"/>-->
                    <Button Grid.Column="0" 
                            Grid.Row="1" 
                            Height="10" 
                            Width="20" 
                            Content="-90" 
                            Click="SeeOthers_Click" 
                            FontSize="3" 
                            BorderThickness="0" 
                            Foreground="Black" />
                </Grid>
            </Viewport2DVisual3D>
            <!-- cube right side -->
            <Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
                <Viewport2DVisual3D.Geometry>
                    <MeshGeometry3D Positions="1.77,-1,1.77 1.77,1,1.77 1.77,1,-1.77, 1.77,-1,-1.77"
                                    TextureCoordinates="0,1 0,0 1,0 1,1 "
                                    TriangleIndices="0,3,2 0,2,1"/>
                </Viewport2DVisual3D.Geometry>
                <Grid x:Name="RightPanel" IsHitTestVisible="True" Background="{StaticResource BlackBackground}">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="15"/>
                        <RowDefinition Height="15" MaxHeight="15"/>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition />
                        <ColumnDefinition/>
                        <ColumnDefinition Width="30"/>
                    </Grid.ColumnDefinitions>
                    <Button Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2" 
                            Content="+90" 
                            Foreground="Black" 
                            FlowDirection="LeftToRight" 
                            FontSize="3" 
                            VerticalContentAlignment= "Center"
                            HorizontalAlignment="Right"
                            Width="20"
                            Height="10"
                            Margin="0,2,0,2"
                            ToolTip="Типа ткни сюда и Опа!" 
                            Click="SeeOthers_Click" />
                    <Label Content="Right" Grid.Row="0" Grid.Column="2" Foreground="LightBlue"/>
                    <Button Grid.Column="0" 
                            Grid.Row="1" 
                            Height="10" 
                            Width="20" 
                            Content="-90" 
                            Click="SeeOthers_Click" 
                            FontSize="3" 
                            BorderThickness="0" 
                            Foreground="Black" />
                </Grid>
            </Viewport2DVisual3D>
            <!-- cube back side -->
            <Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
                <Viewport2DVisual3D.Geometry>
                    <MeshGeometry3D Positions="1.77,1,-1.77 1.77,-1,-1.77 -1.77,1,-1.77, -1.77,-1,-1.77"
                                    TextureCoordinates=" 0,0 0,1 1,0 1,1"
                                    TriangleIndices="1,3,2 1,2,0"/>
                </Viewport2DVisual3D.Geometry>
                <Grid x:Name="BackPanel"  Background="{StaticResource BlackBackground}" IsHitTestVisible="True">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="15"/>
                        <RowDefinition Height="15" MaxHeight="15"/>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition />
                        <ColumnDefinition/>
                        <ColumnDefinition Width="30"/>
                    </Grid.ColumnDefinitions>
                    <Button Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2" 
                            Content="+90" 
                            Foreground="Black" 
                            FlowDirection="LeftToRight" 
                            FontSize="3" 
                            VerticalContentAlignment= "Center"
                            HorizontalAlignment="Right"
                            Width="20"
                            Height="10"
                            Margin="0,2,0,2"
                            ToolTip="Типа ткни сюда и Опа!" 
                            Click="SeeOthers_Click" />
                    <Label Content="Rear" Grid.Row="0" Grid.Column="2" Foreground="LightBlue"/>
                    <Button Grid.Column="0" 
                            Grid.Row="1" 
                            Height="10" 
                            Width="20" 
                            Content="-90" 
                            Click="SeeOthers_Click" 
                            FontSize="3" 
                            BorderThickness="0" 
                            Foreground="Black" />
                </Grid>
            </Viewport2DVisual3D>
<!-- cube left side -->
            <Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
                <Viewport2DVisual3D.Geometry>
                    <MeshGeometry3D Positions="-1.77,-1,-1.77 -1.77,1,-1.77 -1.77,1,1.77, -1.77,-1,1.77"
                                    TextureCoordinates=" 0,1 0,0 1,0 1,1"
                                    TriangleIndices="0,3,2 0,2,1"/>
                </Viewport2DVisual3D.Geometry>
                <Grid x:Name="LeftPanel"  Background="{StaticResource BlackBackground}" IsHitTestVisible="True">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="15"/>
                        <RowDefinition Height="15" MaxHeight="15"/>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition />
                        <ColumnDefinition/>
                        <ColumnDefinition Width="30"/>
                    </Grid.ColumnDefinitions>
                    <Button Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2" 
                            Content="+90" 
                            Foreground="Black" 
                            FlowDirection="LeftToRight" 
                            FontSize="3" 
                            VerticalContentAlignment= "Center"
                            HorizontalAlignment="Right"
                            Width="20"
                            Height="10"
                            Margin="0,2,0,2"
                            ToolTip="Типа ткни сюда и Опа!" 
                            Click="SeeOthers_Click" />
                    <Label Content="Left" Grid.Row="0" Grid.Column="2" Foreground="LightBlue"/>
                    <Button Grid.Column="0" 
                            Grid.Row="1" 
                            Height="10" 
                            Width="20" 
                            Content="-90" 
                            Click="SeeOthers_Click" 
                            FontSize="3" 
                            BorderThickness="0" 
                            Foreground="Black" />
                </Grid>
            </Viewport2DVisual3D>
        </Viewport3D>
        <Button Height="92" HorizontalAlignment="Left" Margin="56,0,0,40" Name="button1" VerticalAlignment="Bottom" Width="186" Click="button1_Click">Button</Button>
    </Grid>

And this is C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using Microsoft.Win32;
namespace WpfApplication4
{
        public partial class Window1 : Window
    {
        System.Windows.Threading.DispatcherTimer clock = new System.Windows.Threading.DispatcherTimer();
        System.Windows.Threading.DispatcherTimer Zoomclock = new System.Windows.Threading.DispatcherTimer();
        public Window1()
        {
            InitializeComponent();
            //rotation clock
            clock.Tick += new EventHandler(clock_Tick);
            clock.Interval = new TimeSpan(0, 0, 0, 0, 20);
            Zoomclock.Tick += new EventHandler(Zoomclock_Tick);
            Zoomclock.Interval = new TimeSpan(0, 0, 0, 0, 15);
        }
        //this is event for zooming
        void Global_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            camera.Position = new Point3D(
            camera.Position.X,
            camera.Position.Y,
            camera.Position.Z - e.Delta / 250D);
                 
        }
        //rotation angle - for rotation on Y-axis
        double rotAngle = 90;
        double CamRot=0;
        bool flagfirst = true;
        void clock_Tick(object sender, EventArgs e)
        {
            if (flagfirst==true) rotAngle = rotAngle + CamRot;
            if (rotAngle > 0) 
            { 
                camRotation.Angle += 5;
                if (camRotation.Angle >= rotAngle)
                {
                    clock.Stop();
                    CamRot = camRotation.Angle;
                    flagfirst = true;
                    camera.FieldOfView = 50;
                }
            }
            else 
            { 
                camRotation.Angle -= 5; 
                if (camRotation.Angle <= rotAngle) 
                { 
                    clock.Stop(); 
                    CamRot = camRotation.Angle;
                    flagfirst = true;
                    camera.FieldOfView = 50;
                }
            }
            flagfirst = false;
        }
        double CamDist = 60;
        void Zoomclock_Tick(object sender, EventArgs e)
        {
            camera.FieldOfView += 5;
            if (camera.FieldOfView >= 100) Zoomclock.Stop();
        }

        //this would need to be global key but i didn't have time to finish this
        //it have problem when some control get focus cube stop to rotate
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            double angle = 5;
            if (e.Key == Key.Left)
                if (camRotation.Angle == 0) camRotation.Angle = 360 - angle;
                else camRotation.Angle -= angle;
            else if (e.Key == Key.Right) camRotation.Angle += angle;
        }

        //navigation button which goes to users panel
        private void SeeOthers_Click(object sender, RoutedEventArgs e)
        {
            Zoomclock.Start();
            Rotar(sender, e);
        }
        double CurrentAngle = 0;
        private void Rotar(object sender, RoutedEventArgs e)
        {
            if (Convert.ToString(((System.Windows.Controls.ContentControl)(e.OriginalSource)).Content) == "+90")
            {
                rotAngle = CurrentAngle + 90;
                clock.Start();
            }
            if (Convert.ToString(((System.Windows.Controls.ContentControl)(e.OriginalSource)).Content) == "-90")
            {
                rotAngle = CurrentAngle - 90;
                clock.Start();
            }
            CurrentAngle = rotAngle;
            if (CurrentAngle >= 360) { CurrentAngle = 0; }
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        private void label3_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Transform3D My3DTrans = new RotateTransform3D();
            //My3DTrans.
        }
    }
}


Please help me, and one more.
Who know please advice - Why I have a troubles with rotation forward and backward?

Thanks.
Tags: C#, WPF, 3D

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900