Can someone tell me what Im doing wrong? Or should I just get a job serving up french fries?
Im writing this line which is probably all wrong
Code: Select all
if (KeyBoard.KeyState[(int)Keys.Left] || KeyBoard.KeyState[(int)Keys.A])//left arrow key
{
camera.Position = new Vector3D(-100, 50, CameraMove = CameraMove + 1);
}
What should I be writing? Please keep it simple. Im a irrlicht virgin.
When I move the position like this, the camera spins off into nowhereshell.
the complete program sample is this;
Code: Select all
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Irrlicht;
using Irrlicht.Video;
using Irrlicht.Core;
using Irrlicht.Scene;
namespace irrlicht14
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
# region keyboard code
public class KeyBoard
{
public static bool[] KeyState;
static KeyBoard()
{
// Watch for keyboard activity
KeyboardListener.s_KeyEventHandler += new EventHandler(KeyboardListener_s_KeyEventHandler);
KeyState = new bool[256];
}
public static event KeyPressEventHandler OnKeyChanged;
static void KeyboardListener_s_KeyEventHandler(object sender, EventArgs e)
{
KeyboardListener.UniversalKeyEventArgs eventArgs = (KeyboardListener.UniversalKeyEventArgs)e;
if (eventArgs.m_Msg == 256)
{
KeyBoard.KeyState[eventArgs.m_Key] = true;
OnKeyChanged(null, null);
}
else
{
KeyBoard.KeyState[eventArgs.m_Key] = false;
OnKeyChanged(null, null);
}
}
}
/// <summary>
/// The KeyboardListener is a static class that allows registering a number
/// of event handlers that you want to get called in case some keyboard key is pressed
/// or released. The nice thing is that this KeyboardListener is also active in case
/// the parent application is running in the back.
/// </summary>
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "SkipVerification")]
public class KeyboardListener
{
#region Private declarations
/// <summary>
/// The Window that intercepts Keyboard messages
/// </summary>
private static ListeningWindow s_Listener;
#endregion
#region Private methods
/// <summary>
/// The function that will handle all keyboard activity signaled by the ListeningWindow.
/// In this context handling means calling all registered subscribers for every key pressed / released.
/// </summary>
/// <remarks>
/// Inside this method the events could also be fired by calling
/// s_KeyEventHandler(null,new KeyEventArgs(key,msg)) However, in case one of the registered
/// subscribers throws an exception, execution of the non-executed subscribers is cancelled.
/// </remarks>
/// <param name="key"></param>
/// <param name="msg"></param>
private static void KeyHandler(ushort key, uint msg)
{
if (s_KeyEventHandler != null)
{
Delegate[] delegates = s_KeyEventHandler.GetInvocationList();
foreach (Delegate del in delegates)
{
EventHandler sink = (EventHandler)del;
try
{
// This is a static class, therefore null is passed as the object reference
sink(null, new UniversalKeyEventArgs(key, msg));
}
// You can add some meaningful code to this catch block.
catch { };
}
}
}
#endregion
#region Public declarations
/// <summary>
/// An instance of this class is passed when Keyboard events are fired by the KeyboardListener.
/// </summary>
public class UniversalKeyEventArgs : KeyEventArgs
{
public readonly uint m_Msg;
public readonly ushort m_Key;
public UniversalKeyEventArgs(ushort aKey, uint aMsg)
: base((Keys)aKey)
{
m_Msg = aMsg;
m_Key = aKey;
}
}
/// <summary>
/// For every application thread that is interested in keyboard events
/// an EventHandler can be added to this variable
/// </summary>
public static event EventHandler s_KeyEventHandler;
#endregion
#region Public methods
static KeyboardListener()
{
ListeningWindow.KeyDelegate aKeyDelegate = new ListeningWindow.KeyDelegate(KeyHandler);
s_Listener = new ListeningWindow(aKeyDelegate);
}
#endregion
#region Definition ListeningWindow class
/// <summary>
/// A ListeningWindow object is a Window that intercepts Keyboard events.
/// </summary>
private class ListeningWindow : NativeWindow
{
#region Declarations
public delegate void KeyDelegate(ushort key, uint msg);
private const int
WS_CLIPCHILDREN = 0x02000000,
WM_INPUT = 0x00FF,
RIDEV_INPUTSINK = 0x00000100,
RID_INPUT = 0x10000003,
RIM_TYPEKEYBOARD = 1;
private uint m_PrevMessage = 0;
private ushort m_PrevControlKey = 0;
private KeyDelegate m_KeyHandler = null;
#endregion
#region Unsafe types
internal unsafe struct RAWINPUTDEV
{
public ushort usUsagePage;
public ushort usUsage;
public uint dwFlags;
public void* hwndTarget;
};
internal unsafe struct RAWINPUTHEADER
{
public uint dwType;
public uint dwSize;
public void* hDevice;
public void* wParam;
};
internal unsafe struct RAWINPUTHKEYBOARD
{
public RAWINPUTHEADER header;
public ushort MakeCode;
public ushort Flags;
public ushort Reserved;
public ushort VKey;
public uint Message;
public uint ExtraInformation;
};
#endregion
public ListeningWindow(KeyDelegate keyHandlerFunction)
{
m_KeyHandler = keyHandlerFunction;
CreateParams cp = new CreateParams();
// Fill in the CreateParams details.
cp.Caption = "Hidden window";
cp.ClassName = null;
cp.X = 0x7FFFFFFF;
cp.Y = 0x7FFFFFFF;
cp.Height = 0;
cp.Width = 0;
//cp.Parent = parent.Handle;
cp.Style = WS_CLIPCHILDREN;
// Create the actual invisible window
this.CreateHandle(cp);
// Register for Keyboard notification
unsafe
{
try
{
RAWINPUTDEV myRawDevice = new RAWINPUTDEV();
myRawDevice.usUsagePage = 0x01;
myRawDevice.usUsage = 0x06;
myRawDevice.dwFlags = RIDEV_INPUTSINK;
myRawDevice.hwndTarget = this.Handle.ToPointer();
if (RegisterRawInputDevices(&myRawDevice, 1, (uint)sizeof(RAWINPUTDEV)) == false)
{
int err = Marshal.GetLastWin32Error();
throw new Win32Exception(err, "ListeningWindow::RegisterRawInputDevices");
}
}
catch { throw; }
}
}
#region Private methods
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_INPUT:
{
try
{
unsafe
{
uint dwSize, receivedBytes;
uint sizeof_RAWINPUTHEADER = (uint)(sizeof(RAWINPUTHEADER));
// Find out the size of the buffer we have to provide
int res = GetRawInputData(m.LParam.ToPointer(), RID_INPUT, null, &dwSize, sizeof_RAWINPUTHEADER);
if (res == 0)
{
// Allocate a buffer and ...
byte* lpb = stackalloc byte[(int)dwSize];
// ... get the data
receivedBytes = (uint)GetRawInputData((RAWINPUTHKEYBOARD*)(m.LParam.ToPointer()), RID_INPUT, lpb, &dwSize, sizeof_RAWINPUTHEADER);
if (receivedBytes == dwSize)
{
RAWINPUTHKEYBOARD* keybData = (RAWINPUTHKEYBOARD*)lpb;
// Finally, analyze the data
if (keybData->header.dwType == RIM_TYPEKEYBOARD)
{
if ((m_PrevControlKey != keybData->VKey) || (m_PrevMessage != keybData->Message))
{
m_PrevControlKey = keybData->VKey;
m_PrevMessage = keybData->Message;
// Call the delegate in case data satisfies
m_KeyHandler(keybData->VKey, keybData->Message);
}
}
}
else
{
string errMsg = string.Format("WndProc::GetRawInputData (2) received {0} bytes while expected {1} bytes", receivedBytes, dwSize);
throw new Exception(errMsg);
}
}
else
{
string errMsg = string.Format("WndProc::GetRawInputData (1) returned non zero value ({0})", res);
throw new Exception(errMsg);
}
}
}
catch { throw; }
}
break;
}
// In case you forget this you will run into problems
base.WndProc(ref m);
}
#endregion
#region Private external methods
// In case you want to have a comprehensive overview of calling conventions follow the next link:
// http://www.codeproject.com/cpp/calling_conventions_demystified.asp
[DllImport("User32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern unsafe bool RegisterRawInputDevices(RAWINPUTDEV* rawInputDevices, uint numDevices, uint size);
[DllImport("User32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.I4)]
internal static extern unsafe int GetRawInputData(void* hRawInput,
uint uiCommand,
byte* pData,
uint* pcbSize,
uint cbSizeHeader
);
#endregion
}
}
#endregion
# endregion
private void Main_Load(object sender, EventArgs e)
{
this.Show();
Main_Run(pictureBox1);
}
private void Main_Run(Control c)
{
IrrlichtDevice device = new IrrlichtDevice(Irrlicht.Video.DriverType.DIRECT3D9,
new Dimension2D(c.Width, c.Height),
32, false, false, false, true, c.Handle);
//setup *****************************************************************
string TextViewer = "Viewer";
bool ShowFPS = true;
int CameraMove = -150;
//ripped from example 07
string path = "C:/irrlicht/media/";
ISceneManager smgr = device.SceneManager;
IVideoDriver driver = device.VideoDriver;
device.FileSystem.AddZipFileArchive(path + "map-20kdm2.pk3");
IAnimatedMesh q3levelmesh = smgr.GetMesh("20kdm2.bsp");
ISceneNode q3node = null;
if (q3levelmesh != null)
q3node = smgr.AddOctTreeSceneNode(q3levelmesh.GetMesh(0), null, 0);
ITriangleSelector selector = null;
if (q3node != null)
{
q3node.Position = new Vector3D(-1370, -130, -1400);
selector = smgr.CreateOctTreeTriangleSelector(
q3levelmesh.GetMesh(0), q3node, 128);
// not implemented but not necessary
//q3node.TriangleSelector=selector;
}
//ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100, 300, 0);
ICameraSceneNode camera = smgr.AddCameraSceneNode(null, new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), 0);
camera.Position = new Vector3D(-100, 50, CameraMove);
ISceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator(
selector, //specifies how the world, against collision detection is done looks like
camera, //object, you
new Vector3D(30, 50, 30),//how big the object is, it is the radius of an ellipsoid
new Vector3D(0, -3, 0), //direction and speed of gravity. (0,0,0) will disable it
new Vector3D(0, 50, 0), //translation: humans have eyes not in the middle of our body so we raise it by 50
0);
camera.AddAnimator(anim);
//device.CursorControl.Visible = false;
// add billboard for drawing where we found an intersection
IBillboardSceneNode bill = smgr.AddBillboardSceneNode(
null, new Dimension2Df(20, 20), new Vector3D(), 0);
bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR);
bill.SetMaterialTexture(0, driver.GetTexture(
path + "particle.bmp"));
bill.SetMaterialFlag(MaterialFlag.LIGHTING, false);
bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false);
Material material = new Material();
material.Texture1 = driver.GetTexture(
path + "faerie2.bmp");
material.Lighting = true;
IAnimatedMeshSceneNode node = null;
IAnimatedMesh faerie = smgr.GetMesh(
path + "faerie.md2");
if (faerie != null)
{
node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
node.Position = new Vector3D(-70, 0, -90);
node.SetMD2Animation(MD2AnimationType.RUN);
node.SetMaterial(0, material);
node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
node.Position = new Vector3D(-70, 0, -30);
node.SetMD2Animation(MD2AnimationType.SALUTE);
node.SetMaterial(0, material);
node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
node.Position = new Vector3D(-70, 0, -60);
node.SetMD2Animation(MD2AnimationType.JUMP);
node.SetMaterial(0, material);
}
material.Texture1 = null;
material.Lighting = false;
//Add a light
smgr.AddLightSceneNode(null, new Vector3D(-60, 100, 400),
new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 600, 0);
/*For not making it too complicated, I'm doing picking inside the drawing
loop. We take two pointers for storing the current and the last selected
scene node and start the loop.*/
ISceneNode selectedSceneNode = null;
ISceneNode lastSelectedSceneNode = null;
//end setup *************************************************************
int fps = -1;
//while (device.Run() && c.Enabled)
while (device.Run())
{
device.VideoDriver.BeginScene(true, true, new Irrlicht.Video.Color(0, 100, 100, 100));
device.SceneManager.DrawAll();
//device.GUIEnvironment.DrawAll();
//draw a line from the camera out and ask colision manager
//Does it hit a triange?
//if yes then we draw the billboard at that position
Line3D line = new Line3D();
line.start = camera.Position;
line.end = line.start +
(camera.Target - line.start).Normalize() * 1000;
Vector3D intersection;
Triangle3D tri;
if (smgr.SceneCollisionManager.GetCollisionPoint(
line, selector, out intersection, out tri))
{
bill.Position = intersection;
driver.SetTransform(TransformationState.WORLD, new Matrix4());
driver.SetMaterial(material);
driver.Draw3DTriangle(tri, new Irrlicht.Video.Color(0, 255, 0, 0));
}
//this illustates scene node picking based on bounding boxes
selectedSceneNode = smgr.SceneCollisionManager.GetSceneNodeFromCameraBB(camera, 0, false);
if (lastSelectedSceneNode != null)
lastSelectedSceneNode.SetMaterialFlag(
MaterialFlag.LIGHTING, true);
if (selectedSceneNode == q3node ||
selectedSceneNode == bill)
selectedSceneNode = null;
if (selectedSceneNode != null)
selectedSceneNode.SetMaterialFlag(
MaterialFlag.LIGHTING, false);
lastSelectedSceneNode = selectedSceneNode;
if (KeyBoard.KeyState[(int)Keys.Left] || KeyBoard.KeyState[(int)Keys.A])//left arrow key
{
camera.Position = new Vector3D(-100, 50, CameraMove = CameraMove + 1);
}
device.VideoDriver.EndScene();
System.Windows.Forms.Application.DoEvents();
if (ShowFPS == true)// display (or dont) the FPS
{
// display frames per second value
if (fps != device.VideoDriver.FPS)
{
fps = device.VideoDriver.FPS;
Text = (TextViewer + " FPS " + fps);
}// end if
}// end if
}// end while loop
}// end method runIrrlichtInWindowsFormTest
}// end class
}// end namespace
Sincerely