rastaman
14-12-2005 17:21:06
big post here
Ok here is the quick and dirty of it. I made alot of other changes but this will get SceneQuery working.
first the small stuff.
OgreBindings.i at line 25 (blank line) add this:
%include new_std_list.i
now for some reason because swig can see a std_list we need to ignore some things, I made a custom wrap for it but its not needed for SceneQuery.
OgreResourceGroupManager.i at line 16 add this:
%ignore Ogre::ResourceGroupManager::ResourceDeclarationList;
%ignore Ogre::ResourceGroupManager::getResourceDeclarationList;
CLSCompliancy.i line 219 add this block:
//Const pointer reference typemaps:
%define PTR_REF_TYPEMAPS(CSTYPE, CTYPE)
#if defined(SWIGCSHARP)
%typemap(ctype) CTYPE *, CTYPE & "void *"
%typemap(imtype) CTYPE *, CTYPE & "IntPtr"
%typemap(cstype) CTYPE *, CTYPE & "CSTYPE"
%typemap(csin) CTYPE *, CTYPE & "CSTYPE.getCPtr($csinput).Handle"
%typemap(csout, excode=SWIGEXCODE) CTYPE *, CTYPE & {
IntPtr cPtr = $imcall;
return (cPtr == IntPtr.Zero) ? null : new CSTYPE(cPtr, $owner);
}
%typemap(in) CTYPE *, CTYPE & %{ $1 = (CTYPE *)$input; %}
%typemap(out) CTYPE *, CTYPE & %{ $result = (void *)$1; %}
#endif
%enddef
in OgreSceneQuery.i replace the whole thing with this:
%{
#include "OgreSceneQuery.h"
%}
%ignore Ogre::SceneQuery::getSupportedWorldFragmentTypes;
%ignore Ogre::RaySceneQueryListener::queryResult; //ignores both
%ignore Ogre::SceneQueryListener::queryResult; //ignores both
%ignore Ogre::RegionSceneQuery::queryResult; //ignores both
%ignore Ogre::RaySceneQuery::queryResult; // ignores both
%ignore Ogre::RaySceneQueryResultEntry::worldFragment;
%ignore Ogre::SceneQueryResult::worldFragments;
//TODO IntersectionSceneQuery
%ignore Ogre::IntersectionSceneQueryListener;
%ignore Ogre::SceneQueryMovableObjectPair;
%ignore Ogre::SceneQueryMovableObjectWorldFragmentPair;
%ignore Ogre::SceneQueryMovableIntersectionList;
%ignore Ogre::SceneQueryMovableWorldFragmentIntersectionList;
%ignore Ogre::IntersectionSceneQueryResult;
%ignore Ogre::IntersectionSceneQuery;
//----------------------------------------------------------------
//
// WFragment
//
%{
namespace Ogre {
class WFragment {
protected:
SceneQuery::WorldFragment *mWF;
public:
WFragment() { mWF=0; }
WFragment(SceneQuery::WorldFragment *p) { mWF=p; }
SceneQuery::WorldFragmentType getFragmentType()
{ if (mWF!=0) return mWF->fragmentType; else return SceneQuery::WFT_NONE; }
Vector3 getSingleIntersection()
{ if (mWF!=0) return mWF->singleIntersection; else return Ogre::Vector3::ZERO; }
std::list<Plane>* getPlanes()
{ if (mWF!=0) return mWF->planes; else return 0; }
void* getGeometry()
{ if (mWF!=0) return (void*)mWF->geometry; else return 0; }
//RenderOperation* renderOp;
void* getRenderOp()
{ if (mWF!=0) return (void*)mWF->renderOp; else return 0; }
};
class ListWFragment {
protected:
//typedef std::list<SceneQuery::WorldFragment*> SceneQueryResultWorldFragmentList;
SceneQueryResultWorldFragmentList *mList;
public:
ListWFragment() { mList=0; }
ListWFragment(SceneQueryResultWorldFragmentList *p) { mList=p; }
size_t size()
{ if (mList==0) return 0;
return mList->size();
}
WFragment *getFirst()
{ if (mList==0) return 0;
SceneQueryResultWorldFragmentList::iterator it =mList->begin();
if (it == mList->end()) return 0;
else return new WFragment( (SceneQuery::WorldFragment*)(*it) );
}
WFragment *getLast()
{ if (mList==0) return 0;
SceneQueryResultWorldFragmentList::reverse_iterator rit =mList->rbegin();
if (rit == mList->rend()) return 0;
else return new WFragment( (SceneQuery::WorldFragment*)(*rit) );
}
WFragment *getByIndex(int index)
{ if (mList==0) return 0;
SceneQueryResultWorldFragmentList::iterator it =mList->begin();
if (it == mList->end())
return 0;
std::advance(it, index);
if (it == mList->end())
return 0;
else
return new WFragment( (SceneQuery::WorldFragment*)(*it) );
}
};
}
%}
namespace Ogre {
class WFragment {
public:
WFragment();
Ogre::SceneQuery::WorldFragmentType getFragmentType();
Vector3 getSingleIntersection();
std::list<Plane>* getPlanes();
void* getGeometry();
void* getRenderOp();
};
class ListWFragment {
public:
ListWFragment();
size_t size();
WFragment *getFirst();
WFragment *getLast();
WFragment *getByIndex(int index);
};
}
%extend Ogre::RaySceneQueryResultEntry {
/// The world fragment, or NULL if this is not a fragment result
WFragment *getWorldFragment()
{ return new Ogre::WFragment(self->worldFragment); }
};
%extend Ogre::SceneQueryResult {
/// The world fragment, or NULL if this is not a fragment result
ListWFragment *getWorldFragments()
{ return new Ogre::ListWFragment(&self->worldFragments); }
};
//----------------------------------------------------------------
//
// RaySceneQueryListenerHandler
//
%ignore Ogre::RaySceneQueryListenerHandler::queryResult;
%ignore Ogre::RaySceneQueryListenerHandler::mFPqueryResultMO;
%ignore Ogre::RaySceneQueryListenerHandler::mFPqueryResultWF;
%ignore Ogre::RSQL_queryResultMO_Function;
%ignore Ogre::RSQL_queryResultWF_Function;
%{
#ifdef SWIG
#define __stdcall
#define __declspec(x)
#endif
namespace Ogre {
typedef bool (__stdcall *RSQL_queryResultMO_FunctionPointer)( Ogre::MovableObject*, Real );
typedef bool (__stdcall *RSQL_queryResultWF_FunctionPointer)( Ogre::SceneQuery::WorldFragment*, Real);
}
%}
%inline %{
namespace Ogre {
class RaySceneQueryListenerHandler : public RaySceneQueryListener
{
public:
RSQL_queryResultMO_FunctionPointer mFPqueryResultMO;
RSQL_queryResultWF_FunctionPointer mFPqueryResultWF;
RaySceneQueryListenerHandler()
{
mFPqueryResultMO =0;
mFPqueryResultWF =0;
}
bool queryResult(MovableObject* obj, Real distance)
{
if( mFPqueryResultMO )
return mFPqueryResultMO(obj, distance);
else
return false; //'false' to abandon any further results from the current query
}
bool queryResult(SceneQuery::WorldFragment* fragment, Real distance)
{
if( mFPqueryResultWF )
return mFPqueryResultWF(fragment, distance);
else
return false; //'false' to abandon any further results from the current query
}
};
extern "C" __declspec(dllexport) void RSQL_queryResultMO_Function( RaySceneQueryListenerHandler * cv, void * fn )
{
cv->mFPqueryResultMO = (RSQL_queryResultMO_FunctionPointer)fn;
}
extern "C" __declspec(dllexport) void RSQL_queryResultWF_Function( RaySceneQueryListenerHandler * cv, void * fn )
{
cv->mFPqueryResultWF = (RSQL_queryResultWF_FunctionPointer)fn;
}
}
%}
%typemap(cscode) RaySceneQueryListenerHandler %{
public delegate bool RSQLQueryResultMODelegate( MovableObject, float );
public delegate bool RSQLQueryResultWFDelegate( WFragment, float );
protected delegate bool _RSQL_queryResultMO_Delegate( MovableObject, float );
protected delegate bool _RSQL_queryResultWF_Delegate( WFragment, float );
public void SubscribeEvents()
{
mGetValueDelegate = new _CVFH_GetValue_Delegate(GetValueHandler);
SetGetValueFunction(swigCPtr, mGetValueDelegate);
mSetValueDelegate = new _CVFH_SetValue_Delegate(SetValueHandler);
SetSetValueFunction(swigCPtr, mSetValueDelegate);
}
// RSQLQueryResultMODelegate handling
public event RSQLQueryResultMODelegate QueryResultMO = null;
[DllImport("OgreBindings", EntryPoint="RSQL_queryResultMO_Function")]
protected static extern void SetQueryResultMOFunction( HandleRef rayscenequerylistenerhandler, _RSQL_queryResultMO_Delegate fn );
protected _RSQL_queryResultMO_Delegate mQueryResultMODelegate = null;
protected bool QueryResultMOHandler( MovableObject obj, float distance )
{
if( QueryResultMO != null )
return QueryResultMO( );
return false;
}
// RSQLQueryResultWFDelegate handling
public event RSQLQueryResultWFDelegate QueryResultWF = null;
[DllImport("OgreBindings", EntryPoint="RSQL_queryResultWF_Function")]
protected static extern void SetQueryResultWFFunction( HandleRef rayscenequerylistenerhandler, _RSQL_queryResultWF_Delegate fn );
protected _RSQL_queryResultWF_Delegate mQueryResultWFDelegate = null;
protected bool QueryResultWFHandler( WFragment fragment, float distance )
{
if( QueryResultWF != null )
return QueryResultWF( );
return false;
}
%}
%include OgreSceneQuery.h
//----------------------------------------------------------------
// templates
//for WFragment aka SceneQuery::WorldFragment
SWIG_STD_LIST_SPECIALIZE_MINIMUM(Plane, Ogre::Plane)
%template(ListPlane) std::list<Ogre::Plane>;
// typedef std::list<RaySceneQueryResultEntry> RaySceneQueryResult;
SWIG_STD_LIST_SPECIALIZE_MINIMUM(RaySceneQueryResultEntry, Ogre::RaySceneQueryResultEntry)
%template(ListRaySceneQueryResult) std::list<Ogre::RaySceneQueryResultEntry>;
PTR_REF_TYPEMAPS(MovableObject, Ogre::MovableObject*)
// typedef std::list<MovableObject*> SceneQueryResultMovableList;
SWIG_STD_LIST_SPECIALIZE(MovableObject, Ogre::MovableObject*)
%template(ListSceneQueryResultMovable) std::list<Ogre::MovableObject*>;
// typedef std::pair<MovableObject*, MovableObject*> SceneQueryMovableObjectPair;
// typedef std::list<SceneQueryMovableObjectPair> SceneQueryMovableIntersectionList;
%template(PairMovableObject) std::pair<Ogre::MovableObject*, Ogre::MovableObject*>;
SWIG_STD_LIST_SPECIALIZE_MINIMUM(PairMovableObject, Ogre::SceneQueryMovableObjectPair)
%template(ListSceneQueryMovableIntersection) std::list<Ogre::SceneQueryMovableObjectPair>;
//dont know about this yet
// typedef std::pair<MovableObject*, SceneQuery::WorldFragment*> SceneQueryMovableObjectWorldFragmentPair;
// typedef std::list<SceneQueryMovableObjectWorldFragmentPair> SceneQueryMovableWorldFragmentIntersectionList;
//%template(PairMovableObjectWorldFragment) std::pair<Ogre::MovableObject*, Ogre::SceneQuery::WorldFragment*>;
now the new file new_std_list.i gose in dir ogredotnet/OgreNet/
// Warning: Use the typemaps here in the expectation that the macros they are in will change name.
#pragma SWIG nowarn=302 //Warning(302): Identifier 'list' redefined (ignored),
/*
* SWIG typemaps for std::list
* C# implementation
* The C# wrapper is made to look and feel like a typesafe C# System.Collections.ArrayList
* All the methods in IList are defined, but we don't derive from IList as this is a typesafe collection.
* Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
*/
%include <std_common.i>
// MACRO for use within the std::list class body
// CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
%define SWIG_STD_LIST_MINIMUM(CSTYPE, CTYPE...)
%typemap(csinterfaces) std::list<CTYPE > "IDisposable, System.Collections.IEnumerable";
%typemap(cscode) std::list<CTYPE > %{
public $csclassname(System.Collections.ICollection c) : this() {
if (c == null)
throw new ArgumentNullException("c");
foreach (CSTYPE element in c) {
this.Add(element);
}
}
public bool IsFixedSize {
get {
return false;
}
}
public bool IsReadOnly {
get {
return false;
}
}
public CSTYPE this[int index] {
get {
return getitem(index);
}
}
public int Count {
get {
return (int)size();
}
}
public bool IsSynchronized {
get {
return false;
}
}
public void CopyTo(System.Array array) {
CopyTo(0, array, 0, this.Count);
}
public void CopyTo(System.Array array, int arrayIndex) {
CopyTo(0, array, arrayIndex, this.Count);
}
public void CopyTo(int index, System.Array array, int arrayIndex, int count) {
if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("index", "Value is less than zero");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
if (count < 0)
throw new ArgumentOutOfRangeException("count", "Value is less than zero");
if (array.Rank > 1)
throw new ArgumentException("Multi dimensional array.");
if (index+count > this.Count || arrayIndex+count > array.Length)
throw new ArgumentException("Number of elements to copy is too large.");
for (int i=0; i<count; i++)
array.SetValue(getitemcopy(index+i), arrayIndex+i);
}
// Type-safe version of IEnumerable.GetEnumerator
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return new $csclassnameEnumerator(this);
}
public $csclassnameEnumerator GetEnumerator() {
return new $csclassnameEnumerator(this);
}
// Type-safe enumerator
/// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
/// whenever the collection is modified. This has been done for changes in the size of the
/// collection but not when one of the elements of the collection is modified as it is a bit
/// tricky to detect unmanaged code that modifies the collection under our feet.
public sealed class $csclassnameEnumerator : System.Collections.IEnumerator {
private $csclassname collectionRef;
private int currentIndex;
private object currentObject;
private int currentSize;
public $csclassnameEnumerator($csclassname collection) {
collectionRef = collection;
currentIndex = -1;
currentObject = null;
currentSize = collectionRef.Count;
}
// Type-safe iterator Current
public CSTYPE Current {
get {
if (currentIndex == -1)
throw new InvalidOperationException("Enumeration not started.");
if (currentIndex > currentSize - 1)
throw new InvalidOperationException("Enumeration finished.");
if (currentObject == null)
throw new InvalidOperationException("Collection modified.");
return (CSTYPE)currentObject;
}
}
// Type-unsafe IEnumerator.Current
object System.Collections.IEnumerator.Current {
get {
return Current;
}
}
public bool MoveNext() {
int size = collectionRef.Count;
bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
if (moveOkay) {
currentIndex++;
currentObject = collectionRef[currentIndex];
} else {
currentObject = null;
}
return moveOkay;
}
public void Reset() {
currentIndex = -1;
currentObject = null;
if (collectionRef.Count != currentSize) {
throw new InvalidOperationException("Collection modified.");
}
}
}
%}
public:
typedef size_t size_type;
%rename(Clear) clear;
void clear();
%rename(Add) push_back;
void push_back(CTYPE value);
size_type size() const;
%newobject GetRange(int index, int count);
%newobject Repeat(CTYPE value, int count);
list();
%extend {
list() throw (std::out_of_range) {
std::list<CTYPE >* pv = 0;
pv = new std::list<CTYPE >();
return pv;
}
CTYPE getitemcopy(int index) throw (std::out_of_range) {
if (index>=0 && index<(int)self->size()) {
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
return (*it);
}
else
throw std::out_of_range("index");
}
CTYPE getitem(int index) throw (std::out_of_range) {
if (index>=0 && index<(int)self->size()) {
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
return (*it);
}
else
throw std::out_of_range("index");
}
// Takes a deep copy of the elements unlike ArrayList.AddRange
void AddRange(const std::list<CTYPE >& values) {
self->insert(self->end(), values.begin(), values.end());
}
// Takes a deep copy of the elements unlike ArrayList.GetRange
std::list<CTYPE > *GetRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
if (index < 0)
throw std::out_of_range("index");
if (count < 0)
throw std::out_of_range("count");
if (index >= (int)self->size()+1 || index+count > (int)self->size())
throw std::invalid_argument("invalid range");
std::list<CTYPE >::iterator it=(*self).begin(), itEnd=(*self).begin();
std::advance(it,index);
std::advance(itEnd,index+count);
return new std::list<CTYPE >(it, itEnd);
}
void Insert(int index, CTYPE value) throw (std::out_of_range) {
if (index>=0 && index<(int)self->size()+1) {
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
self->insert(it, value);
}
else
throw std::out_of_range("index");
}
// Takes a deep copy of the elements unlike ArrayList.InsertRange
void InsertRange(int index, const std::list<CTYPE >& values) throw (std::out_of_range) {
if (index>=0 && index<(int)self->size()+1) {
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
self->insert(it, values.begin(), values.end());
}
else
throw std::out_of_range("index");
}
void RemoveAt(int index) throw (std::out_of_range) {
if (index>=0 && index<(int)self->size()) {
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
self->erase(it);
}
else
throw std::out_of_range("index");
}
void RemoveRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
if (index < 0)
throw std::out_of_range("index");
if (count < 0)
throw std::out_of_range("count");
if (index >= (int)self->size()+1 || index+count > (int)self->size())
throw std::invalid_argument("invalid range");
std::list<CTYPE >::iterator it=(*self).begin(), itEnd=(*self).begin();
std::advance(it,index);
std::advance(itEnd,index+count);
self->erase(it, itEnd);
}
static std::list<CTYPE > *Repeat(CTYPE value, int count) throw (std::out_of_range) {
if (count < 0)
throw std::out_of_range("count");
return new std::list<CTYPE >(count, value);
}
void Reverse() {
self->reverse();
}
void Reverse(int index, int count) throw (std::out_of_range, std::invalid_argument) {
if (index < 0)
throw std::out_of_range("index");
if (count < 0)
throw std::out_of_range("count");
if (index >= (int)self->size()+1 || index+count > (int)self->size())
throw std::invalid_argument("invalid range");
std::list<CTYPE >::iterator it=(*self).begin(), itEnd=(*self).begin();
std::advance(it,index);
std::advance(itEnd,index+count);
std::reverse(it, itEnd);
}
// Takes a deep copy of the elements unlike ArrayList.SetRange
void SetRange(int index, const std::list<CTYPE >& values) throw (std::out_of_range) {
if (index < 0)
throw std::out_of_range("index");
if (index+values.size() > self->size())
throw std::out_of_range("index");
std::list<CTYPE >::iterator it = (*self).begin();
std::advance(it,index);
std::copy(values.begin(), values.end(), it);
}
}
%enddef
// Extra methods added to the collection class if operator== is defined for the class being wrapped
// CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
%define SWIG_STD_LIST_EXTRA_OP_EQUALS_EQUALS(CSTYPE, CTYPE...)
%extend {
bool Contains(CTYPE value) {
return std::find(self->begin(), self->end(), value) != self->end();
}
int IndexOf(CTYPE value) {
int index = -1;
std::list<CTYPE >::iterator it = std::find(self->begin(), self->end(), value);
if (it != self->end())
index = std::distance( self->begin(), it );
return index;
}
int LastIndexOf(CTYPE value) {
int index = -1;
std::list<CTYPE >::reverse_iterator rit = std::find(self->rbegin(), self->rend(), value);
if (rit != self->rend())
index = std::distance( self->rbegin(), rit );
return index;
}
void Remove(CTYPE value) {
std::list<CTYPE >::iterator it = std::find(self->begin(), self->end(), value);
if (it != self->end())
self->erase(it);
}
}
%enddef
// Macros for std::list class specializations
// CSTYPE and CTYPE respectively correspond to the types in the cstype and ctype typemaps
%define SWIG_STD_LIST_SPECIALIZE(CSTYPE, CTYPE...)
namespace std {
template<> class list<CTYPE > {
SWIG_STD_LIST_MINIMUM(CSTYPE, CTYPE)
SWIG_STD_LIST_EXTRA_OP_EQUALS_EQUALS(CSTYPE, CTYPE)
};
}
%enddef
%define SWIG_STD_LIST_SPECIALIZE_MINIMUM(CSTYPE, CTYPE...)
namespace std {
template<> class list<CTYPE > {
SWIG_STD_LIST_MINIMUM(CSTYPE, CTYPE)
};
}
%enddef
%{
#include <list>
#include <algorithm>
#include <stdexcept>
%}
%csmethodmodifiers std::list::getitemcopy "private"
%csmethodmodifiers std::list::getitem "private"
%csmethodmodifiers std::list::size "private"
namespace std {
// primary (unspecialized) class template for std::list
// does not require operator== to be defined
template<class T> class list {
SWIG_STD_LIST_MINIMUM(T, T)
};
}
// template specializations for std::list
// these provide extra collections methods as operator== is defined
SWIG_STD_LIST_SPECIALIZE(bool, bool)
SWIG_STD_LIST_SPECIALIZE(char, char)
SWIG_STD_LIST_SPECIALIZE(sbyte, signed char)
SWIG_STD_LIST_SPECIALIZE(byte, unsigned char)
SWIG_STD_LIST_SPECIALIZE(short, short)
SWIG_STD_LIST_SPECIALIZE(ushort, unsigned short)
SWIG_STD_LIST_SPECIALIZE(int, int)
SWIG_STD_LIST_SPECIALIZE(uint, unsigned int)
SWIG_STD_LIST_SPECIALIZE(int, long)
SWIG_STD_LIST_SPECIALIZE(uint, unsigned long)
SWIG_STD_LIST_SPECIALIZE(long, long long)
SWIG_STD_LIST_SPECIALIZE(ulong, unsigned long long)
SWIG_STD_LIST_SPECIALIZE(float, float)
SWIG_STD_LIST_SPECIALIZE(double, double)
SWIG_STD_LIST_SPECIALIZE(string, std::string) // also requires a %include "std_string.i"
#pragma SWIG nowarn=+302 //turn it back on
now here is a test app create a new project and copy the cApp.cs from DemoGrass and change the namespace RSQTest.
using System;
using System.Drawing;
using Math3D;
using OgreDotNet;
namespace RSQTest
{
class cRSQTest : cApplication
{
protected OgreDotNet.Log mLog;
protected Ray mRay;
protected RaySceneQuery mRaySceneQuery;
protected override void CreateScene()
{
mLog = LogManager.Singleton.createLog("RSQTest.log", false, true );
mLog.LogMessage(string.Format("RSQTest log {0}" , System.DateTime.Now ) );
Plane plane = new Plane();
plane.Normal.x=0;
plane.Normal.y=1;
plane.Normal.z=0;
plane.D = 0;
MeshManager.GetSingleton().CreatePlane( "Myplane", "General" , plane,
500,500,10,10,true,1,10,10,Vector3.UnitZ );
Entity pPlaneEnt = mSceneManager.CreateEntity( "plane", "Myplane" );
pPlaneEnt.SetMaterialName("Examples/GrassFloor");
pPlaneEnt.SetCastShadows(false);
mSceneManager.GetRootSceneNode().CreateChildSceneNode().AttachObject(pPlaneEnt);
for (int x=0; x<4; x++) {
string sname = string.Format("head{0}", x);
Entity e = mSceneManager.CreateEntity( sname, "ogrehead.mesh");
SceneNode n = mSceneManager.GetRootSceneNode().CreateChildSceneNode(sname);
n.AttachObject(e);
float px=(x%2==0?-100:100);
float pz=((x<=1)?-100:100);
n.SetPosition( px, 40.0f, pz );
mLog.LogMessage(string.Format("{0} , at ({1}, {2}, {3})", sname, px, 40.0f, pz ));
}
mRay = new OgreDotNet.Ray(Vector3.Zero, Vector3.NegativeUnitY );
mRaySceneQuery = mSceneManager.CreateRayQuery( mRay );
mCamera.Move( new Vector3(0, 100, 600) );
mCamera.LookAt = new Vector3( 0, 0, 0 );
}
protected override bool FrameStarted( FrameEvent e )
{
if (!base.FrameStarted( e ))
return false;
//SceneNode n = mSceneManager.GetSceneNode("TriangleNode");
//n.Yaw( new Radian(50.0f));
Vector3 p = mCamera.GetPosition();
p.y = 3000.0f;
mRay.setOrigin( p );
mRaySceneQuery.setRay( mRay );
ListRaySceneQueryResult qryResult = mRaySceneQuery.execute();
if (qryResult.Count > 0)
{
RaySceneQueryResultEntry qryEntry = qryResult[0];
OgreDotNet.WFragment wf = qryEntry.getWorldFragment();
if (wf != null)
{
p = mCamera.GetPosition();
mCamera.SetPosition( p.x, wf.getSingleIntersection().y + 1.0f, p.z );
}
}
return true;
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
using(cRSQTest app = new cRSQTest() )
{
app.Start();
}
}
}
}