[Solved] Does GetCameraToViewportRay within a Mogre Form...

Blackbeard

27-03-2007 15:08:08

To test GetCameraToViewportRay i want to place an entity on a plane.

I use a Ray to get start and enpoint for MogreNewts BasicRaycast.
BasicRaycast works. There must be a problem with GetCameraToViewportRay?
On screen you can basicaly hit the plane only...

-=screen
*=area where ray hits plane

-***********-
--*********--
--- ******-----
-----****------
------**--------


I used Mogres Tutorial to render on a reseizable form.
I simply cant see whats wrong with my code.
Maybe Ray doesnt work the way i think it should?
Its like GetCameraToViewportRay uses wrong viewport seize or wrong camera position.



Ray ray = new Ray();
float x = (float)Control.MousePosition.X / Program.form.Width;
float y = (float)Control.MousePosition.Y / Program.form.Height;

ray = Program.form.cam.GetCameraToViewportRay(x, y);
Vector3 start = ray.Origin;
Vector3 end = Program.form.cam.Position + ray.Direction * 1000;

//basicraycast seems not the problem
BasicRaycast nray = new BasicRaycast(Program.form.NWorld,start,end);
if (nray.getHitCount() > 0)
{
BasicRaycast.BasicRaycastInfo tInfo = nray.getInfoAt(0);
Vector3 direction = (end - start);
direction.Normalise();
double dist = System.Math.Sqrt((start.x - end.x) * (start.x - end.x) + (start.y - end.y) * (start.y - end.y) + (start.z - end.z) * (start.z - end.z));
float d = tInfo.mDistance * (float)dist;
Vector3 hitPosition =start+direction * d;
return hitPosition;
}
Vector3 nullvector=Vector3.ZERO;
return nullvector;
}


Please help, I am going nuts..

Blackbeard

27-03-2007 16:23:52

Sorry, BasicRay doesnt work as exspected and so i have to ask in OgreNewt Forum first.


start = Program.form.cam.Position;// at 0, 200, -200);
end = new Vector3(110, -20, -90);

Ray doesnt hit.


start = Program.form.cam.Position;// at 0, 200, -200);
end = new Vector3(109, -20, -90);

Ray hits plane. But why?

Bekas

27-03-2007 20:33:19

Can you provide the full source to the example ?

Blackbeard

28-03-2007 13:55:26

Well, here we go.
It seems the problem is BasicRays startpoint, or a brainbug in my head.
Accurate picking works fine, as long i dont change startpoints X and Z (both values have to be 0).
Change i.e "start" X value to 200 and see what happens.

Someone mentioned that a plane doesnt work for Newtons TreeCollision, but plane showed same behaviour as the cube i created for that example.
My cubes mesh scale is aprox. 150,10,150.

And yes, i couldnt find out how a codebox works here:D

-----------------------------------------------------------------------
OgreForm.cs
-----------------------------------------------------------------------
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Mogre;
using MogreNewt;

namespace WindowsApplication1
{
public partial class OgreForm : Form
{
Root mRoot;
RenderWindow mWindow;
Viewport viewport;
Camera cam;
SceneNode snode1;
SceneNode snode2;
World nworld;

public OgreForm()
{
this.Size = new Size(800, 600);
Disposed += new EventHandler(OgreForm_Disposed);
Resize += new EventHandler(OgreForm_Resize);

InitializeComponent();
}

public void Go()
{
Show();
while (mRoot != null && mRoot.RenderOneFrame())
Application.DoEvents();

}

public void Init()
{
// Create root object
mRoot = new Root();

// Define Resources
ConfigFile cf = new ConfigFile();
cf.Load("resources.cfg", "\t:=", true);
ConfigFile.SectionIterator seci = cf.GetSectionIterator();
String secName, typeName, archName;

while (seci.MoveNext())
{
secName = seci.CurrentKey;
ConfigFile.SettingsMultiMap settings = seci.Current;
foreach (KeyValuePair<string, string> pair in settings)
{
typeName = pair.Key;
archName = pair.Value;
ResourceGroupManager.Singleton.AddResourceLocation(archName, typeName, secName);
}
}

// Setup RenderSystem
RenderSystem rs = mRoot.GetRenderSystemByName("Direct3D9 Rendering Subsystem");
mRoot.RenderSystem = rs;
rs.SetConfigOption("Full Screen", "No");
rs.SetConfigOption("Video Mode", "800 x 600 @ 32-bit colour");

// Create Render Window
mRoot.Initialise(false, "Main Ogre Window");
NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = Handle.ToString();
mWindow = mRoot.CreateRenderWindow("Main RenderWindow", 800, 600, false, misc);

// Init resources
TextureManager.Singleton.DefaultNumMipmaps = 5;
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();

//**** Creates a simple scene
SceneManager mgr = mRoot.CreateSceneManager(SceneType.ST_GENERIC);
cam = mgr.CreateCamera("Camera");
cam.AutoAspectRatio = true;
viewport=mWindow.AddViewport(cam);

Entity ent = mgr.CreateEntity("ninja", "ninja.mesh");
snode1 = mgr.RootSceneNode.CreateChildSceneNode();
snode1.AttachObject(ent);
snode1.Scale(new Vector3(0.2f,0.2f,0.2f));

ent = mgr.CreateEntity("cube", "cube.mesh");
snode2 = mgr.RootSceneNode.CreateChildSceneNode();
snode2.AttachObject(ent);


//Creates Newton World
nworld = new World();
MogreNewt.Debugger.Instance.init(mgr);
//Feed TreeCollision with entities mesh data (cube.mesh)
MogreNewt.CollisionPrimitives.TreeCollision stat_col = new MogreNewt.CollisionPrimitives.TreeCollision(nworld, ent, true);
//Creates a Body (static collision hull)
MogreNewt.Body bod = new MogreNewt.Body(nworld, stat_col);
stat_col.Dispose();
//Attach the body to Ogre's scene node
//bod.attachToNode(snode2);
//bod.setPositionOrientation(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.IDENTITY);

//Add frame listener
this.mRoot.FrameStarted += new FrameListener.FrameStartedHandler(FrameStarted);
//Place Camera
cam.Position = new Vector3(0, 300, 0);
cam.Pitch(new Degree(-90));
}

bool FrameStarted(FrameEvent evt)
{
//Do linepick
Vector3 position = test_linepick();
//Place Ninja on picked coordinates
snode1.Yaw(new Degree(-0.1f));
if (position.IsZeroLength==false) { snode1.Position=position;}
return true;
}

Vector3 test_linepick()
{

Ray ray = new Ray();
//there will be still have a small mouse cursor offset (Y), caused by Windows Titlebar.
float mx=(float) Control.MousePosition.X-this.DesktopLocation.X;
float my=(float) Control.MousePosition.Y-this.DesktopLocation.Y;

float x = mx / viewport.ActualWidth;
float y = my / viewport.ActualHeight;

ray = Program.form.cam.GetCameraToViewportRay(x, y);
Vector3 start = ray.Origin;
Vector3 end = ray.Origin+ray.Direction * 1024;

//!!!!Accurate picking works as long "start" X and Z is 0;
//Whats wrong?

// start = new Vector3(100.0f, 200.0f, 0.0f);


BasicRaycast nray = new BasicRaycast(nworld,start, end);
if (nray.getHitCount() > 0)
{
BasicRaycast.BasicRaycastInfo tInfo = nray.getInfoAt(0);
Vector3 direction = (end - start);
direction.Normalise();
double dist = System.Math.Sqrt((start.x - end.x) * (start.x - end.x) + (start.y - end.y) * (start.y - end.y) + (start.z - end.z) * (start.z - end.z));
float d = tInfo.mDistance * (float)dist;
Vector3 hitPosition =start+direction * d;
return hitPosition;
}
Vector3 nullvector=Vector3.ZERO;
return nullvector;
}



void OgreForm_Disposed(object sender, EventArgs e)
{
mRoot.Dispose();
mRoot = null;
}
void OgreForm_Resize(object sender, EventArgs e)
{
if (mWindow != null) { mWindow.WindowMovedOrResized(); }
}


}
}

------------------------------------------------------------------------
OgreForm.Designer.cs:
------------------------------------------------------------------------
namespace WindowsApplication1
{
partial class OgreForm
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Vom Windows Form-Designer generierter Code

/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// OgreForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(582, 402);
this.KeyPreview = true;
this.Name = "OgreForm";
this.Text = "Test";
this.ResumeLayout(false);

}

#endregion
}
}


----------------------------------------------------------------
Main
Program.cs:
----------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Windows.Forms;


namespace WindowsApplication1
{
public class Program
{
//Forms
public static OgreForm form;

[STAThread]
static void Main()
{
form = new OgreForm();
form.Init();
form.Go();
}
}
}

Blackbeard

29-03-2007 13:48:08

Men, i suck.

Newtons BasicRay only works within Newtons World bounds (what else :roll: )

Added:
nworld.setWorldSize(new Vector3(-1000, -1000, -1000), new Vector3(-000, 1000,100)). Now accurate picking seems to work.

Well, my english isnt bug free, someone else should put it as Intermediate Example 2 in the Wiki:D