Search Home Members Contacts
About Us
Bug #655: X-Axis Rotation Bugs
TV3D SDK 6.5
Current State:
Created On:
January 14th, 2007
Last Modified:
January 14th, 2007
Reported By:
I've supplied the demo in C# but the bug appears to be with all versions. I found it in the GCC version which is the one I use.

Two bugs in one here, but they're clearly related.

If I create a mesh and get it's rotation, it is not 0.0 on the x axis, it's actually 0.01978234 which is too large an error to be floating point inaccuracy. Besides 0.0 can be accurately stored as a float as demonstrated by y and z axes staying at 0.0

Furthermore, and this is the more serious part of the bug, though the first part hopefully helps you to locate the problem, if I do this in the main loop, the x axis rotation constantly moves away from 0 at a fairly high rate.


Note that no change is made. I do not rotate at all. I even set the initial rotation to 0,0,0 because TV3D does not, but it still constantly moves away from 0 on the x axis.

At a high enough frame rate that's coming back 1 degree out in a second.

Anyway, here's a little C# code which demonstrates both bugs and writes out a little text file with the values which hopefully might be of help.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

// Add MTV3D65 to using clause:
using MTV3D65;

namespace Template
/// summary
/// Summary description for Form1.
/// /summary
public class frmMain : System.Windows.Forms.Form
// Declare the TV Objects.
public TVEngine TV;
public TVScene Scene;
public TVInputEngine Input;
public TVGlobals Globals;
public bool bDoLoop;

public TVMesh Cube;

public TV_3DVECTOR V;

/// summary
/// Required designer variable.
/// /summary
private System.ComponentModel.Container components = null;

public frmMain()
// Required for Windows Form Designer support

// TODO: Add any constructor code after InitializeComponent call

/// summary
/// Clean up any resources being used.
/// /summary
protected override void Dispose( bool disposing )
if( disposing )
if (components != null)
base.Dispose( disposing );

#region Windows Form Designer generated code
/// summary
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// /summary
private void InitializeComponent()
// frmMain
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(632, 453);
this.Name = "frmMain";
this.Text = "TV3D SDK 6.5 Template";
this.Closing += new System.ComponentModel.CancelEventHandler(this.frmMain_Closing);
this.Load += new System.EventHandler(this.frmMain_Load);


/// summary
/// The main entry point for the application.
/// /summary
static void Main()
Application.Run(new frmMain());

private void frmMain_Load(object sender, System.EventArgs e)
// Create the TV Interface first:
TV = new TVEngine();

// Set the debug file/options.
// Do this before the 3D init so it can log any errors found during init.
TV.SetDebugMode(true, true);
TV.SetDebugFile(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\debugfile.txt");

// Set your beta-key/license:
// TV.SetLicenseKey(TV_LICENSE_COMMERCIAL, "username", "key");
TV.SetBetaKey("blah", "blah-blah-blah-blah");

// After setting the beta-key/license its time to init the engine:
TV.Init3DWindowed(this.Handle, true);

// Something good to do is to enable the auto-resize feature:
// Get the default viewport and set autoresize to true for it:

// Lets display the FPS:

// Set the prefered angle system:

// Now after we are done initializing the TVEngine component lets continue:
// Create any other components after TV init.

Scene = new TVScene();

Globals = new TVGlobals();

// Input has an additional init method to call.
Input = new TVInputEngine();
// Lets init both keyboard and mouse:
Input.Initialize(true, true);

TextWriter debuglog = new StreamWriter("debug.txt");

Cube = Scene.CreateMeshBuilder();
Cube.SetPosition(0, 0, 5);
debuglog.WriteLine("**BUG HERE** INITIAL ROTATION IS ("+V.x+","+V.y+","+V.z+")"+" INSTEAD OF (0,0,0)");
Cube.SetRotation(0, 0, 0);

// Now we have setup the most basic of components.
// Something to think about, if the component has a diffrent construct method
// then the Object = new TVNAME, use that one instead.

// For example:
// TVMesh Mesh;
// Mesh = Scene.CreateMeshBuilder("MyMesh"); - Instead of Mesh = TVMesh();
// Same goes for RenderSurface, Viewport etc.

bDoLoop = true;

// Lets setup the Loop:
// Check if the application has focus, if yes thats when we process the loop.

V = Cube.GetRotation();
Cube.SetRotation(V.x, V.y, V.z);
debuglog.WriteLine("RELATED BUG HERE - "+V.x + "," + V.y + "," + V.z);

Q = Cube.GetQuaternion();
debuglog.WriteLine("RELATED BUG HERE - "+Q.w+","+Q.x + "," + Q.y + "," + Q.z);

// The actual render loop:
// Render everything

// Lets check if the user presses ESC key, if yes we will quit the app.
if(Input.IsKeyPressed(MTV3D65.CONST_TV_KEY.TV_KEY_ESCAPE)) { bDoLoop = false; };
} else {
// So we arent calling DoEvents to many times if we arent using full CPU power.


// close the stream

// Additional Info:
Normally you dont have to keep track of the TV component and free it on closing.
.NET will free the Managed Interface on close and thus automatically all the internal
objects will be free'd. Such as Mesh's, Textures etc.

Though it might be good to know you do have the ability to destroy and nil objects
for re-creation or cleanup during runtime if you want that.

TV = null;

Will free all of the internal objects automatically.
There are several other Destroy methods such as:

TVNAME.Destroy , DestroyAll exists for some objects aswell if it is a Factory of some sort.

Some other good destroy methods are:

And others...

TV = null;

// End the application.

private void frmMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
// If we close the application lets stop the loop.
bDoLoop = false;



No comments available.