WIP (Threaded Rendering, CP-Lock, MultiDisplay)
parent
634da6fe0b
commit
dd4dc701f9
|
@ -18,85 +18,77 @@ using org.budnhead.core;
|
||||||
|
|
||||||
namespace bnhdemo
|
namespace bnhdemo
|
||||||
{
|
{
|
||||||
public class BootStrap
|
public static class BootStrap
|
||||||
{
|
{
|
||||||
public static BootStrap _instance;
|
static SquaredMap map;
|
||||||
public static BootStrap instance()
|
|
||||||
{
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGLWindow glWindow;
|
static Actor trackedActor;
|
||||||
|
static GLCamera trackingCamera;
|
||||||
SquaredMap map;
|
|
||||||
|
|
||||||
public static void Main(string[] args){
|
public static void Main(string[] args){
|
||||||
_instance = new BootStrap();
|
Engine.InitializeGraphics();
|
||||||
|
|
||||||
_instance.run();
|
Engine.SceneWindows[0].Scene = new Scene();
|
||||||
|
|
||||||
|
loadMap();
|
||||||
|
|
||||||
|
Engine.SceneWindows[0].Visible = true;
|
||||||
|
|
||||||
|
Engine.SceneWindows[0].KeyPress += (sender, e) => {
|
||||||
|
switch (e.KeyChar){
|
||||||
|
case 'r':
|
||||||
|
SceneWindow sw = Engine.createSceneWindow();
|
||||||
|
sw.Visible = true;
|
||||||
|
sw.Scene = new Scene(Engine.SceneWindows[0].Scene);
|
||||||
|
GLCamera cam = new GLCamera();
|
||||||
|
|
||||||
|
cam.Position = new Vector3(800,800,384);
|
||||||
|
cam.View = new Vector3(-1,-1,-1);
|
||||||
|
cam.Top = Vector3.UnitZ;
|
||||||
|
|
||||||
|
CameraRotator cr = new CameraRotator(cam);
|
||||||
|
|
||||||
|
sw.PrimaryViewport.SceneOrientation = cam;
|
||||||
|
|
||||||
|
trackingCamera = cam;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
Console.WriteLine("Fire Ballistic...");
|
||||||
|
BallisticActor ba = new BallisticActor(0);
|
||||||
|
ba.Position.Value = map.ground(new Vector2(10,10));
|
||||||
|
ba.Velocity.Value = new Vector3(1,1,1).Normalized();
|
||||||
|
ba.Velocity.Value *= 100.0f;
|
||||||
|
ba.fire();
|
||||||
|
|
||||||
|
trackedActor = ba;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Engine.AfterUpdate += delegate {
|
||||||
|
if ((trackedActor != null)&&(trackingCamera != null)){
|
||||||
|
if (trackedActor.IsActive){
|
||||||
|
trackingCamera.lookAt(trackedActor.Position.Value);
|
||||||
|
} else {
|
||||||
|
trackedActor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Engine.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BootStrap()
|
public static void loadMap(){
|
||||||
{
|
|
||||||
bootGraphics();
|
|
||||||
bootAudio();
|
|
||||||
bootMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SquaredMap SquaredMap {
|
|
||||||
get { return this.map; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void bootGraphics(){
|
|
||||||
glWindow = new OpenGLWindow();
|
|
||||||
glWindow.MakeCurrent();
|
|
||||||
|
|
||||||
GlobalDefaults.instance();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void bootAudio(){
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AudioDelegate.init();
|
|
||||||
AudioDelegate.DistanceModel("exponential", true);
|
|
||||||
nhBuffers.addSearchPath("./sounds");
|
|
||||||
nhBuffers.loadSound("HowFire", "HowHit", "st1");
|
|
||||||
//AudioDelegate.test();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void bootMap(){
|
|
||||||
ImageSharp.Image i = ImageSharp.Image.Load( new FileStream("M3-wip.png",FileMode.Open));
|
ImageSharp.Image i = ImageSharp.Image.Load( new FileStream("M3-wip.png",FileMode.Open));
|
||||||
i.Flip(ImageSharp.Processing.FlipType.Vertical);
|
i.Flip(ImageSharp.Processing.FlipType.Vertical);
|
||||||
i.Resize(500,500);
|
|
||||||
|
|
||||||
map = new SquaredMap(i);
|
map = new SquaredMap(i);
|
||||||
|
|
||||||
glWindow.Scene.RootObject.addChild( map );
|
Engine.SceneWindows[0].Scene.RootObject.addChild(map);
|
||||||
|
|
||||||
ModelManager.instance.addSearchPath("./models");
|
|
||||||
|
|
||||||
DumpObject dobj = new DumpObject();
|
|
||||||
dobj.Model3D = ModelManager.instance.loadModel("alfa147",0.0254f);
|
|
||||||
Vector3 v3 = map.ground(new Vector2(24,24));
|
|
||||||
dobj.Position = v3;
|
|
||||||
|
|
||||||
glWindow.Scene.RootObject.addChild( dobj );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void run(){
|
|
||||||
glWindow.MakeCurrent();
|
|
||||||
glWindow.Run(25,25);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
using OpenTK.Graphics.OpenGL;
|
|
||||||
using OpenTK;
|
|
||||||
|
|
||||||
namespace bnhdemo
|
|
||||||
{
|
|
||||||
public class Graphics
|
|
||||||
{
|
|
||||||
private TextureManager textureManager;
|
|
||||||
|
|
||||||
public Graphics()
|
|
||||||
{
|
|
||||||
this.textureManager = new TextureManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TextureManager TextureManager {
|
|
||||||
get { return this.textureManager; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -60,9 +60,8 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="BootStrap.cs" />
|
<Compile Include="BootStrap.cs" />
|
||||||
<Compile Include="Graphics.cs" />
|
|
||||||
<Compile Include="OpenGLWindow.cs" />
|
|
||||||
<Compile Include="TextureManager.cs" />
|
<Compile Include="TextureManager.cs" />
|
||||||
|
<Compile Include="demo\CameraRotator.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="OpenTK.dll.config">
|
<None Include="OpenTK.dll.config">
|
||||||
|
@ -114,6 +113,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="sounds\" />
|
<Folder Include="sounds\" />
|
||||||
|
<Folder Include="demo\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using org.budnhead.core;
|
||||||
|
using org.budnhead.graphics;
|
||||||
|
|
||||||
|
namespace bnhdemo
|
||||||
|
{
|
||||||
|
public class CameraRotator : Actor
|
||||||
|
{
|
||||||
|
GLCamera camera;
|
||||||
|
Matrix3 m3 = Matrix3.CreateRotationZ(MathHelper.PiOver2 / 45.0f);
|
||||||
|
|
||||||
|
Vector3 p = new Vector3(400,400,256);
|
||||||
|
Vector3 offset = new Vector3(150,0,0);
|
||||||
|
Vector3 view = new Vector3(-1,0,-1);
|
||||||
|
|
||||||
|
public CameraRotator(GLCamera camera)
|
||||||
|
:base(0)
|
||||||
|
{
|
||||||
|
this.camera = camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update(float timespan)
|
||||||
|
{
|
||||||
|
offset = m3 * offset;
|
||||||
|
view = m3 * view;
|
||||||
|
|
||||||
|
camera.Position = p + offset;
|
||||||
|
camera.View = view.Normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,25 +10,20 @@ namespace org.budnhead.core
|
||||||
{
|
{
|
||||||
public class Actor : WorldObject
|
public class Actor : WorldObject
|
||||||
{
|
{
|
||||||
public static List<Actor> activeActors = new List<Actor>();
|
internal static List<Actor> activeActors = new List<Actor>();
|
||||||
public static List<Actor> finishedActors = new List<Actor>();
|
private static List<Actor> finishedActors = new List<Actor>();
|
||||||
|
|
||||||
|
internal static void updateActors(float elapsed){
|
||||||
public static void updateAll(float timespan)
|
// Update all active Actors...
|
||||||
{
|
foreach (Actor a in activeActors.ToArray()){
|
||||||
foreach (Actor a in activeActors)
|
a.update(elapsed);
|
||||||
{
|
|
||||||
a.update(timespan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Actor a in finishedActors)
|
// Remove finished Actors
|
||||||
{
|
foreach (Actor a in finishedActors.ToArray()){
|
||||||
activeActors.Remove(a);
|
activeActors.Remove(a);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
finishedActors.Clear();
|
finishedActors.Clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
|
@ -39,26 +34,30 @@ namespace org.budnhead.core
|
||||||
this.id = id;
|
this.id = id;
|
||||||
activeActors.Add(this);
|
activeActors.Add(this);
|
||||||
|
|
||||||
_player = new nhPlayer();
|
//_player = new nhPlayer();
|
||||||
activePlayers.Add(_player);
|
//activePlayers.Add(_player);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy(){
|
public void destroy(){
|
||||||
finishedActors.Add(this);
|
finishedActors.Add(this);
|
||||||
_player.deletePlayer();
|
//_player.deletePlayer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Heading { get; set; }
|
public readonly BufferedValueInstance<Vector3> Heading = new BufferedValueInstance<Vector3>(new Vector3(0,0,1));
|
||||||
public Vector3 Velocity { get; set; }
|
public readonly BufferedValueInstance<Vector3> Velocity = new BufferedValueInstance<Vector3>(new Vector3());
|
||||||
public float Weight { get; set; }
|
public readonly BufferedValueInstance<float> Weight = new BufferedValueInstance<float>(0);
|
||||||
|
|
||||||
|
public bool IsActive {
|
||||||
|
get { return activeActors.Contains(this); }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void update(float timespan){
|
public virtual void update(float timespan){
|
||||||
if (soundPlaying()){
|
/* if (soundPlaying()){
|
||||||
syncSoundPosition();
|
syncSoundPosition();
|
||||||
}
|
}
|
||||||
}
|
*/ }
|
||||||
|
|
||||||
public void setHeading(Vector3 heading,Vector3 top){
|
public void setHeading(Vector3 heading,Vector3 top){
|
||||||
Vector3 x,y,z;
|
Vector3 x,y,z;
|
||||||
|
@ -74,7 +73,7 @@ namespace org.budnhead.core
|
||||||
new Vector4(0,0,0,1)
|
new Vector4(0,0,0,1)
|
||||||
);
|
);
|
||||||
|
|
||||||
Rotation = Matrix4.CreateRotationX(MathHelper.PiOver2) * mRotation;
|
Rotation.Value = Matrix4.CreateRotationX(MathHelper.PiOver2) * mRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Model3D Model3D { get; set; }
|
public Model3D Model3D { get; set; }
|
||||||
|
@ -99,35 +98,34 @@ namespace org.budnhead.core
|
||||||
|
|
||||||
public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f)
|
public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f)
|
||||||
{
|
{
|
||||||
_player.setDistanceAttenuation(rollOf, refDistance, maxDistance);
|
// _player.setDistanceAttenuation(rollOf, refDistance, maxDistance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBuffers(params string[] buffers)
|
public void setBuffers(params string[] buffers)
|
||||||
{
|
{
|
||||||
foreach (string i in buffers)
|
/* foreach (string i in buffers)
|
||||||
{
|
{
|
||||||
if(!aBuffers.ContainsKey(i))
|
if(!aBuffers.ContainsKey(i))
|
||||||
aBuffers.Add(i, nhBuffers.buffers[i]);
|
aBuffers.Add(i, nhBuffers.buffers[i]);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playSound(string sound, float gain = 1.0f, bool loop = false)
|
public void playSound(string sound, float gain = 1.0f, bool loop = false)
|
||||||
{
|
{
|
||||||
|
// _player.position = this.Position.Value;
|
||||||
_player.position = this.Position;
|
// _player.velocity = this.Velocity.Value;
|
||||||
_player.velocity = this.Velocity;
|
// _player.play(aBuffers[sound], gain, loop);
|
||||||
_player.play(aBuffers[sound], gain, loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncSoundPosition()
|
private void syncSoundPosition()
|
||||||
{
|
{
|
||||||
_player.setPosition(this.Position);
|
// _player.setPosition(this.Position.Value);
|
||||||
_player.setVelocity(this.Velocity);
|
// _player.setVelocity(this.Velocity.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean soundPlaying(){
|
public Boolean soundPlaying(){
|
||||||
return _player.state();
|
return false; //_player.state();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using org.budnhead.graphics.primitives;
|
using org.budnhead.graphics.primitives;
|
||||||
using org.budnhead.graphics;
|
using org.budnhead.graphics;
|
||||||
using org.budnhead.exceptions;
|
using org.budnhead.exceptions;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ namespace org.budnhead.core
|
||||||
:base(id)
|
:base(id)
|
||||||
{
|
{
|
||||||
this.actorState = BallisticActorStates.FLYING;
|
this.actorState = BallisticActorStates.FLYING;
|
||||||
this.Model3D = ModelManager.instance.findModel("ballistisch");
|
this.Model3D = ResourceLibrary.getResource<LoadedModel>("ballistisch");
|
||||||
|
|
||||||
for (int n=0;n < this.Model3D.vertexes.Length;n++){
|
for (int n=0;n < this.Model3D.vertexes.Length;n++){
|
||||||
this.Model3D.colors[n] = new Vector4(1.0f,0.2f + (0.5f * this.Model3D.vertexes[n].Z / -4.0f),0,1.0f);
|
this.Model3D.colors[n] = new Vector4(1.0f,0.2f + (0.5f * this.Model3D.vertexes[n].Z / -4.0f),0,1.0f);
|
||||||
|
@ -35,16 +36,16 @@ namespace org.budnhead.core
|
||||||
|
|
||||||
switch (actorState){
|
switch (actorState){
|
||||||
case BallisticActorStates.FLYING:
|
case BallisticActorStates.FLYING:
|
||||||
Velocity += (Physics.Gravitation * timespan);
|
Velocity.Value += (Physics.Gravitation * timespan);
|
||||||
Position += Velocity * timespan;
|
Position.Value += Velocity.Value * timespan;
|
||||||
|
|
||||||
setHeading( Velocity, Physics.Gravitation);
|
setHeading( Velocity.Value, Physics.Gravitation);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Vector3 ground = SquaredMap.activeMap.ground(Position.Xy);
|
Vector3 ground = SquaredMap.activeMap.ground(Position.Value.Xy);
|
||||||
|
|
||||||
if (Position.Z <= ground.Z){
|
if (Position.Value.Z <= ground.Z){
|
||||||
Console.WriteLine("BallisticActor hit ground!");
|
Console.WriteLine("BallisticActor hit ground!");
|
||||||
actorState = BallisticActorStates.HIT;
|
actorState = BallisticActorStates.HIT;
|
||||||
playSound("HowHit");
|
playSound("HowHit");
|
||||||
|
@ -71,7 +72,7 @@ namespace org.budnhead.core
|
||||||
|
|
||||||
public void fire()
|
public void fire()
|
||||||
{
|
{
|
||||||
playSound("HowFire");
|
//playSound("HowFire");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public interface IBufferedValue {
|
||||||
|
void buffer();
|
||||||
|
object getBufferedValue();
|
||||||
|
object getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BufferedValueInstance<T> : IDisposable,IBufferedValue
|
||||||
|
{
|
||||||
|
static List<IBufferedValue> bufferedValues = new List<IBufferedValue>();
|
||||||
|
static public void cycle(){
|
||||||
|
foreach (IBufferedValue bvi in bufferedValues){
|
||||||
|
bvi.buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T value,bufferedValue;
|
||||||
|
|
||||||
|
public BufferedValueInstance(){
|
||||||
|
bufferedValues.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedValueInstance(T initialValue){
|
||||||
|
Value = initialValue;
|
||||||
|
bufferedValues.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Value {
|
||||||
|
get { return this.value; }
|
||||||
|
set { this.value = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public T BufferedValue{
|
||||||
|
get { return this.bufferedValue; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose(){
|
||||||
|
bufferedValues.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buffer(){
|
||||||
|
this.bufferedValue = this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object getBufferedValue()
|
||||||
|
{
|
||||||
|
return this.bufferedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object getValue()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ConsumerProducerLock
|
||||||
|
*
|
||||||
|
* Lock a Resource for one producer, mutliple consumers (read-only)
|
||||||
|
*
|
||||||
|
* Producer Lock: Producer will receive and hold lock if no other producer is active
|
||||||
|
* Producer Exclusive Lock: Producer will receive and hold lock, while no consumers are active
|
||||||
|
* Consumer Lock: Consumers will get lock while no Producer Exclusive Lock is held
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
public class ConsumerProducerLock
|
||||||
|
{
|
||||||
|
Object producer;
|
||||||
|
Object producerExclusiveLock;
|
||||||
|
Object consumerLock;
|
||||||
|
|
||||||
|
Int32 consumers;
|
||||||
|
|
||||||
|
bool producerIsExclusive;
|
||||||
|
|
||||||
|
public ConsumerProducerLock(){
|
||||||
|
producer = new object();
|
||||||
|
producerExclusiveLock = new object();
|
||||||
|
consumerLock = new object();
|
||||||
|
|
||||||
|
consumers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConsumerEnter(){
|
||||||
|
Monitor.Enter(producerExclusiveLock);
|
||||||
|
Monitor.Enter(consumerLock);
|
||||||
|
consumers ++;
|
||||||
|
Monitor.Exit(consumerLock);
|
||||||
|
Monitor.Exit(producerExclusiveLock);
|
||||||
|
}
|
||||||
|
public void ConsumerExit(){
|
||||||
|
Monitor.Enter(producerExclusiveLock);
|
||||||
|
Monitor.Enter(consumerLock);
|
||||||
|
consumers --;
|
||||||
|
if (consumers == 0){
|
||||||
|
Monitor.Pulse(producerExclusiveLock);
|
||||||
|
}
|
||||||
|
Monitor.Exit(consumerLock);
|
||||||
|
Monitor.Exit(producerExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProducerEnter(){
|
||||||
|
Monitor.Enter(producer);
|
||||||
|
}
|
||||||
|
public void ProducerExit(){
|
||||||
|
Monitor.Exit(producer);
|
||||||
|
if (Monitor.IsEntered(producerExclusiveLock)){
|
||||||
|
Monitor.Exit(producerExclusiveLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void producerExclusive(){
|
||||||
|
Monitor.Enter(producerExclusiveLock);
|
||||||
|
if (consumers > 0){
|
||||||
|
Monitor.Wait(producerExclusiveLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using org.budnhead.graphics;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace org.budnhead.core
|
||||||
|
{
|
||||||
|
public delegate void UpdateDelegate(float elapsed);
|
||||||
|
|
||||||
|
public static class Engine
|
||||||
|
{
|
||||||
|
/** Objects of the Game World **/
|
||||||
|
|
||||||
|
|
||||||
|
/** Engine management stuff **/
|
||||||
|
private static Object engineLock = new object();
|
||||||
|
private static Boolean initialized = false;
|
||||||
|
|
||||||
|
private static readonly float tickTimeSpan = (1.0f / Stopwatch.Frequency);
|
||||||
|
private static readonly float tickTimeSpanMS = (1000.0f / Stopwatch.Frequency);
|
||||||
|
private static long lastWorldUpdateTick;
|
||||||
|
private static ConsumerProducerLock
|
||||||
|
consumerProducerLock = new ConsumerProducerLock();
|
||||||
|
internal static List<SceneWindow>
|
||||||
|
sceneWindows = new List<SceneWindow>();
|
||||||
|
private static JobThreader sceneWindowJobs;
|
||||||
|
|
||||||
|
private static Thread updateThread = new Thread(updateWorldThread);
|
||||||
|
|
||||||
|
public static event UpdateDelegate
|
||||||
|
BeforeUpdate,
|
||||||
|
AfterUpdate;
|
||||||
|
|
||||||
|
private static Boolean exiting;
|
||||||
|
private static Object syncGraphicsStartup = new object();
|
||||||
|
|
||||||
|
private static float targetUpdatePeriod = 100;
|
||||||
|
|
||||||
|
public static SceneWindow[] SceneWindows {
|
||||||
|
get { lock (sceneWindows) { return sceneWindows.ToArray(); } }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float TargetUpdatePeriod {
|
||||||
|
get { return targetUpdatePeriod; }
|
||||||
|
set { targetUpdatePeriod = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float TargetUpdateFrequency {
|
||||||
|
get { return targetUpdatePeriod == 0 ? 0 : 1.0f / targetUpdatePeriod; }
|
||||||
|
set { targetUpdatePeriod = value == 0 ? 0 : 1.0f / value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean ShouldContinue {
|
||||||
|
get { lock(engineLock) { return !Engine.exiting; } }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Shutdown(){
|
||||||
|
lock (engineLock){
|
||||||
|
exiting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Initialize(){
|
||||||
|
InitializeGraphics();
|
||||||
|
InitializeUpdateThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeUpdateThread(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeGraphics(){
|
||||||
|
GraphicsContext.ShareContexts = true;
|
||||||
|
|
||||||
|
sceneWindowJobs = new JobThreader();
|
||||||
|
|
||||||
|
SceneWindow primaryWindow = new SceneWindow();
|
||||||
|
primaryWindow.MakeCurrent();
|
||||||
|
|
||||||
|
initialized = GlobalDefaults.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void run(){
|
||||||
|
updateThread.Start();
|
||||||
|
|
||||||
|
sceneWindowsThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void updateWorld(float elapsed){
|
||||||
|
consumerProducerLock.ProducerEnter();
|
||||||
|
|
||||||
|
if (BeforeUpdate!=null){
|
||||||
|
BeforeUpdate(elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor.updateActors(elapsed);
|
||||||
|
|
||||||
|
if (AfterUpdate!=null){
|
||||||
|
AfterUpdate(elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
consumerProducerLock.producerExclusive();
|
||||||
|
|
||||||
|
cycleBufferedValues();
|
||||||
|
|
||||||
|
consumerProducerLock.ProducerExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool cycleBufferedValues(){
|
||||||
|
BufferedValueInstance<object>.cycle();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConsumerEnter(){
|
||||||
|
consumerProducerLock.ConsumerEnter();
|
||||||
|
}
|
||||||
|
public static void ConsumerExit(){
|
||||||
|
consumerProducerLock.ConsumerExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static SceneWindow createSceneWindow(){
|
||||||
|
return sceneWindowJobs.execute(delegate { return new SceneWindow(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sceneWindowsThread(){
|
||||||
|
|
||||||
|
while (Engine.ShouldContinue){
|
||||||
|
sceneWindowJobs.execute();
|
||||||
|
|
||||||
|
lock(Engine.sceneWindows){
|
||||||
|
foreach (SceneWindow sceneWindow in Engine.sceneWindows.ToArray()){
|
||||||
|
if (sceneWindow.Visible){
|
||||||
|
sceneWindow.ProcessEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (SceneWindow sceneWindow in Engine.sceneWindows.ToArray()){
|
||||||
|
sceneWindow.paint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateWorldThread(){
|
||||||
|
|
||||||
|
long lastWorldUpdateTick = Stopwatch.GetTimestamp();
|
||||||
|
float elapsed = 0;
|
||||||
|
float update_needs;
|
||||||
|
|
||||||
|
while (Engine.ShouldContinue){
|
||||||
|
long ticks = Stopwatch.GetTimestamp();
|
||||||
|
elapsed = tickTimeSpan * (ticks - lastWorldUpdateTick);
|
||||||
|
|
||||||
|
updateWorld(elapsed);
|
||||||
|
|
||||||
|
update_needs = tickTimeSpanMS * (Stopwatch.GetTimestamp() - ticks);
|
||||||
|
|
||||||
|
lastWorldUpdateTick = ticks;
|
||||||
|
|
||||||
|
if (update_needs < targetUpdatePeriod){
|
||||||
|
Thread.Sleep( (int)(targetUpdatePeriod - update_needs) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,8 +73,8 @@ namespace org.budnhead.core
|
||||||
.requires(intersectPlainCoeff(P,V,A,B,C,out coeff))
|
.requires(intersectPlainCoeff(P,V,A,B,C,out coeff))
|
||||||
.requires(coeff.Y >= 0)
|
.requires(coeff.Y >= 0)
|
||||||
.requires(coeff.Z >= 0)
|
.requires(coeff.Z >= 0)
|
||||||
.requires(coeff.Y <= 1)
|
.requires(coeff.Y <= 1.00001f)
|
||||||
.requires(coeff.Z <= 1)
|
.requires(coeff.Z <= 1.00001f)
|
||||||
.assigns(ref p, delegate { return P + (coeff.X * V); })
|
.assigns(ref p, delegate { return P + (coeff.X * V); })
|
||||||
.isSuccess();
|
.isSuccess();
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ namespace org.budnhead.core
|
||||||
.requires(intersectPlainCoeff(P,V,A,B,C,out coeff))
|
.requires(intersectPlainCoeff(P,V,A,B,C,out coeff))
|
||||||
.requires(coeff.Y >= 0)
|
.requires(coeff.Y >= 0)
|
||||||
.requires(coeff.Z >= 0)
|
.requires(coeff.Z >= 0)
|
||||||
.requires(coeff.Y <= 1)
|
.requires(coeff.Y <= 1.00001f)
|
||||||
.requires(coeff.Z <= 1)
|
.requires(coeff.Z <= 1.00001f)
|
||||||
.requires(coeff.Y + coeff.Z <= 1)
|
.requires(coeff.Y + coeff.Z <= 1.00001f)
|
||||||
.assigns(ref p, delegate { return A + (coeff.Y * (B-A)) + (coeff.Z * (C-A)); })
|
.assigns(ref p, delegate { return A + (coeff.Y * (B-A)) + (coeff.Z * (C-A)); })
|
||||||
.isSuccess();
|
.isSuccess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,55 +2,29 @@
|
||||||
|
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
namespace org.budnhead.graphics
|
using org.budnhead.graphics;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
|
namespace org.budnhead.core
|
||||||
{
|
{
|
||||||
public class GlobalDefaults
|
public static class GlobalDefaults
|
||||||
{
|
{
|
||||||
private static GlobalDefaults _instance = new GlobalDefaults();
|
internal static bool initialize(){
|
||||||
public static GlobalDefaults instance(){
|
ResourceLibrary.initializeResourceType(typeof(Shader), "shader/", "");
|
||||||
return _instance;
|
ResourceLibrary.initializeResourceType(typeof(ShaderProgram), "shader/", ".program");
|
||||||
}
|
ResourceLibrary.initializeResourceType(typeof(LoadedModel), "models/", ".obj");
|
||||||
|
|
||||||
private Shader defVertexShader,
|
ResourceLibrary.cacheInstance("default.vshader",new Shader(OpenTK.Graphics.OpenGL.ShaderType.VertexShader, defVertexShaderSource));
|
||||||
defFragmentShader;
|
ResourceLibrary.cacheInstance("default.fshader",new Shader(OpenTK.Graphics.OpenGL.ShaderType.FragmentShader, defFragmentShaderSource));
|
||||||
private ShaderProgram
|
|
||||||
defShaderProgram;
|
|
||||||
|
|
||||||
private GLSceneOrientation activeScene;
|
ResourceLibrary.cacheInstance("default",new ShaderProgram("default.vshader","default.fshader"));
|
||||||
|
|
||||||
private GlobalDefaults(){
|
return true;
|
||||||
|
|
||||||
Console.WriteLine("GlobalDefaults: Shader Version: {0}", GL.GetString(StringName.ShadingLanguageVersion));
|
|
||||||
|
|
||||||
defVertexShader = new Shader(OpenTK.Graphics.OpenGL.ShaderType.VertexShader, defVertexShaderSource);
|
|
||||||
defFragmentShader = new Shader(OpenTK.Graphics.OpenGL.ShaderType.FragmentShader, defFragmentShaderSource);
|
|
||||||
|
|
||||||
defShaderProgram = new ShaderProgram(defVertexShader, defFragmentShader);
|
|
||||||
|
|
||||||
activeScene = new GLSceneOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShaderProgram DefaultShaderProgram {
|
|
||||||
get { return this.defShaderProgram;}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Shader DefaultVertexShader
|
|
||||||
{
|
|
||||||
get { return defVertexShader; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Shader DefaultFragmentShader
|
|
||||||
{
|
|
||||||
get { return defFragmentShader; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public GLSceneOrientation ActiveScene {
|
|
||||||
get { return this.activeScene; }
|
|
||||||
set { this.activeScene = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private string defVertexShaderSource = @"#version 330
|
|
||||||
|
private static string defVertexShaderSource = @"#version 330
|
||||||
|
|
||||||
layout(location = 0) in vec3 iv_position;
|
layout(location = 0) in vec3 iv_position;
|
||||||
layout(location = 1) in vec4 iv_color;
|
layout(location = 1) in vec4 iv_color;
|
||||||
|
@ -94,7 +68,7 @@ void main()
|
||||||
|
|
||||||
";
|
";
|
||||||
|
|
||||||
private string defFragmentShaderSource = @"#version 330
|
private static string defFragmentShaderSource = @"#version 330
|
||||||
|
|
||||||
in vec4 color;
|
in vec4 color;
|
||||||
in vec3 norm;
|
in vec3 norm;
|
||||||
|
@ -119,7 +93,5 @@ void main()
|
||||||
|
|
||||||
";
|
";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,8 +13,8 @@ namespace org.budnhead.core
|
||||||
rows[2] = new Vector4(X.Z,Y.Z,Z.Z,W.Z);
|
rows[2] = new Vector4(X.Z,Y.Z,Z.Z,W.Z);
|
||||||
c = new Vector3();
|
c = new Vector3();
|
||||||
|
|
||||||
Console.WriteLine("New Linear Equation System to solve:");
|
//Console.WriteLine("New Linear Equation System to solve:");
|
||||||
dumpLinearSystem(rows);
|
//dumpLinearSystem(rows);
|
||||||
|
|
||||||
if (rows[0].Z == 0){
|
if (rows[0].Z == 0){
|
||||||
Vector4 t = rows[0];
|
Vector4 t = rows[0];
|
||||||
|
@ -34,7 +34,7 @@ namespace org.budnhead.core
|
||||||
rows[2] -= rows[0] * (rows[2].Z / rows[0].Z);
|
rows[2] -= rows[0] * (rows[2].Z / rows[0].Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpLinearSystem(rows);
|
//dumpLinearSystem(rows);
|
||||||
|
|
||||||
if (rows[1].Y == 0){
|
if (rows[1].Y == 0){
|
||||||
Vector4 t = rows[1];
|
Vector4 t = rows[1];
|
||||||
|
@ -48,7 +48,7 @@ namespace org.budnhead.core
|
||||||
rows[2] -= rows[1] * (rows[2].Y / rows[1].Y);
|
rows[2] -= rows[1] * (rows[2].Y / rows[1].Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpLinearSystem(rows);
|
//dumpLinearSystem(rows);
|
||||||
|
|
||||||
rows[2] /= rows[2].X;
|
rows[2] /= rows[2].X;
|
||||||
c.X = rows[2].W;
|
c.X = rows[2].W;
|
||||||
|
@ -65,8 +65,8 @@ namespace org.budnhead.core
|
||||||
rows[0] /= rows[0].Z;
|
rows[0] /= rows[0].Z;
|
||||||
c.Z = rows[0].W;
|
c.Z = rows[0].W;
|
||||||
|
|
||||||
dumpLinearSystem(rows);
|
//dumpLinearSystem(rows);
|
||||||
Console.WriteLine("Solved to {0}",c);
|
//Console.WriteLine("Solved to {0}",c);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,10 @@ using OpenTK.Graphics.OpenGL4;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
using org.hwo.contracts;
|
using org.hwo.contracts;
|
||||||
|
|
||||||
using org.budnhead.core;
|
|
||||||
using org.budnhead.exceptions;
|
using org.budnhead.exceptions;
|
||||||
|
using org.budnhead.graphics;
|
||||||
|
|
||||||
namespace org.budnhead.graphics
|
namespace org.budnhead.core
|
||||||
{
|
{
|
||||||
public class SquaredMap : WorldObject
|
public class SquaredMap : WorldObject
|
||||||
{
|
{
|
||||||
|
@ -197,7 +196,7 @@ namespace org.budnhead.graphics
|
||||||
|
|
||||||
public Vector2 toTileBorderless(Vector2 world){
|
public Vector2 toTileBorderless(Vector2 world){
|
||||||
Vector2 tile = world / edge;
|
Vector2 tile = world / edge;
|
||||||
return tile;
|
return new Vector2((int)tile.X,(int)tile.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 toTile(Vector2 world){
|
public Vector2 toTile(Vector2 world){
|
||||||
|
@ -211,7 +210,7 @@ namespace org.budnhead.graphics
|
||||||
.requires(tile.Y < height)
|
.requires(tile.Y < height)
|
||||||
.throws<OutOfWorldException>();
|
.throws<OutOfWorldException>();
|
||||||
|
|
||||||
return tile;
|
return new Vector2((int)tile.X,(int)tile.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 intersectTile(Vector3 P,Vector3 V){
|
public Vector2 intersectTile(Vector3 P,Vector3 V){
|
||||||
|
@ -225,57 +224,63 @@ namespace org.budnhead.graphics
|
||||||
|
|
||||||
Console.WriteLine("P: {0} V: {1}",P,V);
|
Console.WriteLine("P: {0} V: {1}",P,V);
|
||||||
|
|
||||||
if (!Geometry.intersectPlain(P,V,corners[0],corners[1],corners[3],out A)){
|
|
||||||
throw new OutOfWorldException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Geometry.intersectPlain(P,V,corners[4],corners[5],corners[7],out B)){
|
|
||||||
throw new OutOfWorldException();
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Lower Plane Intersection (LIN): {0}",A);
|
|
||||||
A = P + ( V * ( -P.Z / V.Z) );
|
A = P + ( V * ( -P.Z / V.Z) );
|
||||||
Console.WriteLine("Lower Plane Intersection: {0}",A);
|
Console.WriteLine("Lower Plane Intersection: {0}",A);
|
||||||
|
|
||||||
Console.WriteLine("Higher Plane Intersection (LIN): {0}",B);
|
|
||||||
B = P + ( V * ( (SquaredMap.maxHeight-P.Z) / V.Z) );
|
B = P + ( V * ( (SquaredMap.maxHeight-P.Z) / V.Z) );
|
||||||
Console.WriteLine("Higher Plane Intersection: {0}",B);
|
Console.WriteLine("Higher Plane Intersection: {0}",B);
|
||||||
|
|
||||||
Vector2 a,b,min,max;
|
Vector2 start = Vector2.ComponentMin(A.Xy,B.Xy);
|
||||||
|
Vector2 finish = Vector2.ComponentMax(A.Xy,B.Xy);
|
||||||
|
Vector2 step = finish - start;
|
||||||
|
|
||||||
a = toTileBorderless(A.Xy);
|
float steps = (step.X * step.Y) / 25.0f;
|
||||||
b = toTileBorderless(B.Xy);
|
step /= steps;
|
||||||
|
|
||||||
min = Vector2.ComponentMax(Vector2.ComponentMin(a,b)-new Vector2(1,1),new Vector2());
|
int isteps = (int)steps;
|
||||||
max = Vector2.ComponentMin(Vector2.ComponentMax(a,b)+new Vector2(1,1),new Vector2(width,height));
|
|
||||||
|
|
||||||
Console.WriteLine("Checking Intersections: {0} -> {1}",min,max);
|
Vector2 pos = start,
|
||||||
|
tile = toTileBorderless(pos);
|
||||||
|
|
||||||
for (int nx = (int)min.X; nx < max.X; nx++){
|
Console.WriteLine("Interpolation: {0} - {1} - {2}",start,step,finish);
|
||||||
for (int ny = (int)min.Y; ny < max.Y; ny++){
|
|
||||||
Vector3 isect = new Vector3();
|
|
||||||
//Console.WriteLine("Check Intersection: {0}/{1}",nx,ny);
|
|
||||||
|
|
||||||
for (int n=0;n<4;n++){
|
for (int n=0;n<=isteps;){
|
||||||
try {
|
Console.WriteLine("IP RUN[{0}]: {1} Tile: {2}",n,pos,tile);
|
||||||
Model3D.Triangle t = model.triangles[tileIndex(nx,ny)];
|
if (new BooleanConditional()
|
||||||
if (Geometry.intersectTriangle(
|
.requires( tile.X >= 0)
|
||||||
P,
|
.requires( tile.Y >= 0)
|
||||||
V,
|
.requires( tile.X < width)
|
||||||
t.VertexA,
|
.requires( tile.Y < height)
|
||||||
t.VertexB,
|
.isSuccess()
|
||||||
t.VertexC,
|
){
|
||||||
out isect
|
Vector3 isect = new Vector3();
|
||||||
)){
|
for (int nt=0;nt<4;nt++){
|
||||||
return isect;
|
try {
|
||||||
|
Model3D.Triangle t = model.triangles[tileIndex((int)tile.X,(int)tile.Y)];
|
||||||
|
if (Geometry.intersectTriangle(
|
||||||
|
P,
|
||||||
|
V,
|
||||||
|
t.VertexA,
|
||||||
|
t.VertexB,
|
||||||
|
t.VertexC,
|
||||||
|
out isect
|
||||||
|
)){
|
||||||
|
return isect;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (OutOfWorldException){
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (OutOfWorldException owe){
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Vector2 nextTile = tile;
|
||||||
|
while (nextTile.Equals(tile)){
|
||||||
|
pos += step;
|
||||||
|
nextTile = toTileBorderless(pos);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
tile = nextTile;
|
||||||
|
}
|
||||||
throw new OutOfWorldException();
|
throw new OutOfWorldException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,13 +20,15 @@ namespace org.budnhead.core
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Position{ get; set; } = new Vector3();
|
public readonly BufferedValueInstance<Vector3> Position = new BufferedValueInstance<Vector3>(new Vector3());
|
||||||
public Matrix4 Rotation { get; set; } = Matrix4.Identity;
|
public readonly BufferedValueInstance<Matrix4> Rotation = new BufferedValueInstance<Matrix4>(Matrix4.Identity);
|
||||||
public Matrix4 Scale { get; set; } = Matrix4.Identity;
|
public readonly BufferedValueInstance<Matrix4> Scale = new BufferedValueInstance<Matrix4>(Matrix4.Identity);
|
||||||
|
|
||||||
|
|
||||||
public Matrix4 Transformation {
|
public Matrix4 Transformation {
|
||||||
get { return (Scale * Rotation) * Matrix4.CreateTranslation( Position ) ; }
|
get { return (Scale.Value * Rotation.Value) * Matrix4.CreateTranslation( Position.Value ) ; }
|
||||||
|
}
|
||||||
|
public Matrix4 BufferedTransformation {
|
||||||
|
get { return (Scale.BufferedValue * Rotation.BufferedValue) * Matrix4.CreateTranslation( Position.BufferedValue ) ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChild(WorldObject wo){
|
public void addChild(WorldObject wo){
|
||||||
|
@ -44,7 +46,6 @@ namespace org.budnhead.core
|
||||||
public WorldObject[] Children{
|
public WorldObject[] Children{
|
||||||
get { return this.children.ToArray(); }
|
get { return this.children.ToArray(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObjectGroup : WorldObject {
|
public class ObjectGroup : WorldObject {
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace org.budnhead.graphics
|
||||||
buildMatrices();
|
buildMatrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setViewport(int width, int height)
|
override public void setViewport(int width, int height)
|
||||||
{
|
{
|
||||||
this.width = (float)width;
|
this.width = (float)width;
|
||||||
this.height = (float)height;
|
this.height = (float)height;
|
||||||
|
@ -54,7 +54,7 @@ namespace org.budnhead.graphics
|
||||||
aspect,
|
aspect,
|
||||||
1.0f,
|
1.0f,
|
||||||
100000.0f
|
100000.0f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Position
|
public Vector3 Position
|
||||||
|
@ -136,6 +136,21 @@ namespace org.budnhead.graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of Methods: LookXXXX
|
||||||
|
*
|
||||||
|
* Arrange Camera to point on/to/...
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
public void lookAt(Vector3 position){
|
||||||
|
Vector3 v = position - Position;
|
||||||
|
v.Normalize();
|
||||||
|
|
||||||
|
View = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ using OpenTK.Graphics.OpenGL;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
namespace org.budnhead.graphics
|
namespace org.budnhead.graphics
|
||||||
{
|
{
|
||||||
|
@ -33,13 +34,13 @@ namespace org.budnhead.graphics
|
||||||
|
|
||||||
public GLObject(int vertexes)
|
public GLObject(int vertexes)
|
||||||
{
|
{
|
||||||
shaderProgram = GlobalDefaults.instance().DefaultShaderProgram;
|
shaderProgram = ResourceLibrary.getResource<ShaderProgram>("default");
|
||||||
init(vertexes);
|
init(vertexes);
|
||||||
prepareGL();
|
prepareGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GLObject(){
|
public GLObject(){
|
||||||
shaderProgram = GlobalDefaults.instance().DefaultShaderProgram;
|
shaderProgram = ResourceLibrary.getResource<ShaderProgram>("default");
|
||||||
init(0);
|
init(0);
|
||||||
prepareGL();
|
prepareGL();
|
||||||
}
|
}
|
||||||
|
@ -194,7 +195,7 @@ namespace org.budnhead.graphics
|
||||||
|
|
||||||
public void paint()
|
public void paint()
|
||||||
{
|
{
|
||||||
paint(GlobalDefaults.instance().ActiveScene);
|
paint(new GLCamera());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paint(GLSceneOrientation scene)
|
public void paint(GLSceneOrientation scene)
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using OpenTK;
|
|
||||||
using org.budnhead.core;
|
|
||||||
|
|
||||||
namespace org.budnhead.graphics
|
|
||||||
{
|
|
||||||
public class GLScene
|
|
||||||
{
|
|
||||||
GLSceneOrientation sceneOrientation;
|
|
||||||
ShaderProgram shader;
|
|
||||||
WorldObject root;
|
|
||||||
|
|
||||||
public GLScene()
|
|
||||||
{
|
|
||||||
sceneOrientation = GlobalDefaults.instance().ActiveScene;
|
|
||||||
shader = GlobalDefaults.instance().DefaultShaderProgram;
|
|
||||||
root = new ObjectGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GLScene(GLSceneOrientation sceneOrientation)
|
|
||||||
{
|
|
||||||
this.sceneOrientation = sceneOrientation;
|
|
||||||
shader = GlobalDefaults.instance().DefaultShaderProgram;
|
|
||||||
root = new ObjectGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public WorldObject RootObject {
|
|
||||||
get { return this.root; }
|
|
||||||
set { this.root = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(){
|
|
||||||
Matrix4 objectMatrix = Matrix4.Identity;
|
|
||||||
|
|
||||||
shader.use();
|
|
||||||
|
|
||||||
if (root != null){
|
|
||||||
draw( objectMatrix, root );
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (WorldObject child in Actor.activeActors){
|
|
||||||
draw( objectMatrix, child );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Matrix4 baseMatrix,WorldObject wo){
|
|
||||||
Matrix4 objectMatrix = wo.Transformation * baseMatrix;
|
|
||||||
|
|
||||||
//Console.WriteLine("draw(,{0}",wo);
|
|
||||||
|
|
||||||
//Console.WriteLine("draw(): o={0}\noM=\n{1}",wo,objectMatrix);
|
|
||||||
shader.setup(objectMatrix, sceneOrientation);
|
|
||||||
|
|
||||||
Model3D m3d = wo.getModel3D();
|
|
||||||
if (m3d != null){
|
|
||||||
m3d.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (WorldObject child in wo.Children){
|
|
||||||
draw( objectMatrix, child );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,5 +28,16 @@ namespace org.budnhead.graphics
|
||||||
public Matrix4 mProjection(){
|
public Matrix4 mProjection(){
|
||||||
return this._mProjection;
|
return this._mProjection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void setViewport(int width, int height){
|
||||||
|
float aspect = width / height;
|
||||||
|
|
||||||
|
_mProjection = Matrix4.CreatePerspectiveFieldOfView(
|
||||||
|
MathHelper.PiOver2,
|
||||||
|
aspect,
|
||||||
|
1.0f,
|
||||||
|
100000.0f
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
@ -8,13 +9,12 @@ using OpenTK;
|
||||||
|
|
||||||
using org.budnhead.core;
|
using org.budnhead.core;
|
||||||
using org.budnhead.exceptions;
|
using org.budnhead.exceptions;
|
||||||
using org.budnhead.graphics;
|
|
||||||
using org.budnhead.graphics.primitives;
|
using org.budnhead.graphics.primitives;
|
||||||
|
|
||||||
namespace bnhdemo
|
namespace org.budnhead.graphics
|
||||||
{
|
{
|
||||||
|
|
||||||
public class OpenGLWindow : GameWindow
|
public class GLWindow : GameWindow
|
||||||
{
|
{
|
||||||
private Point mouseCapturePosition;
|
private Point mouseCapturePosition;
|
||||||
private bool mouseCaptured;
|
private bool mouseCaptured;
|
||||||
|
@ -25,15 +25,11 @@ namespace bnhdemo
|
||||||
private Vector3 lookAt;
|
private Vector3 lookAt;
|
||||||
private float lookDistance;
|
private float lookDistance;
|
||||||
|
|
||||||
private Cube cube,
|
|
||||||
c1, c2, c3;
|
|
||||||
|
|
||||||
private string titleMsg = "";
|
|
||||||
|
|
||||||
GLCamera sceneCamera;
|
GLCamera sceneCamera;
|
||||||
GLScene scene;
|
Scene scene;
|
||||||
|
|
||||||
public OpenGLWindow()
|
public GLWindow()
|
||||||
:base(600, 600,
|
:base(600, 600,
|
||||||
GraphicsMode.Default,
|
GraphicsMode.Default,
|
||||||
"nhEngine",
|
"nhEngine",
|
||||||
|
@ -44,37 +40,29 @@ namespace bnhdemo
|
||||||
{
|
{
|
||||||
VSync = VSyncMode.On;
|
VSync = VSyncMode.On;
|
||||||
sceneCamera = new GLCamera();
|
sceneCamera = new GLCamera();
|
||||||
scene = new GLScene(sceneCamera);
|
scene = new Scene(sceneCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scene Scene {
|
||||||
|
get { return this.scene; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLoad(EventArgs e)
|
protected override void OnLoad(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLoad(e);
|
base.OnLoad(e);
|
||||||
GL.ClearColor(0.05f, 0.05f, 0.05f, 0.0f);
|
GL.ClearColor(0.15f, 0.15f, 0.15f, 0.0f);
|
||||||
GL.Enable(EnableCap.DepthTest);
|
GL.Enable(EnableCap.DepthTest);
|
||||||
GL.Enable(EnableCap.Normalize);
|
GL.Enable(EnableCap.Normalize);
|
||||||
GL.Enable(EnableCap.Blend);
|
GL.Enable(EnableCap.Blend);
|
||||||
GL.BlendFunc(BlendingFactorSrc.SrcAlpha,BlendingFactorDest.OneMinusSrcAlpha);
|
GL.BlendFunc(BlendingFactorSrc.SrcAlpha,BlendingFactorDest.OneMinusSrcAlpha);
|
||||||
|
|
||||||
cube = new Cube(new Vector3(0,0,150), 16.0f);
|
|
||||||
c1 = new Cube(new Vector3(16,0,150), 8.0f);
|
|
||||||
c2 = new Cube(new Vector3(0,150,150), 8.0f);
|
|
||||||
c3 = new Cube(new Vector3(175,175,150), 8.0f);
|
|
||||||
|
|
||||||
lookAt = new Vector3(0,0,SquaredMap.maxHeight);
|
lookAt = new Vector3(0,0,SquaredMap.maxHeight);
|
||||||
lookDistance = 2048;
|
lookDistance = 2048;
|
||||||
arcUpDown = MathHelper.PiOver6;
|
arcUpDown = MathHelper.PiOver6;
|
||||||
arcLeftRight = MathHelper.PiOver4;
|
arcLeftRight = MathHelper.PiOver4;
|
||||||
|
sceneCamera.setFoV(MathHelper.PiOver2);
|
||||||
sceneCamera.setFoV(MathHelper.PiOver4);
|
|
||||||
|
|
||||||
setupCamera();
|
setupCamera();
|
||||||
|
|
||||||
scene.RootObject.addChild( cube );
|
|
||||||
scene.RootObject.addChild( c1 );
|
|
||||||
scene.RootObject.addChild( c2 );
|
|
||||||
scene.RootObject.addChild( c3 );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
|
@ -85,32 +73,6 @@ namespace bnhdemo
|
||||||
sceneCamera.setViewport(ClientRectangle.Width, ClientRectangle.Height);
|
sceneCamera.setViewport(ClientRectangle.Width, ClientRectangle.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderFrame(FrameEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnRenderFrame(e);
|
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
|
||||||
|
|
||||||
scene.draw();
|
|
||||||
|
|
||||||
SwapBuffers();
|
|
||||||
|
|
||||||
Title = string.Format("{0:F}/s {1:F}/s [{2:F}s] {3}", RenderFrequency,UpdateFrequency,UpdatePeriod,titleMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnUpdateFrame(e);
|
|
||||||
Matrix4 m4 = Matrix4.CreateRotationZ(MathHelper.Pi / 90.0f);
|
|
||||||
|
|
||||||
cube.Rotation = m4 * cube.Rotation;
|
|
||||||
c1.Position = (m4.Inverted() * new Vector4(c1.Position)).Xyz;
|
|
||||||
c2.Rotation = (m4 * c2.Rotation);
|
|
||||||
c3.Position = (m4 * new Vector4(c3.Position)).Xyz;
|
|
||||||
|
|
||||||
|
|
||||||
Actor.updateAll( (float)UpdatePeriod );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void captureMouse(){
|
private void captureMouse(){
|
||||||
mouseCapturePosition = new Point(Mouse.X, Mouse.Y);
|
mouseCapturePosition = new Point(Mouse.X, Mouse.Y);
|
||||||
mouseCaptured = true;
|
mouseCaptured = true;
|
||||||
|
@ -141,7 +103,7 @@ namespace bnhdemo
|
||||||
{
|
{
|
||||||
switch (e.Button){
|
switch (e.Button){
|
||||||
case OpenTK.Input.MouseButton.Left:
|
case OpenTK.Input.MouseButton.Left:
|
||||||
markMouse(e.X,e.Y);
|
//markMouse(e.X,e.Y);
|
||||||
break;
|
break;
|
||||||
case OpenTK.Input.MouseButton.Right:
|
case OpenTK.Input.MouseButton.Right:
|
||||||
captureMouse();
|
captureMouse();
|
||||||
|
@ -211,7 +173,7 @@ namespace bnhdemo
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenTK.Input.Key.Space:
|
case OpenTK.Input.Key.Space:
|
||||||
fireBallistic();
|
//fireBallistic();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenTK.Input.Key.Number1:
|
case OpenTK.Input.Key.Number1:
|
||||||
|
@ -234,7 +196,7 @@ namespace bnhdemo
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
private void fireBallistic(){
|
private void fireBallistic(){
|
||||||
Console.WriteLine("Fire Ballistic...");
|
Console.WriteLine("Fire Ballistic...");
|
||||||
BallisticActor ba = new BallisticActor(0);
|
BallisticActor ba = new BallisticActor(0);
|
||||||
|
@ -245,7 +207,7 @@ namespace bnhdemo
|
||||||
ba.Velocity.Normalize();
|
ba.Velocity.Normalize();
|
||||||
ba.Velocity *= 50;
|
ba.Velocity *= 50;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public void rotateUpDown(float arc)
|
public void rotateUpDown(float arc)
|
||||||
{
|
{
|
||||||
|
@ -289,10 +251,20 @@ namespace bnhdemo
|
||||||
sceneCamera.Position = pos;
|
sceneCamera.Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GLScene Scene {
|
|
||||||
get { return this.scene; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* private void startTimers(){
|
||||||
|
timerGraphics.Change(0,50);
|
||||||
|
timerUpdates.Change(0,50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void stopTimers(){
|
||||||
|
timerGraphics.Change(Timeout.Infinite,Timeout.Infinite);
|
||||||
|
timerUpdates.Change(Timeout.Infinite,Timeout.Infinite);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,10 @@ namespace org.budnhead.graphics
|
||||||
load(new StreamReader(filename),scale);
|
load(new StreamReader(filename),scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoadedModel(Stream stream){
|
||||||
|
load(new StreamReader(stream),1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
private void load(TextReader reader){
|
private void load(TextReader reader){
|
||||||
load(reader,1);
|
load(reader,1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace org.budnhead.graphics {
|
||||||
|
|
||||||
public class Model3D {
|
public class Model3D {
|
||||||
|
|
||||||
protected int vao,
|
protected int vao = 0,
|
||||||
vbo, // Vertex Buffer
|
vbo, // Vertex Buffer
|
||||||
cbo, // Color Buffer
|
cbo, // Color Buffer
|
||||||
cbo2, // Second Color Buffer
|
cbo2, // Second Color Buffer
|
||||||
|
@ -24,15 +24,14 @@ namespace org.budnhead.graphics {
|
||||||
|
|
||||||
public Triangle[] triangles = new Triangle[0];
|
public Triangle[] triangles = new Triangle[0];
|
||||||
|
|
||||||
|
public Model3D(){
|
||||||
protected Model3D(){
|
|
||||||
vao = GL.GenVertexArray();
|
|
||||||
nTriangles = 0;
|
nTriangles = 0;
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void prepare(){
|
protected void prepare(){
|
||||||
|
vao = GL.GenVertexArray();
|
||||||
vbo = GL.GenBuffer();
|
vbo = GL.GenBuffer();
|
||||||
cbo = GL.GenBuffer();
|
cbo = GL.GenBuffer();
|
||||||
cbo2 = GL.GenBuffer();
|
cbo2 = GL.GenBuffer();
|
||||||
|
@ -110,6 +109,10 @@ namespace org.budnhead.graphics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rebind(){
|
public void rebind(){
|
||||||
|
if (vao != 0){
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
bindVertexes();
|
bindVertexes();
|
||||||
bindNormals();
|
bindNormals();
|
||||||
bindColors();
|
bindColors();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using org.budnhead.core;
|
using org.budnhead.core;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
namespace org.budnhead.graphics
|
namespace org.budnhead.graphics
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using org.budnhead.core;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
|
||||||
|
namespace org.budnhead.graphics
|
||||||
|
{
|
||||||
|
public class Scene
|
||||||
|
{
|
||||||
|
ShaderProgram shader;
|
||||||
|
WorldObject root;
|
||||||
|
|
||||||
|
public Scene()
|
||||||
|
{
|
||||||
|
shader = ResourceLibrary.getResource<ShaderProgram>("default");
|
||||||
|
root = new ObjectGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scene(GLSceneOrientation sceneOrientation)
|
||||||
|
{
|
||||||
|
shader = ResourceLibrary.getResource<ShaderProgram>("default");
|
||||||
|
root = new ObjectGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scene(Scene source){
|
||||||
|
this.shader = source.shader;
|
||||||
|
this.root = source.root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WorldObject RootObject {
|
||||||
|
get { return this.root; }
|
||||||
|
set { this.root = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Viewport viewport){
|
||||||
|
Matrix4 objectMatrix = Matrix4.Identity;
|
||||||
|
|
||||||
|
shader.use();
|
||||||
|
|
||||||
|
if (root != null){
|
||||||
|
draw( viewport, objectMatrix, root );
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (WorldObject child in Actor.activeActors.ToArray()){
|
||||||
|
draw( viewport, objectMatrix, child );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Viewport viewport,Matrix4 baseMatrix,WorldObject wo){
|
||||||
|
Matrix4 objectMatrix = wo.Transformation * baseMatrix;
|
||||||
|
|
||||||
|
//Console.WriteLine("draw(,{0}",wo);
|
||||||
|
|
||||||
|
//Console.WriteLine("draw(): o={0}\noM=\n{1}",wo,objectMatrix);
|
||||||
|
shader.setup(objectMatrix, viewport.SceneOrientation);
|
||||||
|
|
||||||
|
Model3D m3d = wo.getModel3D();
|
||||||
|
if (m3d != null){
|
||||||
|
m3d.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (WorldObject child in wo.Children){
|
||||||
|
draw( viewport, objectMatrix, child );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
|
using org.budnhead.core;
|
||||||
|
|
||||||
|
namespace org.budnhead.graphics
|
||||||
|
{
|
||||||
|
public class SceneWindow : GameWindow
|
||||||
|
{
|
||||||
|
Scene scene;
|
||||||
|
|
||||||
|
Viewport primaryViewport;
|
||||||
|
List<Viewport> viewports = new List<Viewport>();
|
||||||
|
|
||||||
|
internal SceneWindow()
|
||||||
|
:base(600, 600,
|
||||||
|
GraphicsMode.Default,
|
||||||
|
"nhEngine",
|
||||||
|
GameWindowFlags.Default,
|
||||||
|
DisplayDevice.Default,
|
||||||
|
3, 3,
|
||||||
|
GraphicsContextFlags.ForwardCompatible)
|
||||||
|
{
|
||||||
|
this.primaryViewport = new Viewport();
|
||||||
|
addViewport(primaryViewport);
|
||||||
|
|
||||||
|
lock(Engine.sceneWindows){
|
||||||
|
Engine.sceneWindows.Add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Viewport PrimaryViewport {
|
||||||
|
get { return this.primaryViewport; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Viewport[] Viewports {
|
||||||
|
get { return this.viewports.ToArray(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
lock (Engine.sceneWindows){
|
||||||
|
Engine.sceneWindows.Remove(this);
|
||||||
|
if (Engine.sceneWindows.Count == 0){
|
||||||
|
Engine.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addViewport(Viewport viewport){
|
||||||
|
if (viewport.Parent != null){
|
||||||
|
viewport.Parent.removeViewport(viewport);
|
||||||
|
}
|
||||||
|
this.viewports.Add(viewport);
|
||||||
|
viewport.Parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeViewport(Viewport viewport){
|
||||||
|
if ((primaryViewport!=viewport) && (viewports.Contains(viewport))){
|
||||||
|
viewport.Parent = null;
|
||||||
|
viewports.Remove(viewport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scene Scene {
|
||||||
|
get { return this.primaryViewport.Scene; }
|
||||||
|
set { lock(this){
|
||||||
|
this.primaryViewport.Scene = value;
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnResize(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnResize(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnRenderFrame(FrameEventArgs e)
|
||||||
|
{
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnClosed(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnClosed(e);
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(){
|
||||||
|
lock(this){
|
||||||
|
MakeCurrent();
|
||||||
|
|
||||||
|
paintViewports();
|
||||||
|
paintControls();
|
||||||
|
|
||||||
|
SwapBuffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintViewports(){
|
||||||
|
Engine.ConsumerEnter();
|
||||||
|
|
||||||
|
foreach (Viewport viewport in this.viewports){
|
||||||
|
viewport.paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine.ConsumerExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintControls(){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ using System.IO;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
|
using org.budnhead.tools;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ShaderProgram Class
|
* ShaderProgram Class
|
||||||
*
|
*
|
||||||
|
@ -70,8 +72,8 @@ namespace org.budnhead.graphics
|
||||||
public ShaderProgram(String vertexShader, String fragmentShader)
|
public ShaderProgram(String vertexShader, String fragmentShader)
|
||||||
{
|
{
|
||||||
init(
|
init(
|
||||||
new Shader(ShaderType.VertexShader, vertexShader),
|
ResourceLibrary.getResource<Shader>(vertexShader),
|
||||||
new Shader(ShaderType.FragmentShader, fragmentShader)
|
ResourceLibrary.getResource<Shader>(fragmentShader)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
using org.budnhead.core;
|
||||||
|
using org.budnhead.tools;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
|
namespace org.budnhead.graphics
|
||||||
|
{
|
||||||
|
public class Viewport
|
||||||
|
{
|
||||||
|
GLSceneOrientation sceneOrientation;
|
||||||
|
Scene scene;
|
||||||
|
ShaderProgram shader;
|
||||||
|
|
||||||
|
public float Left { get; set; }
|
||||||
|
public float Top { get; set; }
|
||||||
|
public float Width { get; set; }
|
||||||
|
public float Height { get; set; }
|
||||||
|
|
||||||
|
public Viewport()
|
||||||
|
{
|
||||||
|
sceneOrientation = new GLSceneOrientation();
|
||||||
|
Left = 0.0f;
|
||||||
|
Top = 0.0f;
|
||||||
|
Width = 1.0f;
|
||||||
|
Height = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SceneWindow Parent { get; set; }
|
||||||
|
|
||||||
|
public Scene Scene {
|
||||||
|
get { return this.scene; }
|
||||||
|
set { this.scene = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLSceneOrientation SceneOrientation {
|
||||||
|
get { return this.sceneOrientation; }
|
||||||
|
set { this.sceneOrientation = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(){
|
||||||
|
Console.WriteLine("Viewport.paint()");
|
||||||
|
if (Parent != null){
|
||||||
|
Rectangle cr = Parent.ClientRectangle;
|
||||||
|
Rectangle vpr = new Rectangle(
|
||||||
|
(int)(cr.Left + (cr.Width * Left)),
|
||||||
|
(int)(cr.Top + (cr.Height * Top)),
|
||||||
|
(int)(cr.Width * Width),
|
||||||
|
(int)(cr.Height * Height)
|
||||||
|
);
|
||||||
|
|
||||||
|
Console.WriteLine(String.Format("Viewport: {0}",vpr));
|
||||||
|
|
||||||
|
GL.Viewport( vpr );
|
||||||
|
sceneOrientation.setViewport( cr.Width, cr.Height );
|
||||||
|
|
||||||
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||||
|
|
||||||
|
Scene.draw(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,8 @@ namespace org.budnhead.graphics.primitives
|
||||||
{
|
{
|
||||||
public Cube(Vector3 position, float width)
|
public Cube(Vector3 position, float width)
|
||||||
{
|
{
|
||||||
Scale = Matrix4.CreateScale(width);
|
Scale.Value = Matrix4.CreateScale(width);
|
||||||
Position = position;
|
Position.Value = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Model3D getModel3D()
|
public override Model3D getModel3D()
|
||||||
|
|
|
@ -50,18 +50,15 @@
|
||||||
<Compile Include="graphics\GLObject.cs" />
|
<Compile Include="graphics\GLObject.cs" />
|
||||||
<Compile Include="graphics\Shader.cs" />
|
<Compile Include="graphics\Shader.cs" />
|
||||||
<Compile Include="graphics\ShaderProgram.cs" />
|
<Compile Include="graphics\ShaderProgram.cs" />
|
||||||
<Compile Include="graphics\GlobalDefaults.cs" />
|
|
||||||
<Compile Include="graphics\primitives\Cube.cs" />
|
<Compile Include="graphics\primitives\Cube.cs" />
|
||||||
<Compile Include="graphics\primitives\Triangle.cs" />
|
<Compile Include="graphics\primitives\Triangle.cs" />
|
||||||
<Compile Include="graphics\GLSceneOrientation.cs" />
|
<Compile Include="graphics\GLSceneOrientation.cs" />
|
||||||
<Compile Include="graphics\GLModel.cs" />
|
<Compile Include="graphics\GLModel.cs" />
|
||||||
<Compile Include="graphics\GLScene.cs" />
|
<Compile Include="graphics\Scene.cs" />
|
||||||
<Compile Include="graphics\Model3D.cs" />
|
<Compile Include="graphics\Model3D.cs" />
|
||||||
<Compile Include="graphics\ModelManager.cs" />
|
<Compile Include="graphics\ModelManager.cs" />
|
||||||
<Compile Include="FileHelper.cs" />
|
|
||||||
<Compile Include="graphics\Texture.cs" />
|
<Compile Include="graphics\Texture.cs" />
|
||||||
<Compile Include="graphics\LoadedModel.cs" />
|
<Compile Include="graphics\LoadedModel.cs" />
|
||||||
<Compile Include="graphics\SquaredMap.cs" />
|
|
||||||
<Compile Include="exceptions\OutOfWorldException.cs" />
|
<Compile Include="exceptions\OutOfWorldException.cs" />
|
||||||
<Compile Include="audio\nhPlayer.cs" />
|
<Compile Include="audio\nhPlayer.cs" />
|
||||||
<Compile Include="audio\AudioDelegate.cs" />
|
<Compile Include="audio\AudioDelegate.cs" />
|
||||||
|
@ -77,6 +74,25 @@
|
||||||
<Compile Include="core\Physics.cs" />
|
<Compile Include="core\Physics.cs" />
|
||||||
<Compile Include="core\WorldObject.cs" />
|
<Compile Include="core\WorldObject.cs" />
|
||||||
<Compile Include="exceptions\BudNHeadException.cs" />
|
<Compile Include="exceptions\BudNHeadException.cs" />
|
||||||
|
<Compile Include="core\Engine.cs" />
|
||||||
|
<Compile Include="core\BufferedValue.cs" />
|
||||||
|
<Compile Include="graphics\GLWindow.cs" />
|
||||||
|
<Compile Include="core\SquaredMap.cs" />
|
||||||
|
<Compile Include="ui\Control.cs" />
|
||||||
|
<Compile Include="ui\Container.cs" />
|
||||||
|
<Compile Include="ui\events\UIEvent.cs" />
|
||||||
|
<Compile Include="ui\events\KeyPressedEvent.cs" />
|
||||||
|
<Compile Include="ui\ModifierKeys.cs" />
|
||||||
|
<Compile Include="core\ConsumerProducerLock.cs" />
|
||||||
|
<Compile Include="graphics\SceneWindow.cs" />
|
||||||
|
<Compile Include="tools\ResourceLibrary.cs" />
|
||||||
|
<Compile Include="tools\FileHelper.cs" />
|
||||||
|
<Compile Include="core\GlobalDefaults.cs" />
|
||||||
|
<Compile Include="tools\JobThreader.cs" />
|
||||||
|
<Compile Include="audio\streams\StreamSegment.cs" />
|
||||||
|
<Compile Include="audio\streams\AudioDomain.cs" />
|
||||||
|
<Compile Include="ui\SceneInScene.cs" />
|
||||||
|
<Compile Include="graphics\Viewport.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@ -159,6 +175,10 @@
|
||||||
</Folder>
|
</Folder>
|
||||||
<Folder Include="exceptions\" />
|
<Folder Include="exceptions\" />
|
||||||
<Folder Include="core\" />
|
<Folder Include="core\" />
|
||||||
|
<Folder Include="ui\" />
|
||||||
|
<Folder Include="ui\events\" />
|
||||||
|
<Folder Include="tools\" />
|
||||||
|
<Folder Include="audio\streams\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\org.hwo.contracts\org.hwo.contracts.csproj">
|
<ProjectReference Include="..\org.hwo.contracts\org.hwo.contracts.csproj">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace org.budnhead.core
|
namespace org.budnhead.tools
|
||||||
{
|
{
|
||||||
public static class FileHelper
|
public static class FileHelper
|
||||||
{
|
{
|
|
@ -0,0 +1,84 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace org.budnhead.tools
|
||||||
|
{
|
||||||
|
public delegate T JobDelegate<T>();
|
||||||
|
|
||||||
|
public class JobThreader
|
||||||
|
{
|
||||||
|
Thread workerThread;
|
||||||
|
List<Job> queuedJobs;
|
||||||
|
|
||||||
|
|
||||||
|
public JobThreader()
|
||||||
|
{
|
||||||
|
workerThread = Thread.CurrentThread;
|
||||||
|
queuedJobs = new List<Job>();
|
||||||
|
}
|
||||||
|
public JobThreader(Thread workerThread){
|
||||||
|
this.workerThread = workerThread;
|
||||||
|
queuedJobs = new List<Job>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(){
|
||||||
|
Monitor.Enter(queuedJobs);
|
||||||
|
|
||||||
|
foreach (Job j in queuedJobs){
|
||||||
|
j.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
queuedJobs.Clear();
|
||||||
|
|
||||||
|
Monitor.PulseAll(queuedJobs);
|
||||||
|
Monitor.Exit(queuedJobs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T execute<T>(JobDelegate<T> jobDelegate) where T : class{
|
||||||
|
if (workerThread.Equals(Thread.CurrentThread)){
|
||||||
|
return jobDelegate();
|
||||||
|
} else {
|
||||||
|
return Enqueue(jobDelegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T Enqueue<T>(JobDelegate<T> jobDelegate) where T : class {
|
||||||
|
Job<T> job;
|
||||||
|
Monitor.Enter(queuedJobs);
|
||||||
|
|
||||||
|
job = new Job<T>(jobDelegate);
|
||||||
|
|
||||||
|
queuedJobs.Add(job);
|
||||||
|
|
||||||
|
Monitor.Wait(queuedJobs);
|
||||||
|
Monitor.Exit(queuedJobs);
|
||||||
|
|
||||||
|
return job.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class Job{
|
||||||
|
public virtual void execute(){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Job<T> : Job{
|
||||||
|
T result;
|
||||||
|
JobDelegate<T> jobDelegate;
|
||||||
|
|
||||||
|
public Job(JobDelegate<T> jobDelegate){
|
||||||
|
this.jobDelegate = jobDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void execute()
|
||||||
|
{
|
||||||
|
this.result = this.jobDelegate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Result {
|
||||||
|
get { return this.result; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using org.hwo.contracts;
|
||||||
|
|
||||||
|
namespace org.budnhead.tools
|
||||||
|
{
|
||||||
|
public static class ResourceLibrary
|
||||||
|
{
|
||||||
|
static Dictionary<Type,Dictionary<string,object>>
|
||||||
|
resourceTypes = new Dictionary<Type, Dictionary<string, object>>();
|
||||||
|
static List<string>
|
||||||
|
resourcePaths = new List<string>(new string[]{"."});
|
||||||
|
|
||||||
|
static Dictionary<Type,string> prefixes = new Dictionary<Type, string>();
|
||||||
|
static Dictionary<Type,string> suffixes = new Dictionary<Type, string>();
|
||||||
|
|
||||||
|
internal static bool initializeResourceType(Type t,string prefix,string suffix,bool initializeBases){
|
||||||
|
ConstructorInfo ci = null;
|
||||||
|
|
||||||
|
new BooleanConditional()
|
||||||
|
.requiresValid(ref ci,delegate { return t.GetConstructor(new Type[]{ typeof(Stream) }); })
|
||||||
|
.does( delegate { initializeResourceType(t,prefix,suffix); } );
|
||||||
|
|
||||||
|
if (initializeBases && (t.BaseType != null)){
|
||||||
|
initializeResourceType(t.BaseType,prefix,suffix,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
internal static bool initializeResourceType(Type t,string prefix,string suffix){
|
||||||
|
if (prefix != null)
|
||||||
|
prefixes.Add(t,prefix);
|
||||||
|
if (suffix != null)
|
||||||
|
suffixes.Add(t,suffix);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T findLoadedInstance<T>(string name){
|
||||||
|
if (resourceTypes.ContainsKey(typeof(T))){
|
||||||
|
if (resourceTypes[typeof(T)].ContainsKey(name)){
|
||||||
|
return (T)resourceTypes[typeof(T)][name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new KeyNotFoundException("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cacheInstance<T>(string name,T instance){
|
||||||
|
if (!resourceTypes.ContainsKey(typeof(T))){
|
||||||
|
resourceTypes.Add(typeof(T),new Dictionary<string, object>());
|
||||||
|
}
|
||||||
|
resourceTypes[typeof(T)].Add(name,instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T getResource<T>(string name){
|
||||||
|
try {
|
||||||
|
return findLoadedInstance<T>(name);
|
||||||
|
} catch (KeyNotFoundException){
|
||||||
|
string p="",s="";
|
||||||
|
|
||||||
|
if (prefixes.ContainsKey(typeof(T))){
|
||||||
|
p = prefixes[typeof(T)];
|
||||||
|
}
|
||||||
|
if (suffixes.ContainsKey(typeof(T))){
|
||||||
|
s = suffixes[typeof(T)];
|
||||||
|
}
|
||||||
|
|
||||||
|
string resFileName = FileHelper.findFile(String.Format("{0}{1}{2}",p,name,s),resourcePaths.ToArray());
|
||||||
|
if (resFileName != null){
|
||||||
|
Stream resStream = new FileStream(resFileName,FileMode.Open);
|
||||||
|
ConstructorInfo ci = typeof(T).GetConstructor(new Type[]{ typeof(Stream) });
|
||||||
|
T o = (T)ci.Invoke(new object[]{ resStream });
|
||||||
|
|
||||||
|
cacheInstance(name,o);
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
throw new KeyNotFoundException(String.Format("ResourceLibrary[{0}:{1}]",typeof(T).ToString(),name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public class Container : Control
|
||||||
|
{
|
||||||
|
private List<Control> children;
|
||||||
|
|
||||||
|
public Container()
|
||||||
|
{
|
||||||
|
this.children = new List<Control>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChild(Control control){
|
||||||
|
if (control.parent != null){
|
||||||
|
control.parent.removeChild(control);
|
||||||
|
}
|
||||||
|
this.children.Add(control);
|
||||||
|
}
|
||||||
|
public void removeChild(Control control){
|
||||||
|
this.children.Remove(control);
|
||||||
|
}
|
||||||
|
public Control[] Children {
|
||||||
|
get { return this.children.ToArray(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public class Control
|
||||||
|
{
|
||||||
|
internal Container parent;
|
||||||
|
|
||||||
|
public Control()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 Position { get; set; }
|
||||||
|
public Vector2 Size { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Container Parent {
|
||||||
|
get { return this.parent; }
|
||||||
|
set { if (value == null) { if (this.parent != null) this.parent.removeChild(this); } else { value.addChild(this); } }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public virtual void paint(){
|
||||||
|
paintBorder();
|
||||||
|
paintControl();
|
||||||
|
}
|
||||||
|
public virtual void paintBorder(){
|
||||||
|
}
|
||||||
|
public virtual void paintControl(){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using System;
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public enum ModifierKeys
|
||||||
|
{
|
||||||
|
NONE,SHIFT,CONTROL,COMMAND,WIN,CONTEXT
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using org.budnhead.graphics;
|
||||||
|
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public class SceneInScene : Control
|
||||||
|
{
|
||||||
|
Scene scene;
|
||||||
|
|
||||||
|
public SceneInScene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void paintControl()
|
||||||
|
{
|
||||||
|
if (scene != null){
|
||||||
|
|
||||||
|
// ToDo: Prepare Transformation Matrix and Clipping
|
||||||
|
// ... scene.draw();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public class KeyPressedEvent : UIEvent
|
||||||
|
{
|
||||||
|
public KeyPressedEvent(char keyChar,ModifierKeys modifierKeys)
|
||||||
|
{
|
||||||
|
KeyChar = keyChar;
|
||||||
|
Modifier = modifierKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char KeyChar { get; private set; }
|
||||||
|
public ModifierKeys Modifier { get; private set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
namespace org.budnhead
|
||||||
|
{
|
||||||
|
public class UIEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
public UIEvent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,13 +41,21 @@ namespace org.hwo.contracts
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conditional<T> assigns<AT>(ref AT target,assignDelegate<AT> assigner){
|
public Conditional<T> assigns<AT>(ref AT target,assignDelegate<AT> assigner) {
|
||||||
if (success){
|
if (success){
|
||||||
target = assigner();
|
target = assigner();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Conditional<T> requiresValid<AT>(ref AT target,assignDelegate<AT> assigner){
|
||||||
|
if (success){
|
||||||
|
target = assigner();
|
||||||
|
success = target != null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public bool isSuccess(){
|
public bool isSuccess(){
|
||||||
return this.success;
|
return this.success;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue