Added Box2D

This commit is contained in:
Julian Nießner
2018-05-06 12:43:20 +02:00
parent cb5469bb89
commit d175d433a8
351 changed files with 123545 additions and 1 deletions

View File

@@ -0,0 +1,32 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class AABB
{
public:
Vector ^lowerBound, ^upperBound;
bool IsValid()
{
return getAABB().IsValid();
}
AABB(Vector^ min, Vector^ max) : lowerBound(gcnew Vector(min)), upperBound(gcnew Vector(max)) { }
AABB() : lowerBound(gcnew Vector()), upperBound(gcnew Vector()) { }
b2AABB getAABB()
{
b2AABB returnme;
returnme.lowerBound = lowerBound->getVec2();
returnme.upperBound = upperBound->getVec2();
return returnme;
}
};
}
}

View File

@@ -0,0 +1,40 @@
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("Box2DNet")];
[assembly:AssemblyDescriptionAttribute("A .NET wrapper for the Box2D physics library")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("")];
[assembly:AssemblyProductAttribute("Box2DNet")];
[assembly:AssemblyCopyrightAttribute("Copyright (c) Jay Lemmon 2008")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];

View File

@@ -0,0 +1,243 @@
#pragma once
#include "Stdafx.h"
#include "Vector.cpp"
#include "Shape.cpp"
#include "ShapeDef.cpp"
namespace Box2D
{
namespace Net
{
/// <summary>
/// A rigid body. Internal computation are done in terms
/// of the center of mass position. The center of mass may
/// be offset from the body's origin.
/// </summary>
public ref class Body
{
internal:
b2Body *body;
Body(b2Body *bodyRef) : body(bodyRef) { }
public:
/// <summary>
/// Set the position of the body's origin and rotation (radians).
/// This breaks any contacts and wakes the other bodies.
/// </summary>
void SetXForm(Vector^ position, float32 rotation)
{
body->SetXForm(position->getVec2(), rotation);
}
/// <summary>
/// Get the position of the body's origin. The body's origin does not
/// necessarily coincide with the center of mass. It depends on how the
/// shapes are created.
/// </summary>
XForm^ GetXForm()
{
return gcnew XForm(body->GetXForm());
}
///<summary>Accesses the linear velocity of the center of mass.</summary>
property Vector^ LinearVelocity
{
Vector^ get()
{
return gcnew Vector(body->GetLinearVelocity());
}
void set(Vector^ value)
{
body->SetLinearVelocity(value->getVec2());
}
}
///<summary>Accesses the angular velocity.</summary>
property float32 AngularVelocity
{
float32 get()
{
return body->GetAngularVelocity();
}
void set(float32 value)
{
body->SetAngularVelocity(value);
}
}
///<summary> Apply a force at a world point. Additive. </summary>
void ApplyForce(Vector^ Force, Vector^ Point)
{
body->ApplyForce(Force->getVec2(), Point->getVec2());
}
///<summary> Apply a torque. Additive. </summary>
void ApplyTorque(float32 Torque)
{
body->ApplyTorque(Torque);
}
///<summary> Apply an impulse at a point. This immediately modifies the velocity. </summary>
void ApplyImpulse(Vector^ Impulse, Vector^ Point)
{
body->ApplyImpulse(Impulse->getVec2(), Point->getVec2());
}
///<summary>Accesses the Mass.</summary>
property float32 Mass
{
float32 get()
{
return body->GetMass();
}
}
///<summary>Accesses the Mass.</summary>
property float32 Inertia
{
float32 get()
{
return body->GetInertia();
}
}
/// <summary>
/// Get the world coordinates of a point give the local coordinates
/// relative to the body's center of mass.
/// </summary>
Vector^ GetWorldPoint(Vector^ LocalPoint)
{
return gcnew Vector(body->GetWorldPoint(LocalPoint->getVec2()));
}
/// <summary>
/// Get the world coordinates of a vector given the local coordinates.
/// </summary>
Vector^ GetWorldVector(Vector^ LocalVector)
{
return gcnew Vector(body->GetWorldVector(LocalVector->getVec2()));
}
/// <summary>
/// Returns a local point relative to the center of mass given a world point.
/// </summary>
Vector^ GetLocalPoint(Vector^ WorldPoint)
{
return gcnew Vector(body->GetLocalPoint(WorldPoint->getVec2()));
}
/// <summary>
/// Returns a local vector given a world vector.
/// </summary>
Vector^ GetLocalVector(Vector^ WorldVector)
{
return gcnew Vector(body->GetLocalVector(WorldVector->getVec2()));
}
///<summary>Is this body static (immovable)</summary>
property bool Static
{
bool get()
{
return body->IsStatic();
}
}
///<summary>Is this body frozen</summary>
property bool Frozen
{
bool get()
{
return body->IsFrozen();
}
}
///<summary>Is this body sleeping</summary>
property bool Sleeping
{
bool get()
{
return body->IsSleeping();
}
}
///<summary>You can disable sleeping on this particular body.</summary>
property bool AllowSleeping
{
bool get()
{
return body->IsSleeping();
}
void set(bool value)
{
body->AllowSleeping(value);
}
}
property bool Bullet
{
bool get()
{
return body->IsBullet();
}
void set(bool value)
{
body->SetBullet(value);
}
}
void WakeUp()
{
body->WakeUp();
}
///<summary> Get the list of all shapes attached to this body.</summary>
property IList<Shape^>^ Shapes
{
IList<Shape^>^ get()
{
List<Shape^>^ list = gcnew List<Shape^>();
for(b2Shape *shape = body->GetShapeList(); shape; shape = shape->GetNext())
list->Add(gcnew Shape(shape));
return list;
}
}
void CreateShape(ShapeDef^ def)
{
body->CreateShape(def->def);
}
void DestroyShape(Shape^ shape)
{
body->DestroyShape(shape->shape);
}
void SetMassFromShapes()
{
body->SetMassFromShapes();
}
//TODO:
//void* GetUserData();
//const b2Mat22& GetRotationMatrix() const;
};
}
}
/*
TODO:
public:
// Get the list of all contacts attached to this body.
b2ContactNode* GetContactList();
// Get the list of all joints attached to this body.
b2JointNode* GetJointList();
*/

View File

@@ -0,0 +1,168 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "ShapeDef.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
/// The type of body.
public enum class BodyType
{
e_staticBody = ::b2BodyDef::e_staticBody, ///< A static body should not move and has infinite mass.
e_dynamicBody = ::b2BodyDef::e_dynamicBody ///< A regular moving body.
};
public ref class BodyDef
{
internal:
b2BodyDef *def;
public:
BodyDef() : def(new b2BodyDef()) { }
virtual ~BodyDef()
{
delete def;
}
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(def->position);
}
void set(Vector^ value)
{
def->position = value->getVec2();
}
}
property float32 Angle
{
float32 get()
{
return def->angle;
}
void set(float32 value)
{
def->angle = value;
}
}
property float32 LinearDamping
{
float32 get()
{
return def->linearDamping;
}
void set(float32 value)
{
def->linearDamping = value;
}
}
property float32 AngularDamping
{
float32 get()
{
return def->angularDamping;
}
void set(float32 value)
{
def->angularDamping = value;
}
}
property bool AllowSleep
{
bool get()
{
return def->allowSleep;
}
void set(bool value)
{
def->allowSleep = value;
}
}
property bool IsBullet
{
bool get()
{
return def->isBullet;
}
void set(bool value)
{
def->isBullet = value;
}
}
property bool IsSleeping
{
bool get()
{
return def->isSleeping;
}
void set(bool value)
{
def->isSleeping = value;
}
}
property bool FixedRotation
{
bool get()
{
return def->fixedRotation;
}
void set(bool value)
{
def->fixedRotation = value;
}
}
property BodyType BodyType
{
Box2D::Net::BodyType get()
{
return (Box2D::Net::BodyType)def->type;
}
void set(Box2D::Net::BodyType value)
{
def->type = ((::b2BodyDef::Type)value);
}
}
//TODO:
/*property Object^ UserData
{
Object^ get()
{
Object^ ReturnMe;
System::Runtime::InteropServices::Marshal::PtrToStructure((System::IntPtr)def->userData, ReturnMe);
return ReturnMe;
}
void set(Object^ value)
{
def->userData = value;
}
}*/
};
}
}

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="Box2D.Net"
ProjectGUID="{0E95DBB9-EA97-407B-811C-810B225E79D2}"
RootNamespace="Box2DNet"
Keyword="ManagedCProj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\Include\"
PreprocessorDefinitions="WIN32;_DEBUG"
RuntimeLibrary="3"
UsePrecompiledHeader="1"
GenerateXMLDocumentationFiles="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
AssemblyDebug="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\Include\"
PreprocessorDefinitions="WIN32;NDEBUG"
RuntimeLibrary="2"
UsePrecompiledHeader="1"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
<AssemblyReference
RelativePath="System.dll"
AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
<AssemblyReference
RelativePath="System.Data.dll"
AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
/>
<AssemblyReference
RelativePath="System.XML.dll"
AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AssemblyInfo.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\Stdafx.h"
>
</File>
</Filter>
<Filter
Name="Wrappers"
>
<File
RelativePath=".\AABB.cpp"
>
</File>
<File
RelativePath=".\Body.cpp"
>
</File>
<File
RelativePath=".\BodyDef.cpp"
>
</File>
<File
RelativePath=".\Contact.cpp"
>
</File>
<File
RelativePath=".\Delegates.cpp"
>
</File>
<File
RelativePath=".\Joint.cpp"
>
</File>
<File
RelativePath=".\JointDef.cpp"
>
</File>
<File
RelativePath=".\Manifold.cpp"
>
</File>
<File
RelativePath=".\ManifoldPoint.cpp"
>
</File>
<File
RelativePath=".\MassData.cpp"
>
</File>
<File
RelativePath=".\Matrix.cpp"
>
</File>
<File
RelativePath=".\RevoluteJoint.cpp"
>
</File>
<File
RelativePath=".\Shape.cpp"
>
</File>
<File
RelativePath=".\Shape.h"
>
</File>
<File
RelativePath=".\ShapeDef.cpp"
>
</File>
<File
RelativePath=".\ShapeType.cpp"
>
</File>
<File
RelativePath=".\VariousImplementations.cpp"
>
</File>
<File
RelativePath=".\Vector.cpp"
>
</File>
<File
RelativePath=".\World.cpp"
>
</File>
<File
RelativePath=".\XForm.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,53 @@
#pragma once
#include "stdafx.h"
#include "Shape.cpp"
#include "Manifold.cpp"
namespace Box2D
{
namespace Net
{
public ref class Contact
{
internal:
b2Contact *contact;
Contact(b2Contact *contactRef) : contact(contactRef) { }
public:
property Shape^ Shape1
{
Shape^ get()
{
return gcnew Shape(contact->GetShape1());
}
}
property Shape^ Shape2
{
Shape^ get()
{
return gcnew Shape(contact->GetShape2());
}
}
Contact^ GetNext()
{
return gcnew Contact(contact->GetNext());
}
Manifold^ GetManifolds()
{
return gcnew Manifold(contact->GetManifolds());
}
property int ManifoldCount
{
int get()
{
return contact->GetManifoldCount();
}
}
};
}
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "stdafx.h"
#include "Joint.cpp"
#include "Body.cpp"
namespace Box2D
{
namespace Net
{
/// <summary>
/// If a body is destroyed, then any joints attached to it are also destroyed.
/// This prevents memory leaks, but you may unexpectedly be left with an
/// orphaned joint pointer.
/// Box2D will notify you when a joint is implicitly destroyed.
/// It is NOT called if you directly destroy a joint.
/// DO NOT modify the Box2D world inside this callback.
/// </summary>
public delegate void NotifyJointDestroyed(Joint);
/// <summary>
/// Return true if collision calculations should be performed between shape1 and shape2
/// Box2D has a default implementation for this, so only add a new delegate if you
/// want to override the default behavior.
/// </summary>
public delegate bool CollisionFilter(Shape shape1, Shape shape2);
}
}

View File

@@ -0,0 +1,106 @@
#pragma once
#include "stdafx.h"
#include "Body.cpp"
#include "JointDef.cpp"
namespace Box2D
{
namespace Net
{
public ref class Joint
{
internal:
b2Joint *joint;
Joint(b2Joint *jointRef) : joint(jointRef) { }
public:
property JointType JointType
{
Box2D::Net::JointType get()
{
return (Box2D::Net::JointType) joint->GetType();
}
}
property Body^ Body1
{
Body^ get()
{
return gcnew Body(joint->GetBody1());
}
}
property Body^ Body2
{
Body^ get()
{
return gcnew Body(joint->GetBody2());
}
}
property Vector^ Anchor1
{
Vector^ get()
{
return gcnew Vector(joint->GetAnchor1());
}
}
property Vector^ Anchor2
{
Vector^ get()
{
return gcnew Vector(joint->GetAnchor2());
}
}
Vector^ GetReactionForce()
{
return gcnew Vector(joint->GetReactionForce());
}
float32 GetReactionTorque()
{
return joint->GetReactionTorque();
}
Joint^ GetNext()
{
return gcnew Joint(joint->GetNext());
}
//TODO:
/*
void* GetUserData();
*/
};
public ref class MouseJoint : public Joint
{
internal:
b2MouseJoint *mouseJoint;
MouseJoint(b2MouseJoint *joint) : Joint(joint), mouseJoint(joint) { }
public:
MouseJoint(Joint^ joint) : Joint(joint->joint), mouseJoint(0)
{
if(joint->JointType == Box2D::Net::JointType::e_mouseJoint &&
reinterpret_cast<b2MouseJoint *>(joint->joint))
{
mouseJoint = reinterpret_cast<b2MouseJoint *>(joint->joint);
}
else
{
throw gcnew System::Exception("Attempting to convert a Joint to a MouseJoint, "
"but the joint is not a mouse joint.");
}
}
void SetTarget(Vector^ Target)
{
mouseJoint->SetTarget(Target->getVec2());
}
};
}
}

View File

@@ -0,0 +1,178 @@
#pragma once
#include "stdafx.h"
#include "Body.cpp"
#include "Vector.cpp"
using namespace System::Runtime::InteropServices;
namespace Box2D
{
namespace Net
{
//TODO: is there a way to automatically include the b2JointType as an enum here?
public enum class JointType
{
e_unknownJoint = ::e_unknownJoint,
e_revoluteJoint = ::e_revoluteJoint,
e_prismaticJoint = ::e_prismaticJoint,
e_distanceJoint = ::e_distanceJoint,
e_pulleyJoint = ::e_pulleyJoint,
e_mouseJoint = ::e_mouseJoint,
e_gearJoint = ::e_gearJoint
};
public ref class JointDef
{
internal:
b2JointDef *def;
JointDef() : def(new b2JointDef()) { }
JointDef(b2JointDef *justBuilt) : def(justBuilt) { }
virtual ~JointDef()
{
delete def;
}
public:
property JointType Type
{
JointType get()
{
return (JointType)def->type;
}
void set(JointType value)
{
def->type = (b2JointType)value;
}
}
property Object^ UserData
{
Object^ get()
{
return System::Runtime::InteropServices::GCHandle::FromIntPtr((System::IntPtr)def->userData).Target;
}
void set(Object^ value)
{
GCHandle^ gch = GCHandle::Alloc(value);
def->userData = (void *)gch->ToIntPtr(*gch);
}
}
property Body^ Body1
{
Body^ get()
{
return gcnew Body(def->body1);
}
void set(Body^ value)
{
def->body1 = value->body;
}
}
property Body^ Body2
{
Body^ get()
{
return gcnew Body(def->body2);
}
void set(Body^ value)
{
def->body2 = value->body;
}
}
property bool CollideConnected
{
bool get()
{
return def->collideConnected;
}
void set(bool value)
{
def->collideConnected = value;
}
}
};
public ref class MouseJointDef : public JointDef
{
internal:
b2MouseJointDef *mouseJoint;
public:
MouseJointDef() : JointDef(mouseJoint = new b2MouseJointDef()) { }
property Vector^ Target
{
Vector^ get()
{
return gcnew Vector(mouseJoint->target);
}
void set(Vector^ value)
{
mouseJoint->target = value->getVec2();
}
}
property float32 MaxForce
{
float32 get()
{
return mouseJoint->maxForce;
}
void set(float32 value)
{
mouseJoint->maxForce = value;
}
}
property float32 FrequencyHz
{
float32 get()
{
return mouseJoint->frequencyHz;
}
void set(float32 value)
{
mouseJoint->frequencyHz = value;
}
}
property float32 DampingRatio
{
float32 get()
{
return mouseJoint->dampingRatio;
}
void set(float32 value)
{
mouseJoint->dampingRatio = value;
}
}
property float32 TimeStep
{
float32 get()
{
return mouseJoint->timeStep;
}
void set(float32 value)
{
mouseJoint->timeStep = value;
}
}
};
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
//#include "ContactPoint.cpp"
#include "ManifoldPoint.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
public ref class Manifold
{
internal:
b2Manifold *fold;
Manifold(b2Manifold *foldRef) : fold(foldRef) { }
public:
property Vector^ Normal
{
Vector^ get()
{
return gcnew Vector(fold->normal);
}
}
property IList<ManifoldPoint^ >^ Points
{
IList<ManifoldPoint^ >^ get()
{
//TODO: implement
List<ManifoldPoint^>^ list = gcnew List<ManifoldPoint^>;
for(int x = 0; x < fold->pointCount; ++x)
list->Add(gcnew ManifoldPoint(&fold->points[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,100 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
//TODO: is this class really necessary for the public interface?
public ref class ManifoldPoint
{
internal:
b2ManifoldPoint *point;
ManifoldPoint(b2ManifoldPoint *pointRef) : point(pointRef) { }
public:
property Vector^ LocalPoint1
{
Vector^ get()
{
return gcnew Vector(point->localPoint1);
}
void set(Vector^ value)
{
point->localPoint1 = value->getVec2();
}
}
property Vector^ LocalPoint2
{
Vector^ get()
{
return gcnew Vector(point->localPoint2);
}
void set(Vector^ value)
{
point->localPoint2 = value->getVec2();
}
}
property float32 Separation
{
float32 get()
{
return point->separation;
}
void set(float32 value)
{
point->separation = value;
}
}
property float32 NormalForce
{
float32 get()
{
return point->normalForce;
}
void set(float32 value)
{
point->normalForce = value;
}
}
property float32 TangentForce
{
float32 get()
{
return point->tangentForce;
}
void set(float32 value)
{
point->tangentForce = value;
}
}
//TODO: marshall b2ContactID
/*
property b2ContactID ID
{
b2ContactID get()
{
return point->id;
}
void set(b2ContactID value)
{
point->id = value;
}
}
*/
};
}
}

View File

@@ -0,0 +1,64 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class MassData
{
internal:
bool DeleteWhenDone;
b2MassData *data;
MassData(b2MassData *dataRef) : data(dataRef), DeleteWhenDone(false) { }
public:
MassData() : data(new b2MassData()), DeleteWhenDone(true) { }
virtual ~MassData()
{
if(DeleteWhenDone)
delete data;
}
property float32 Mass
{
float32 get()
{
return data->mass;
}
void set(float32 value)
{
data->mass = value;
}
}
property float32 I
{
float32 get()
{
return data->I;
}
void set(float32 value)
{
data->I = value;
}
}
property Vector^ Center
{
Vector^ get()
{
return gcnew Vector(data->center);
}
void set(Vector^ value)
{
data->center = value->getVec2();
}
}
};
}
}

View File

@@ -0,0 +1,94 @@
#pragma once
#include "Stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class Matrix
{
internal:
Matrix(const b2Mat22 &matrix) : col1(gcnew Vector(matrix.col1)), col2(gcnew Vector(matrix.col2)) { }
b2Mat22 getMat22()
{
return b2Mat22(col1->getVec2(), col2->getVec2());
}
public:
Vector ^col1, ^col2;
Matrix() : col1(gcnew Vector()), col2(gcnew Vector()) {}
Matrix(Vector^ c1, Vector^ c2) : col1(gcnew Vector(c1)), col2(gcnew Vector(c2)) { }
explicit Matrix(float32 angle)
{
Set(angle);
}
void Set(Vector^ c1, Vector^ c2)
{
col1->X = c1->X;
col1->Y = c1->Y;
col2->X = c2->X;
col2->Y = c2->Y;
}
void Set(float32 angle)
{
float32 c = cosf(angle), s = sinf(angle);
col1->X = c; col2->X = -s;
col1->Y = s; col2->Y = c;
}
void SetIdentity()
{
col1->X = 1; col2->X = 0;
col1->Y = 0; col2->Y = 1;
}
static Vector^ operator * (Matrix^ mat, Vector^ a)
{
return gcnew Vector(b2Mul(mat->getMat22(), a->getVec2()));
}
};
}
}
/*
struct b2Mat22
{
void SetZero()
{
col1.x = 0.0f; col2.x = 0.0f;
col1.y = 0.0f; col2.y = 0.0f;
}
b2Mat22 Invert() const
{
float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y;
b2Mat22 B;
float32 det = a * d - b * c;
b2Assert(det != 0.0f);
det = 1.0f / det;
B.col1.x = det * d; B.col2.x = -det * b;
B.col1.y = -det * c; B.col2.y = det * a;
return B;
}
// Solve A * x = b
b2Vec2 Solve(const b2Vec2& b) const
{
float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y;
float32 det = a11 * a22 - a12 * a21;
b2Assert(det != 0.0f);
det = 1.0f / det;
b2Vec2 x;
x.x = det * (a22 * b.x - a12 * b.y);
x.y = det * (a11 * b.y - a21 * b.x);
return x;
}
b2Vec2 col1, col2;
};
*/

View File

@@ -0,0 +1,190 @@
#pragma once
#include "stdafx.h"
#include "Joint.cpp"
#include "JointDef.cpp"
namespace Box2D
{
namespace Net
{
public ref class RevoluteJointDef : public JointDef
{
public:
RevoluteJointDef() : JointDef(new b2RevoluteJointDef()) { }
property Vector^ LocalAnchor1
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor1);
}
void set(Vector^ value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor1 = value->getVec2();
}
}
property Vector^ LocalAnchor2
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor2);
}
void set(Vector^ value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor2 = value->getVec2();
}
}
property float32 LowerAngle
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->lowerAngle;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->lowerAngle = value;
}
}
property float32 UpperAngle
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->upperAngle;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->upperAngle = value;
}
}
property float32 MotorTorque
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->maxMotorTorque;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->maxMotorTorque = value;
}
}
property float32 MotorSpeed
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->motorSpeed;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->motorSpeed = value;
}
}
property bool EnableLimit
{
bool get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->enableLimit;
}
void set(bool value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->enableLimit = value;
}
}
property bool EnableMotor
{
bool get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->enableMotor;
}
void set(bool value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->enableMotor = value;
}
}
void Initialize(Body^ body1, Body^ body2, Vector^ Anchor)
{
reinterpret_cast<b2RevoluteJointDef*>(def)->Initialize(body1->body, body2->body, Anchor->getVec2());
}
};
public ref class RevoluteJoint : public Joint
{
internal:
RevoluteJoint(b2RevoluteJoint *jointRef) : Joint(jointRef) { }
public:
property Vector^ Anchor1
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetAnchor1());
}
}
property Vector^ Anchor2
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetAnchor2());
}
}
Vector^ GetReactionForce()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetReactionForce());
}
float32 GetReactionTorque()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetReactionTorque());
}
property float32 JointAngle
{
float32 get()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetJointAngle());
}
}
property float32 JointSpeed
{
float32 get()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetJointSpeed());
}
}
float32 GetMotorTorque()
{
return reinterpret_cast<b2RevoluteJoint*>(joint)->GetMotorTorque();
}
void SetMotorSpeed(float32 speed)
{
reinterpret_cast<b2RevoluteJoint*>(joint)->SetMotorSpeed(speed);
}
void SetMotorTorque(float32 torque)
{
reinterpret_cast<b2RevoluteJoint*>(joint)->SetMaxMotorTorque(torque);
}
};
}
}

View File

@@ -0,0 +1,153 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "Matrix.cpp"
#include "ShapeType.cpp"
#include "XForm.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
ref class Body;
public ref class Shape
{
internal:
b2Shape *shape;
Shape(b2Shape *shapeRef) : shape(shapeRef) { }
public:
bool TestPoint(XForm^ xf, Vector^ p)
{
return shape->TestPoint(xf->getXForm(), p->getVec2());
}
property ShapeType ShapeType
{
Box2D::Net::ShapeType get()
{
return (Box2D::Net::ShapeType)shape->GetType();
}
}
/// <summary>
/// Get the parent body of this shape.
/// </summary>
property Body^ Body
{
Box2D::Net::Body^ get();
}
/*
/// <summary>
/// Get the world position.
/// </summary>
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(shape->Get->GetPosition());
}
}
*/
/*
property Matrix^ Rotation
{
Matrix^ get()
{
return gcnew Matrix(shape->GetRotationMatrix());
}
}
*/
//TODO:
//void* GetUserData();
//
// Remove and then add proxy from the broad-phase.
// This is used to refresh the collision filters.
//virtual void ResetProxy(b2BroadPhase* broadPhase) = 0;
/// <summary>
/// Get the next shape in the parent body's shape list.
/// </summary>
Shape^ GetNext()
{
return gcnew Shape(shape->GetNext());
}
};
public ref class CircleShape : public Shape
{
internal:
b2CircleShape *circleShape;
CircleShape(b2CircleShape *shapeRef) : Shape(shapeRef), circleShape(shapeRef) { }
public:
CircleShape(Shape^ shape) : Shape(shape->shape), circleShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_circleShape &&
reinterpret_cast<b2CircleShape *>(shape->shape))
{
circleShape = reinterpret_cast<b2CircleShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a CircleShape,"
"but the Shape is not a circle shape.");
}
}
//TODO: this is not technically part of the "public" interface for CircleShape
property float32 Radius
{
float32 get()
{
return circleShape->m_radius;
}
void set(float32 value)
{
circleShape->m_radius = value;
}
}
};
public ref class PolyShape : public Shape
{
internal:
b2PolygonShape *polyShape;
PolyShape(b2PolygonShape *shapeRef) : Shape(shapeRef), polyShape(shapeRef) { }
public:
PolyShape(Shape^ shape) : Shape(shape->shape), polyShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_polygonShape &&
reinterpret_cast<b2PolygonShape *>(shape->shape))
{
polyShape = reinterpret_cast<b2PolygonShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a PolyShape,"
"but the Shape is not a poly shape.");
}
}
property IList<Vector^>^ Vertices
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < polyShape->m_vertexCount; ++x)
list->Add(gcnew Vector(polyShape->m_vertices[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,125 @@
#pragma once
#include "stdafx.h"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
ref class Body;
enum class ShapeType;
ref class Vector;
ref class Matrix;
public ref class Shape
{
internal:
b2Shape *shape;
Shape(b2Shape *shapeRef) : shape(shapeRef) { }
public:
bool TestPoint(Vector^ p);
property ShapeType ShapeType
{
ShapeType get();
}
/// <summary>
/// Get the parent body of this shape.
/// </summary>
property Body^ Body;
/// <summary>
/// Get the world position.
/// </summary>
property Vector^ Position;
property Matrix^ Rotation;
//TODO:
//void* GetUserData();
//
// Remove and then add proxy from the broad-phase.
// This is used to refresh the collision filters.
//virtual void ResetProxy(b2BroadPhase* broadPhase) = 0;
/// <summary>
/// Get the next shape in the parent body's shape list.
/// </summary>
Shape^ GetNext();
};
public ref class CircleShape : public Shape
{
internal:
b2CircleShape *circleShape;
CircleShape(b2CircleShape *shapeRef) : Shape(shapeRef), circleShape(shapeRef) { }
public:
CircleShape(Shape^ shape) : Shape(shape->shape), circleShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_circleShape &&
reinterpret_cast<b2CircleShape *>(shape->shape))
{
circleShape = reinterpret_cast<b2CircleShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a CircleShape,"
"but the Shape is not a circle shape.");
}
}
//TODO: this is not technically part of the "public" interface for CircleShape
property float32 Radius
{
float32 get()
{
return circleShape->m_radius;
}
void set(float32 value)
{
circleShape->m_radius = value;
}
}
};
public ref class PolyShape : public Shape
{
internal:
b2PolyShape *polyShape;
PolyShape(b2PolyShape *shapeRef) : Shape(shapeRef), polyShape(shapeRef) { }
public:
PolyShape(Shape^ shape) : Shape(shape->shape), polyShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_polyShape &&
reinterpret_cast<b2PolyShape *>(shape->shape))
{
polyShape = reinterpret_cast<b2PolyShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a PolyShape,"
"but the Shape is not a poly shape.");
}
}
property IList<Vector^>^ Vertices
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < polyShape->m_vertexCount; ++x)
list->Add(gcnew Vector(polyShape->m_vertices[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,202 @@
#pragma once
#include "stdafx.h"
#include "MassData.cpp"
#include "ShapeType.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
public ref class ShapeDef
{
internal:
bool DeleteOnDtor;
b2ShapeDef *def;
ShapeDef(b2ShapeDef *defRef) : def(defRef), DeleteOnDtor(false) { }
//Needs to work for derivative types, too
b2ShapeDef GetShapeDef()
{
return *def;
}
public:
virtual ~ShapeDef()
{
if(DeleteOnDtor)
delete def;
}
property ShapeType ShapeType
{
Box2D::Net::ShapeType get()
{
return (Box2D::Net::ShapeType) def->type;
}
void set(Box2D::Net::ShapeType value)
{
def->type = b2ShapeType(value);
}
}
property float32 Friction
{
float32 get()
{
return def->friction;
}
void set(float32 value)
{
def->friction = value;
}
}
property float32 Restitution
{
float32 get()
{
return def->restitution;
}
void set(float32 value)
{
def->restitution = value;
}
}
property float32 Density
{
float32 get()
{
return def->density;
}
void set(float32 value)
{
def->density = value;
}
}
/// <summary>
/// The collision category bits. Normally you would just set one bit.
/// </summary>
property unsigned __int16 CategoryBits
{
unsigned __int16 get()
{
return def->categoryBits;
}
void set(unsigned __int16 value)
{
def->categoryBits = value;
}
}
/// <summary>
/// The collision mask bits. This states the categories that this
/// shape would accept for collision.
/// </summary>
property unsigned __int16 MaskBits
{
unsigned __int16 get()
{
return def->maskBits;
}
void set(unsigned __int16 value)
{
def->maskBits = value;
}
}
/// <summary>
/// Collision groups allow a certain group of objects to never collide (negative)
/// or always collide (positive). Zero means no collision group. Non-zero group
/// filtering always wins against the mask bits.
/// </summary>
property unsigned __int16 GroupIndex
{
unsigned __int16 get()
{
return def->groupIndex;
}
void set(unsigned __int16 value)
{
def->groupIndex = value;
}
}
//TODO:
//void* userData;
};
public ref class CircleDef : public ShapeDef
{
public:
CircleDef() : ShapeDef(new b2CircleDef())
{
ShapeDef::DeleteOnDtor = (true);
}
property float32 Radius
{
float32 get()
{
return reinterpret_cast<b2CircleDef*>(def)->radius;
}
void set(float32 value)
{
reinterpret_cast<b2CircleDef*>(def)->radius = value;
}
}
};
public ref class PolygonDef : public ShapeDef
{
public:
PolygonDef() : ShapeDef(new b2PolygonDef())
{
DeleteOnDtor = (true);
}
void SetAsBox(float X, float Y)
{
reinterpret_cast<b2PolygonDef*>(def)->SetAsBox(X, Y);
}
void SetAsBox(float X, float Y, Vector^ Center, float Angle)
{
reinterpret_cast<b2PolygonDef*>(def)->SetAsBox(X, Y, Center->getVec2(), Angle);
}
property IList<Vector^>^ Verticies
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < reinterpret_cast<b2PolygonDef*>(def)->vertexCount; ++x)
{
list->Add(gcnew Vector(reinterpret_cast<b2PolygonDef*>(def)->vertices[x]));
}
return list;
}
void set(IList<Vector^>^ value)
{
b2PolygonDef* Def = reinterpret_cast<b2PolygonDef*>(def);
for(int x = 0; x < value->Count; ++x)
Def->vertices[x] = value[x]->getVec2();
}
}
};
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "stdafx.h"
namespace Box2D
{
namespace Net
{
//TODO: is there a way to auto incorporate shape types?
public enum class ShapeType
{
e_unknownShape = ::e_unknownShape,
e_circleShape = ::e_circleShape,
e_polygonShape = ::e_polygonShape,
e_shapeTypeCount = ::e_shapeTypeCount
};
}
}

View File

@@ -0,0 +1,8 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#include "Box2D.h"

View File

@@ -0,0 +1,16 @@
#pragma once
#include "stdafx.h"
#include "Shape.cpp"
#include "Body.cpp"
namespace Box2D
{
namespace Net
{
Body^ Shape::Body::get()
{
return gcnew Box2D::Net::Body(shape->GetBody());
}
}
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "Stdafx.h"
namespace Box2D
{
namespace Net
{
public ref class Vector
{
internal:
b2Vec2 getVec2()
{
return b2Vec2(X, Y);
}
public:
//TODO: this needs to be read only outside the class,
//because if you have a vector as a get property, and
//try to set the X,Y components, it won't take to the
//original vector:
//
//ie: Shape.Extents.X += 10;
//won't behave like you think it should (or will it?)
float32 X, Y;
Vector() : X(0), Y(0) { }
Vector(float32 x, float32 y) : X(x), Y(y) { }
Vector(Vector^ other) : X(other->X), Y(other->Y) { }
Vector(const b2Vec2 &other) : X(other.x), Y(other.y) { }
/*
Vector^ Set(float32 x, float32 y)
{
X = x;
Y = y;
return this;
}
*/
///Defines basic vector addition
static Vector^ operator +(Vector^ a, Vector^ b)
{
return gcnew Vector(a->X + b->X, a->Y + b->Y);
}
///<summary>Negates a vector (that is, returns (-X, -Y)</summary>
static Vector^ operator - (Vector^ a)
{
return gcnew Vector(-a->X, -a->Y);
}
///<summary>Defines basic vector subtraction</summary>
static Vector^ operator - (Vector^ a, Vector^ b)
{
return gcnew Vector(a->X - b->X, a->Y - b->Y);
}
///<summary>Scalar multiplication for a vector</summary>
static Vector^ operator * (Vector^ a, float32 b)
{
return gcnew Vector(a->X * b, a->Y * b);
}
/*
static Vector^ operator = (Vector^ a, Vector^ b)
{
a.X = b.X;
a.Y = b.Y;
}
*/
///<summary>Returns a string representation of this vector</summary>
virtual System::String^ ToString() override
{
return gcnew System::String("<" + X + ", " + Y + ">");
}
};
}
}

View File

@@ -0,0 +1,162 @@
#pragma once
#include "Stdafx.h"
#include "AABB.cpp"
#include "Body.cpp"
#include "BodyDef.cpp"
#include "Joint.cpp"
#include "JointDef.cpp"
#include "Contact.cpp"
namespace Box2D
{
namespace Net
{
public ref class World
{
b2World *world;
public:
World(AABB^ worldAABB, Vector^ gravity, bool doSleep) : world(new b2World(
worldAABB->getAABB(), gravity->getVec2(), doSleep)) { }
~World()
{
delete world;
}
/// <summary> Create rigid body from a definition </summary>
Body^ CreateBody(BodyDef^ def)
{
return gcnew Body(world->CreateBody(def->def));
}
///<summary>
/// Destroy rigid bodies. Destruction is deferred until the the next call to Step.
/// This is done so that bodies may be destroyed while you iterate through the contact list.
///</summary>
void DestroyBody(Body^ body)
{
world->DestroyBody(body->body);
}
/// <summary>
/// The world provides a single ground body with no collision shapes. You
/// can use this to simplify the creation of joints.
/// </summary>
Body^ GetGroundBody()
{
return gcnew Body(world->GetGroundBody());
}
void Step(float32 timeStep, int32 iterations)
{
world->Step(timeStep, iterations);
}
Joint^ CreateJoint(JointDef^ def)
{
return gcnew Joint(world->CreateJoint(def->def));
}
void DestroyJoint(Joint^ joint)
{
world->DestroyJoint(joint->joint);
}
property IList<Body^>^ Bodies
{
IList<Body^>^ get()
{
List<Body^>^ list = gcnew List<Body^>();
for(b2Body *body = world->GetBodyList(); body; body = body->GetNext())
list->Add(gcnew Body(body));
return list;
}
}
property IList<Joint^>^ Joints
{
IList<Joint^>^ get()
{
List<Joint^>^ list = gcnew List<Joint^>();
for(b2Joint *joint = world->GetJointList(); joint; joint = joint->GetNext())
list->Add(gcnew Joint(joint));
return list;
}
}
Joint^ GetJointList()
{
return gcnew Joint(world->GetJointList());
}
///<summary> You can use these to iterate over all the bodies, joints, and contacts. </summary>
/*
Contact^ GetContactList()
{
return gcnew Contact(world->C>GetContactList());
}
*/
/// <summary>
/// Query the world for all shapes that potentially overlap the
/// provided AABB. You provide a shape pointer buffer of specified
/// size. The number of shapes found is returned.
/// </summary>
IList<Shape^>^ Query(AABB^ aabb)
{
const int32 k_maxCount = 25;
b2Shape* shapes[k_maxCount];
int32 count = world->Query(aabb->getAABB(), shapes, k_maxCount);
List<Shape^>^ list = gcnew List<Shape^>();
for(int x = 0; x < count; ++x)
list->Add(gcnew Shape(shapes[x]));
return list;
}
static property bool PositionCorrection
{
bool get()
{
return b2World::s_enablePositionCorrection == 1;
}
void set(bool value)
{
b2World::s_enablePositionCorrection = value ? 1 : 0;
}
}
static property bool WarmStarting
{
bool get()
{
return b2World::s_enableWarmStarting == 1;
}
void set(bool value)
{
b2World::s_enableWarmStarting = value ? 1 : 0;
}
}
};
}
}
/*
class b2World
{
public:
// Register a world listener to receive important events that can
// help prevent your code from crashing.
void SetListener(b2WorldListener* listener);
// Register a collision filter to provide specific control over collision.
// Otherwise the default filter is used (b2CollisionFilter).
void SetFilter(b2CollisionFilter* filter);
*/

View File

@@ -0,0 +1,47 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "Matrix.cpp"
namespace Box2D
{
namespace Net
{
public ref class XForm
{
internal:
b2XForm *xform;
bool DeleteOnDtor;
XForm(b2XForm *XForm) : xform(XForm), DeleteOnDtor(false) { }
XForm(b2XForm XForm) : xform(new b2XForm(XForm)), DeleteOnDtor(false) { }
b2XForm getXForm()
{
return *xform;
}
public:
XForm() : xform(new b2XForm()), DeleteOnDtor(true) { }
~XForm()
{
if(DeleteOnDtor)
delete xform;
}
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(xform->position);
}
}
property Matrix^ Rotation
{
Matrix^ get()
{
return gcnew Matrix(xform->R);
}
}
};
}
}