Anonymous
Wie man das Objekt um gegebenen Winkel dreht
Post
by Anonymous » 23 Sep 2025, 14:16
Ich habe das Tutorial unter
http://viewport3d.com/trackball.htm verwendet, um Trackball zu programmieren. Ich habe Achse und Winkel berechnet, aber ich weiß nicht, wie man Rotation auf Objekt anwendet. Irgendwelche Hilfe? < /P>
Code besteht aus mehreren Dateien. Hier sind zwei wichtigste.
Code: Select all
using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
namespace _038trackball
{
public partial class Form1
{
#region Camera attributes
///
/// Current camera position.
///
private Vector3 eye = new Vector3( 0.0f, 0.0f, 10.0f );
///
/// Current point to look at.
///
private Vector3 pointAt = Vector3.Zero;
///
/// Current "up" vector.
///
private Vector3 up = Vector3.UnitY;
///
/// Vertical field-of-view angle in radians.
///
private float fov = 1.0f;
///
/// Camera's far point.
///
private float far = 200.0f;
#endregion
protected Vector3d v1 = new Vector3d(0, 0, 0);
protected Vector3d v2 = new Vector3d(0, 0, 0);
protected float theta = 0;
///
/// Sets up a projective viewport
///
private void SetupViewport ()
{
int width = glControl1.Width;
int height = glControl1.Height;
// 1. set ViewPort transform:
GL.Viewport( 0, 0, width, height );
// 2. set projection matrix
GL.MatrixMode( MatrixMode.Projection );
Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView( fov, (float)width / (float)height, 0.1f, far );
GL.LoadMatrix( ref proj );
}
///
/// Setup of a camera called for every frame prior to any rendering.
///
private void SetCamera ()
{
// !!!{{ TODO: add camera setup here
SetupViewport();
GL.MatrixMode( MatrixMode.Modelview );
Matrix4 modelview = Matrix4.CreateTranslation(-center) *
Matrix4.Scale(1.0f / diameter) *
Matrix4.CreateTranslation(0.0f, 0.0f, -1.5f);
GL.LoadMatrix( ref modelview );
// !!!}}
}
private void ResetCamera ()
{
// !!!{{ TODO: add camera reset code here
// !!!}}
}
///
/// Rendering of one frame.
///
private void Render ()
{
if ( !loaded ) return;
frameCounter++;
GL.Clear( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit );
GL.ShadeModel( ShadingModel.Flat );
GL.PolygonMode( MaterialFace.Front, PolygonMode.Fill );
GL.Enable( EnableCap.CullFace );
SetCamera();
RenderScene();
glControl1.SwapBuffers();
}
public void glControl1_MouseDown ( object sender, MouseEventArgs e )
{
Cursor.Current = Cursors.Hand;
double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2);
double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2);
x = x - 1;
y = 1 - y;
double z2 = 1 - x * x - y * y;
double z = z2 > 0 ? Math.Sqrt(z2) : 0;
v1 = new Vector3d(x, y, z);
v1.Normalize();
//labelFile.Text = String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", x, y, z, MousePosition.X, MousePosition.Y, glControl1.Width, glControl1.Height);
}
private void glControl1_MouseUp ( object sender, MouseEventArgs e )
{
Cursor.Current = Cursors.Default;
double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2);
double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2);
x = x - 1;
y = 1 - y;
double z2 = 1 - x * x - y * y;
double z = z2 > 0 ? Math.Sqrt(z2) : 0;
v2 = new Vector3d(x, y, z);
v2.Normalize();
Vector3d axis = Vector3d.Cross(v1, v2);
float theta = (float) Vector3d.CalculateAngle(v1, v2);
// Here sholud be smoething
//labelFile.Text = String.Format("{0}, {1}", axis, theta);
}
private void glControl1_MouseMove ( object sender, MouseEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void glControl1_MouseWheel ( object sender, MouseEventArgs e )
{
// !!!{{ TODO: add the event handler here
// HINT: for most mouses, e.delta / 120 is the number of wheel clicks, +/- indicated the direction
// !!!}}
}
private void glControl1_KeyDown ( object sender, KeyEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void glControl1_KeyUp ( object sender, KeyEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void buttonReset_Click ( object sender, EventArgs e )
{
// !!!{{ TODO: add the event handler here
ResetCamera();
// !!!}}
}
}
}
< /code>
und Form1.cs < /p>
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using Scene3D;
namespace _038trackball
{
public partial class Form1 : Form
{
///
/// Scene read from file.
///
protected SceneBrep scene = new SceneBrep();
///
/// Scene center point.
///
protected Vector3 center = Vector3.Zero;
///
/// Scene diameter.
///
protected float diameter = 3.5f;
///
/// GLControl guard flag.
///
bool loaded = false;
///
/// Are we allowed to use VBO?
///
bool useVBO = true;
#region OpenGL globals
private uint[] VBOid = new uint[ 2 ]; // vertex array (colors, normals, coords), index array
private int stride = 0; // stride for vertex array
#endregion
#region FPS counter
long lastFpsTime = 0L;
int frameCounter = 0;
long triangleCounter = 0L;
#endregion
public Form1 ()
{
InitializeComponent();
}
private void glControl1_Load ( object sender, EventArgs e )
{
loaded = true;
// OpenGL init code:
GL.ClearColor( Color.DarkBlue );
GL.Enable( EnableCap.DepthTest );
GL.ShadeModel( ShadingModel.Flat );
// VBO init:
GL.GenBuffers( 2, VBOid );
if ( GL.GetError() != ErrorCode.NoError )
useVBO = false;
SetupViewport();
Application.Idle += new EventHandler( Application_Idle );
comboTrackballType.SelectedIndex = 0;
}
private void glControl1_Resize ( object sender, EventArgs e )
{
if ( !loaded ) return;
SetupViewport();
glControl1.Invalidate();
}
private void glControl1_Paint ( object sender, PaintEventArgs e )
{
Render();
}
private void buttonOpen_Click ( object sender, EventArgs e )
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open Scene File";
ofd.Filter = "Wavefront OBJ Files|*.obj" +
"|All scene types|*.obj";
ofd.FilterIndex = 1;
ofd.FileName = "";
if ( ofd.ShowDialog() != DialogResult.OK )
return;
WavefrontObj objReader = new WavefrontObj();
objReader.MirrorConversion = false;
StreamReader reader = new StreamReader( new FileStream( ofd.FileName, FileMode.Open ) );
int faces = objReader.ReadBrep( reader, scene );
reader.Close();
scene.BuildCornerTable();
diameter = scene.GetDiameter( out center );
scene.GenerateColors( 12 );
ResetCamera();
//labelFile.Text = String.Format("{0}: {1} faces, {2}, {3}, {4}, {5}", ofd.SafeFileName, faces, theta, v1.X, x, y);
PrepareDataBuffers();
glControl1.Invalidate();
}
///
/// Prepare VBO content and upload it to the GPU.
///
private void PrepareDataBuffers ()
{
if ( useVBO &&
scene != null &&
scene.Triangles > 0 )
{
GL.EnableClientState( ArrayCap.VertexArray );
if ( scene.Normals > 0 )
GL.EnableClientState( ArrayCap.NormalArray );
GL.EnableClientState( ArrayCap.ColorArray );
// Vertex array: color [normal] coord
GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] );
int vertexBufferSize = scene.VertexBufferSize( true, false, true, true );
GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.StaticDraw );
IntPtr videoMemoryPtr = GL.MapBuffer( BufferTarget.ArrayBuffer, BufferAccess.WriteOnly );
unsafe
{
stride = scene.FillVertexBuffer( (float*)videoMemoryPtr.ToPointer(), true, false, true, true );
}
GL.UnmapBuffer( BufferTarget.ArrayBuffer );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
// Index buffer
GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] );
GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)(scene.Triangles * 3 * sizeof( uint )), IntPtr.Zero, BufferUsageHint.StaticDraw );
videoMemoryPtr = GL.MapBuffer( BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly );
unsafe
{
scene.FillIndexBuffer( (uint*)videoMemoryPtr.ToPointer() );
}
GL.UnmapBuffer( BufferTarget.ElementArrayBuffer );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
}
else
{
GL.DisableClientState( ArrayCap.VertexArray );
GL.DisableClientState( ArrayCap.NormalArray );
GL.DisableClientState( ArrayCap.ColorArray );
if ( useVBO )
{
GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] );
GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] );
GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
}
}
}
}
}
1758629787
Anonymous
Ich habe das Tutorial unter http://viewport3d.com/trackball.htm verwendet, um Trackball zu programmieren. Ich habe Achse und Winkel berechnet, aber ich weiß nicht, wie man Rotation auf Objekt anwendet. Irgendwelche Hilfe? < /P> Code besteht aus mehreren Dateien. Hier sind zwei wichtigste.[code]using System; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace _038trackball { public partial class Form1 { #region Camera attributes /// /// Current camera position. /// private Vector3 eye = new Vector3( 0.0f, 0.0f, 10.0f ); /// /// Current point to look at. /// private Vector3 pointAt = Vector3.Zero; /// /// Current "up" vector. /// private Vector3 up = Vector3.UnitY; /// /// Vertical field-of-view angle in radians. /// private float fov = 1.0f; /// /// Camera's far point. /// private float far = 200.0f; #endregion protected Vector3d v1 = new Vector3d(0, 0, 0); protected Vector3d v2 = new Vector3d(0, 0, 0); protected float theta = 0; /// /// Sets up a projective viewport /// private void SetupViewport () { int width = glControl1.Width; int height = glControl1.Height; // 1. set ViewPort transform: GL.Viewport( 0, 0, width, height ); // 2. set projection matrix GL.MatrixMode( MatrixMode.Projection ); Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView( fov, (float)width / (float)height, 0.1f, far ); GL.LoadMatrix( ref proj ); } /// /// Setup of a camera called for every frame prior to any rendering. /// private void SetCamera () { // !!!{{ TODO: add camera setup here SetupViewport(); GL.MatrixMode( MatrixMode.Modelview ); Matrix4 modelview = Matrix4.CreateTranslation(-center) * Matrix4.Scale(1.0f / diameter) * Matrix4.CreateTranslation(0.0f, 0.0f, -1.5f); GL.LoadMatrix( ref modelview ); // !!!}} } private void ResetCamera () { // !!!{{ TODO: add camera reset code here // !!!}} } /// /// Rendering of one frame. /// private void Render () { if ( !loaded ) return; frameCounter++; GL.Clear( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit ); GL.ShadeModel( ShadingModel.Flat ); GL.PolygonMode( MaterialFace.Front, PolygonMode.Fill ); GL.Enable( EnableCap.CullFace ); SetCamera(); RenderScene(); glControl1.SwapBuffers(); } public void glControl1_MouseDown ( object sender, MouseEventArgs e ) { Cursor.Current = Cursors.Hand; double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2); double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2); x = x - 1; y = 1 - y; double z2 = 1 - x * x - y * y; double z = z2 > 0 ? Math.Sqrt(z2) : 0; v1 = new Vector3d(x, y, z); v1.Normalize(); //labelFile.Text = String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", x, y, z, MousePosition.X, MousePosition.Y, glControl1.Width, glControl1.Height); } private void glControl1_MouseUp ( object sender, MouseEventArgs e ) { Cursor.Current = Cursors.Default; double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2); double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2); x = x - 1; y = 1 - y; double z2 = 1 - x * x - y * y; double z = z2 > 0 ? Math.Sqrt(z2) : 0; v2 = new Vector3d(x, y, z); v2.Normalize(); Vector3d axis = Vector3d.Cross(v1, v2); float theta = (float) Vector3d.CalculateAngle(v1, v2); // Here sholud be smoething //labelFile.Text = String.Format("{0}, {1}", axis, theta); } private void glControl1_MouseMove ( object sender, MouseEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void glControl1_MouseWheel ( object sender, MouseEventArgs e ) { // !!!{{ TODO: add the event handler here // HINT: for most mouses, e.delta / 120 is the number of wheel clicks, +/- indicated the direction // !!!}} } private void glControl1_KeyDown ( object sender, KeyEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void glControl1_KeyUp ( object sender, KeyEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void buttonReset_Click ( object sender, EventArgs e ) { // !!!{{ TODO: add the event handler here ResetCamera(); // !!!}} } } } < /code> und Form1.cs < /p> using System; using System.Drawing; using System.IO; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; using Scene3D; namespace _038trackball { public partial class Form1 : Form { /// /// Scene read from file. /// protected SceneBrep scene = new SceneBrep(); /// /// Scene center point. /// protected Vector3 center = Vector3.Zero; /// /// Scene diameter. /// protected float diameter = 3.5f; /// /// GLControl guard flag. /// bool loaded = false; /// /// Are we allowed to use VBO? /// bool useVBO = true; #region OpenGL globals private uint[] VBOid = new uint[ 2 ]; // vertex array (colors, normals, coords), index array private int stride = 0; // stride for vertex array #endregion #region FPS counter long lastFpsTime = 0L; int frameCounter = 0; long triangleCounter = 0L; #endregion public Form1 () { InitializeComponent(); } private void glControl1_Load ( object sender, EventArgs e ) { loaded = true; // OpenGL init code: GL.ClearColor( Color.DarkBlue ); GL.Enable( EnableCap.DepthTest ); GL.ShadeModel( ShadingModel.Flat ); // VBO init: GL.GenBuffers( 2, VBOid ); if ( GL.GetError() != ErrorCode.NoError ) useVBO = false; SetupViewport(); Application.Idle += new EventHandler( Application_Idle ); comboTrackballType.SelectedIndex = 0; } private void glControl1_Resize ( object sender, EventArgs e ) { if ( !loaded ) return; SetupViewport(); glControl1.Invalidate(); } private void glControl1_Paint ( object sender, PaintEventArgs e ) { Render(); } private void buttonOpen_Click ( object sender, EventArgs e ) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open Scene File"; ofd.Filter = "Wavefront OBJ Files|*.obj" + "|All scene types|*.obj"; ofd.FilterIndex = 1; ofd.FileName = ""; if ( ofd.ShowDialog() != DialogResult.OK ) return; WavefrontObj objReader = new WavefrontObj(); objReader.MirrorConversion = false; StreamReader reader = new StreamReader( new FileStream( ofd.FileName, FileMode.Open ) ); int faces = objReader.ReadBrep( reader, scene ); reader.Close(); scene.BuildCornerTable(); diameter = scene.GetDiameter( out center ); scene.GenerateColors( 12 ); ResetCamera(); //labelFile.Text = String.Format("{0}: {1} faces, {2}, {3}, {4}, {5}", ofd.SafeFileName, faces, theta, v1.X, x, y); PrepareDataBuffers(); glControl1.Invalidate(); } /// /// Prepare VBO content and upload it to the GPU. /// private void PrepareDataBuffers () { if ( useVBO && scene != null && scene.Triangles > 0 ) { GL.EnableClientState( ArrayCap.VertexArray ); if ( scene.Normals > 0 ) GL.EnableClientState( ArrayCap.NormalArray ); GL.EnableClientState( ArrayCap.ColorArray ); // Vertex array: color [normal] coord GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] ); int vertexBufferSize = scene.VertexBufferSize( true, false, true, true ); GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.StaticDraw ); IntPtr videoMemoryPtr = GL.MapBuffer( BufferTarget.ArrayBuffer, BufferAccess.WriteOnly ); unsafe { stride = scene.FillVertexBuffer( (float*)videoMemoryPtr.ToPointer(), true, false, true, true ); } GL.UnmapBuffer( BufferTarget.ArrayBuffer ); GL.BindBuffer( BufferTarget.ArrayBuffer, 0 ); // Index buffer GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] ); GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)(scene.Triangles * 3 * sizeof( uint )), IntPtr.Zero, BufferUsageHint.StaticDraw ); videoMemoryPtr = GL.MapBuffer( BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly ); unsafe { scene.FillIndexBuffer( (uint*)videoMemoryPtr.ToPointer() ); } GL.UnmapBuffer( BufferTarget.ElementArrayBuffer ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 ); } else { GL.DisableClientState( ArrayCap.VertexArray ); GL.DisableClientState( ArrayCap.NormalArray ); GL.DisableClientState( ArrayCap.ColorArray ); if ( useVBO ) { GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] ); GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw ); GL.BindBuffer( BufferTarget.ArrayBuffer, 0 ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] ); GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 ); } } } } } [/code]