-
What is it?
NetEXT is a SFML.NET extension library that is designed to provide extension modules to SFML for CLI/CLR languages. It currently covers areas in graphics, particles and more (see the feature list below), but more is planned. The API is very close if not exactly the same as Thor so most examples can be ported directly from Thor to NetEXT.
Special Thanks
I want to thank Nexus (http://en.sfml-dev.org/forums/index.php?action=profile;u=361) for his Thor Library (http://en.sfml-dev.org/forums/index.php?topic=7329). NetEXT is a native C# port of Thor. And of course thanks to Laurent for SFML.
Licensing
NetEXT is licensed with the ZLIP/PNG, the license same as SFML and Thor. Go to town on it and write patches and other features and then make pull requests.
Current Features
- Large Texture/Sprite/RenderTexture classes
- Particle System complete with the ability to build custom Emitters/Affectors
- Animation Module that supports custom Animation classes
- Vector Math Module
- Time module providing different wrappers around the Clock class such as a Stopwatch
- Complete Input Module with customizable actions and callbacks
- Resource Manager Module
- Networking module [WIP] [BETA]
Planned Features
- Shape Module
- More math functions
Where do I get it?
You can get the full source code over on Bitbucket (https://bitbucket.org/zsbzsb/netext/overview). There is also a precompiled version available here (https://bitbucket.org/zsbzsb/netext/downloads) and here (http://www.zbrown.net/projects/netext/downloads).
Documentation
Documentation has now been written for NetEXT, at the moment there is no online version of it [coming soon], but for now just drop NetEXT into your object browser to read the documentation.
-
Very interesting project. Thank you for bringing the functionality to C# :)
I can add a link to your BitBucket site on the Thor download page (http://www.bromeon.ch/libraries/thor/download.html), in order to consider NetEXT an official port (even if it doesn't cover all/exactly the same features). If you keep the API similar, you can also link to the Thor documentation (http://www.bromeon.ch/libraries/thor/documentation.html) in your project, to avoid the massive duplication and maintenance.
In case you ever need help to understand the implementation or design decisions behind Thor, don't hesitate to contact me ;)
-
Update
I have now ported and pushed Thor's animation module to NetEXT. The animation example is also ported so try it out. :)
Very interesting project. Thank you for bringing the functionality to C# :)
No problem :D I finally decided that since the SFML.NET community was growing it was time to do a port.
I can add a link to your BitBucket site on the Thor download page (http://www.bromeon.ch/libraries/thor/download.html), in order to consider NetEXT an official port (even if it doesn't cover all/exactly the same features). If you keep the API similar, you can also link to the Thor documentation (http://www.bromeon.ch/libraries/thor/documentation.html) in your project, to avoid the massive duplication and maintenance.
That would be great if you would consider NetEXT an official port :) Currently the API is very similar except for a little variable renaming, the API signatures just about match exactly though (except in a few places where C# can't do what C++ can). As for the documentation, I will add a link to your documentation since I do not feel like writing my own ;)
In case you ever need help to understand the implementation or design decisions behind Thor, don't hesitate to contact me ;)
Of course, can't forget that particle system bug :D
-
Hello zsbzsb,
first, thank you for the c# port! :D
I may be wrong, but I have possible found a bug in the particlesystem AddAffector.
If I add more than one affector without parameter TimeTo Live (using only the constructor AddAffector(AffectorBase NewAffector) ), only the first affector is added because
_affector.Contains(affector) returns allways true.
public void AddAffector
(AffectorBase NewAffector,
long TimeToLive
) { TimeLink
<ExpiringTime, AffectorBase
> affector
= new TimeLink
<ExpiringTime, AffectorBase
>(new ExpiringTime
(TimeToLive
), NewAffector
); if (!_affectors
.Contains(affector
)) _affectors
.Add(affector
); }
I have also two questions:
- the math distributions is not implemented, right? So, I can not write something like
emitter.setParticlePosition( thor::Distributions::circle(center, radius) ); // Emit particles in given circle
- any plans to add the AnimationAffector ? :-)
-
I may be wrong, but I have possible found a bug in the particlesystem AddAffector.
If I add more than one affector without parameter TimeTo Live (using only the constructor AddAffector(AffectorBase NewAffector) ), only the first affector is added because
_affector.Contains(affector) returns allways true.
You are right, there was a bug. In the comparison check I was comparing the time value and the affector/emitter and returning true if either was the same.
I have also two questions:
- the math distributions is not implemented, right? So, I can not write something like
emitter.setParticlePosition( thor::Distributions::circle(center, radius) ); // Emit particles in given circle
Predefined distributions are not implemented yet, but it is planned. The distribution class however is implemented so it is possible for you to write your own circle functions. You can write that now ;)
UniversalEmitter emitter;
emitter.ParticlePosition = Distributions.Circle(center, radius);
- any plans to add the AnimationAffector ? :-)
Yes
Edit
I decided to go ahead and implement the predefined distributions and the AnimationAffector. It is all on Bitbucket so go download the latest :D
-
Man, you are quick. :D Thanks!
One question: didn't the constructors in class Distribution<ValueType> have to be public?
-
Man, you are quick. :D Thanks!
The implementation of those two things was fairly easy and straightforward. 8)
One question: didn't the constructors in class Distribution<ValueType> have to be public?
They are not public because there are implicit operators to create the Distribution<ValueType> object. After all it feels weird and makes code more unreadable to write something like this
Distribution
<string> stringvalue
= new Distribution
<string>("Hello There");
verses
Distribution<string> stringvalue = "Hello There";
I guess they could be public, but as I see it there is no need for them to be public. However, I will look into this and see how Thor handles it.
-
However, I will look into this and see how Thor handles it.
The constructors are public, but in C++ you can implicitly convert from other objects if a constructor is not explicit and can be called with one argument.
The implementation is a bit more complicated: To allow indirect conversions, such as const char[5] to std::string as in
thor::Distribution<std::string> s = "text";
, the constructor parameter is a template parameter.
In addition, I use SFINAE (through AURORA_ENABLE_IF) to find out whether a functor or a constant is passed ;)
-
The constructors are public, but in C++ you can implicitly convert from other objects if a constructor is not explicit and can be called with one argument.
Well in that case I will change the constructors of NetEXT's Distribution to public.
In addition, I use SFINAE (through AURORA_ENABLE_IF) to find out whether a functor or a constant is passed ;)
Well in my case whether it be a blessing or a curse, C# does not have the ability to pass by constants ::)
Also you should all download the latest version, measuring of time has been greatly improved and there have been several other bug fixes.
-
Hello!
Can someone give me a small example how to use AnimatedText ?
I can not find examples, neither at Thor nor NetExt :(
Thanks!
-
Hello!
Can someone give me a small example how to use AnimatedText ?
I can not find examples, neither at Thor nor NetExt :(
Thanks!
If you are talking about making text animations such as text flying in off the screen, showing letters one at a time, and so on your out of luck. You would need to design those animations yourself, the reason AnimatedText exists is to only allow Text objects to be applied to the animation module.
In Thor you don't need separate objects to apply animations to templates (C++ templates are compiled directly into the user code using the type provided). But in C# it is a bit different because I can't just call on functions/properties in C# with templates unless the generic type has been constrained to a base type. So in the end I wrote an abstract class that then takes care of calling the animated object's functions/properties. That is the reason there is an AnimatedBase, AnimatedText, AnimatedSprite, and so on.
This way you can apply animations to whatever object type you want by simply inheriting AnimatedBase and then calling the appropriate functions/properties on the type you want to animate.
-
Hello!
Can someone give me a small example how to use AnimatedText ?
I can not find examples, neither at Thor nor NetExt :(
Thanks!
If you are talking about making text animations such as text flying in off the screen, showing letters one at a time, and so on your out of luck. You would need to design those animations yourself, the reason AnimatedText exists is to only allow Text objects to be applied to the animation module.
Well, that was my intension. 8) ok, out of luck...and I went back to coding ::)
-
Alright, lots of stuff has been improved and finished since the initial release ;D
Mainly what has been completed is...
- Vector Module
- Input Module
- Time Module (includes Time and Clock classes that implement sf::Time and sf::Clock for easy handling of time)
Currently the Resources and Shapes modules are in progress :)
For anyone that is using it I highly recommend you upgrade to the latest edition ;)
-
You seem to be really fast, it looks like a large part of Thor has already been ported :)
Concerning resources, keep in mind that thor::ResourceCache is not meant to be a general-purpose resource management system, it is rather specific to the cases where 1. shared ownership is required and 2. duplicates shall be resolved automatically. Often, neither is necesssary, that's why I am going to implement a more lightweight alternative in the future. I don't know if it even makes sense to port thor::ResourceCache directly to C#, as the lifetime and object ownership model is completely different from C++ -- however, the latter was an important point when I designed the resource caches. You should ask yourself whether a C# implementation would relieve the user and allow resources to be handled in a generic way (e.g. thor::ResourceKey<R> can also be used independently), or if it would just make everything more abstract and complicated.
Concerning shapes, the classes thor::Arrow and thor::ConcaveShape can be considered more or less stable. Some functions in the thor::Shapes namespace however might be removed -- shapes like pies are nice to show shapes in action, but they're not particularly useful as a reusable component of the Thor library. I might put them directly into an example.
Just to keep that in mind, not that you have to perform useless refactoring later. In general, the progress list (http://www.bromeon.ch/libraries/thor/progress.html) gives a rough idea on what may still change in Thor ;)
-
Seems like you are developing something similiar to mine library: https://bitbucket.org/krzat/sfml.utils .
Feel free to pull some classes (unless the goal is only to port Thor).
-
I don't know if it even makes sense to port thor::ResourceCache directly to C#, as the lifetime and object ownership model is completely different from C++. You should ask yourself whether a C# implementation would relieve the user and allow resources to be handled in a generic way (e.g. thor::ResourceKey<R> can also be used independently), or if it would just make everything more abstract and complicated.
I have already been considering most of these points. The biggest point is the way the CLR handles objects, the automatic garbage collection will only collect objects when no references remain to them, this is essentially already the shared ownership model. The only reason to implement the resource module in C# would be to avoid duplicate loading of resources.
Seems like you are developing something similiar to mine library: https://bitbucket.org/krzat/sfml.utils .
Feel free to pull some classes (unless the goal is only to port Thor).
Good to know, my main goal at the moment is to only port Thor and keep a generic interface. But I will keep your library in mind in case I ever need anything ;)
-
Something important I forgot to mention: thor::ConcaveShape is based on a Constrained Delaunay Triangulation implemented in Thor.Math. It took me quite some time to implement and test this algorithm. It will be a huge effort to port the algorithm to C#, I do not recommend it.
I suggest that -- if you even want to provide ConcaveShape in NetEXT (I have the feeling it's not used very often in Thor) -- you should look for simpler triangulation algorithms, see here (https://en.wikipedia.org/wiki/Polygon_triangulation). Maybe the .NET framework can also help you, I don't know about its geometric capabilities.
-
Alright, I have now added a resource module to NetEXT. It is a much more simplified version of Thor's resource module that is more tailored to C#/CLI. The main point to this module is to avoid duplicate loading of resources.
Here is a sample of how to utilize this module.
// Create a ResourceCache<Texture> with predefined Texture constructors// Note: If you create a resource cache without the factory function you must provide constructors// that match the parameters that are passed in the Aquire(Key, Parameters) functionvar texturecache
= CacheFactory
.CreateTextureCache();// Gets a couple handle to a texture with "My Texture" string as the key// If the key doesn't exist then it will be loaded from ".\\image.jpg"var texturehandle
= texturecache
.Aquire("My Texture",
".\\image.jpg"); // Will load the texture// since it hasn't been loaded/cached yetvar secondhandle
= texturecache
.Aquire("My Texture",
".\\image.jpg"); // Will NOT load the// texture since we already cached it// Now create a sprite with the texture we just acquired// Note: All resource handles must be kept alive as long as the resource is being usedSprite sprite
= new Sprite
(texturehandle
); // Implicit conversion from// ResourceHandle<Texture> to Texture// Now do whatever you want, maybe draw the sprite to the screen
On a side note, I have also added a networking module that is based on SFNUL (http://en.sfml-dev.org/forums/index.php?topic=13723.0). Please note the networking module is a WIP and still has several issues, but I would be glad if anyone would like to try it out and report any issues they have.
Here is a sample of the networking module.
public class Coordinate
: SyncedObject
{ public SyncedInt X
= null; public SyncedInt Y
= null; public Coordinate
() { // Initialization order *must* remain the same X
= new SyncedInt
(200,
this, SynchronizationType
.Dynamic); Y
= new SyncedInt
(300,
this, SynchronizationType
.Dynamic); }}// ServerSynchronizerServer synchronizer
= new SynchronizerServer
();var coord
= synchronizer
.CreateObject<Coordinate
>();// ClientSynchronizerClient synchronizer
= new SynchronizerClient
();// Assuming everything is already setup and created// Servercoord
.X.Value = 45; // Yea still working on implicit conversion so the *.Value will not be neededcoord
.Y.Value = 6;// On the client we do nothing and the values are automatically updated
-
NetEXT 1.8 (https://bitbucket.org/zsbzsb/netext/commits/tag/1.8) Released
This is a big update including documentation for all modules. Oh and about the huge version number jump [there wasn't any before so technically I can start wherever 8)]. I am working on getting NetEXT version numbering synchronized with Thor, so considering Thor currently has 2.0 as the development version I am aiming to hit the same number when Thor 2.x is finally released. :)
- Particle system now includes support for multiple texture rects
- Refactored the input module, support has now been added for custom actions and joystick axis actions
- Refactored input module, it is no longer required to implement a proxy class for animations
- And lots of other minor tweaks to improve consistency/generic support
The biggest thing left to do at the moment is to finish the shape module and get the official site up with tutorials and documentation.
Documentation is not yet available online, but for now just plug an updated version of NetEXT into the object browser to read the documentation. Also any feedback from anyone is welcome on the documentation, even if you don't plan on using NetEXT I want to hear your opinions :D
-
Just a silly question. How do I use it? I have SFML.net installed and fully working but for this one I couldn't find any installation guides. Do I just throw it in there with the SFML-files - and what next? The readme-file was just about the licensing. How about making a step-by-step guide for the newbies :)
-
Sorry for the late reply, I was out of the country. Yes I am working on getting some tutorials (http://zbrown.net/projects/netext/tutorials/) created. Right now there is a tutorial for building NetEXT only. After you build NetEXT the only thing left to do is add the NetEXT dll as a reference to your project (same as adding the SFML dlls as references). ;)
-
hmm this should be useful. Going to be working on a space shooter with a huge range to move about so can't have the player getting bored with my programmer art. :P Keep up the good work too. :)
-
Just curious did you compile for VS 2013 or 2012? Since I'm using 2012. ???
-
Compiler version makes no difference when it comes to managed assemblies (unlike when dealing with C++ libraries). Instead you should pay attention to which version of the .NET framework that it builds with. NetEXT will work with .NET Framework 4 Client Profile or greater (4.5 and 4.5.1). ;)
-
OK just checking. :)
-
You're missing two vector math equations that could be useful.
One for changing a vector into an angle and another for changing an angle into a vector.
Chances are I missed something in these two equations so make any changes you have to. :)
public static double VectorToAngle
(double x,
double y
) { double angle
= ToDegrees
(Math
.Atan2(y,x
)); double realangle
= (angle
% 360); return realangle
;}public static double VectorToAngle
(Vector2f vector
) { return VectorToAngle
(vector
.X,vector
.Y);}public static double[] AngleToVector
(double degreesangle
) { double[] newvector
= new double[2]; newvector
[0] = Math
.Cos(ToRadians
(angle
% 360)); newvector
[1] = Math
.Sin(ToRadians
(angle
% 360)); return newvector
;}public static Vector2f AngleToVectorSFML
(double degreesangle
) { double[] newvector
= AngleToVector
(degreesangle
); return new Vector2f
((float)newvector
[0],
(float)newvector
[1]);}
I did see the rotate method in there but what you seem to be missing is just straight conversion between vector and angle. Unless I'm blind and missed it. ???
-
PolarVector struct and PolarAngle functions is what you are looking for. ;)
-
lol oops. :-[ :)
-
zsbzsb your UnitVector code has an error. What happens when len becomes 0 or rounds to it somehow? :) Divide by 0 exception and the dang thing doesn't gripe either too. ??? Had the same error in my normalization code too and didn't notice it until I started dismantling it. :(
public static Vector2f normallizedVector2(Vector2f vec)
{
float mag = (float)VectorMagnitude(vec);
if (Math.Abs(mag) > Math.Abs(0) || (vec.X != 0 && vec.Y != 0))
{
return vec / mag; //needs check for divide by 0 error or it'll return new Vector2f(NaN,NaN)
}
else
{
return vec;
}
}
Hope this helps. :D
-
Alright thanks for that, I added assertions so now invalid vectors in debug configuration will throw an error. ;)
I also pushed a few other small changes. :)
-
if (Math.Abs(mag) > Math.Abs(0) || (vec.X != 0 && vec.Y != 0))
What's the purpose of this double-check? How could X and Y be both non-zero if the length of the vector is zero? And do you really expect Math.Abs(0) to do something useful? :P
public static Vector2f normalizedVector2(Vector2f vec)
{
float mag = VectorMagnitude(vec);
return mag != 0 ? vec / mag : vec;
}
I added assertions so now invalid vectors in debug configuration will throw an error
I think returning the zero vector in this case would be more natural than throwing an error. A vector with zero length is valid, it's just a special case to handle.
-
I think returning the zero vector in this case would be more natural than throwing an error. A vector with zero length is valid, it's just a special case to handle.
Hmmm, I would like to know what Nexus thinks of this. I am open to change, but when I implemented the assertions I was following Thor's implementation (https://github.com/Bromeon/Thor/blob/master/include/Thor/Vectors/Detail/VectorAlgebra2D.inl#L51). Personally I haven't done enough math dealing with vectors to know the best way to handle this.
-
I think returning the zero vector in this case would be more natural than throwing an error. A vector with zero length is valid, it's just a special case to handle.
My point of view here is that UnitVector() claims to return a vector of unit length. If it doesn't, that's a violation of the method's postcondition. Analoguously, a vector of length zero is not a valid input -- you cannot compute the unit vector of a zero vector. Same thing if you compute the polar angle. In otherwords, the precondition is a non-zero vector argument, and Thor explicitly states that in the documentation.
I'm personally not a fan of hiding logic errors like this; if the user wants to handle zero vectors differently, he should do so explicitly. The nice side effect is that users who really want to compute a unit vector don't pay for a useless if statement.
-
if (Math.Abs(mag) > Math.Abs(0) || (vec.X != 0 && vec.Y != 0))
What's the purpose of this double-check? How could X and Y be both non-zero if the length of the vector is zero? And do you really expect Math.Abs(0) to do something useful? :P
lol Brain fart on my end. For some reason went for double check when I didn't have to. XD
I think returning the zero vector in this case would be more natural than throwing an error. A vector with zero length is valid, it's just a special case to handle.
My point of view here is that UnitVector() claims to return a vector of unit length. If it doesn't, that's a violation of the method's postcondition. Analoguously, a vector of length zero is not a valid input -- you cannot compute the unit vector of a zero vector. Same thing if you compute the polar angle. In otherwords, the precondition is a non-zero vector argument, and Thor explicitly states that in the documentation.
I'm personally not a fan of hiding logic errors like this; if the user wants to handle zero vectors differently, he should do so explicitly. The nice side effect is that users who really want to compute a unit vector don't pay for a useless if statement.
Sometimes throwing an error is good other times like when doing AI calculations it can be annoying so I went for just returning the passed vector without doing anything to it since it won't crash me when I don't want it to. :) Although yes I'm not much of a fan of hiding errors like this either when they shouldn't be hidden. :D
-
If I use string as the Key for a TextureCache, it randomly gets freed? How can I use resources properly?
-
If I use string as the Key for a TextureCache, it randomly gets freed?
What do you mean by randomly freed? If you think there is an issue I need a complete and minimal code example to test with.
How can I use resources properly?
There is an example in the source code for you to look at.
-
Hey there. Thank for this, but I can't build it.
It rants about this:
Error 1 The type or namespace name 'System' does not exist in the namespace 'SFML' (are you missing an assembly reference?) D:\GameMaking\NetEXT\NetEXT\TimeFunctions\Stopwatch.cs 2 12 NetEXT
With loads of errors like this.
And these warnings:
Warning 49 'NetEXT.Particles.ParticleSystem.ExpiringTime' overrides Object.Equals(object o) but does not override Object.GetHashCode() D:\GameMaking\NetEXT\NetEXT\Particles\ParticleSystem.cs 281 23 NetEXT
Warning 55 'NetEXT.Particles.ParticleSystem.TimeLink<TimeType,ValueType>' overrides Object.Equals(object o) but does not override Object.GetHashCode() D:\GameMaking\NetEXT\NetEXT\Particles\ParticleSystem.cs 328 23 NetEXT
I want to build a 64bit version, because I downloaded the .dll present and apparently it is not 64bit.
Am I being dense, or some compatibility somewhere lurks in my vicinity?
-
NetEXT has been updated to work with the latest SFML.NET version (the soon to be released 2.2 version). So you will need to download and compile the latest SFML.NET and grab the latest nightly builds of CSFML from here (http://www.nightlybuilds.ch) (or compile it yourself). As for the warnings, you can safely ignore them.
-
Hello, was just wondering if this even needed to be updated from the 2.2 release? :)
-
Is this library still in active development?