Jump to content

  • Log In with Google      Sign In   
  • Create Account

Waterlimon

Member Since 28 May 2011
Offline Last Active Yesterday, 04:33 PM

Topics I've Started

Generating many configurations of a class at compile time

30 December 2015 - 11:42 AM

Basically I have my game world class with its various components and whatnot.

 

Now, there are some features that cannot be cleanly separated into distinct classes without ridiculous amounts of boilerplate:

-Rendering

-Networking

 

(code snippets and additional state everywhere - with pure templates managing this would mean ridiculous amounts of extra classes/funcs wrapped in template magic)

 

While waiting for static_if, I found the following approach online:

 

object.h:

#once
template<bool FeatureA, bool FeatureB>
class Object;
{
}
//generate all specializations with preprocessor
#define F_A true
#define F_B true
#include "ObjectTemplate.h"
#define F_A false
#define F_B true
#include "ObjectTemplate.h"
#define F_A true
#define F_B false
#include "ObjectTemplate.h"
#define F_A false
#define F_B false
#include "ObjectTemplate.h"

ObjectTemplate.h:

template<>
class Object<F_A,F_B>
{
#if F_A
  int a;
#endif

#if F_B
  int b;
#endif

  int someFunc()
  {
#if F_A && F_B
    return a + b;
#elif F_A
    return a + 5;
#elif F_B
    return b;
#endif
    return 0;
  }
}

The result is a template (the preprocessor usage is encapsulated within this software component). So I dont get the issues with "globality" that would come with straight up using some COMPILING_SERVER define or such.

 

Anyone see any glaring flaws with this approach?

 

EDIT:

Intellisense seems to hate it which is to be expected I guess... Just me being silly and instantiating with params I didnt specialize for


Rasterizing triangle in 3D

09 September 2015 - 07:35 PM

TFoxJKY.png

 

So I made a thing to rasterize the N dimensional features of N dimensional euclidean simplices (I need to, uh, check which chunks are within the rectangular region seen by camera...rolleyes.gif )

 

Such as this rasterization of the 2-simplices that make up a 4-simplex (hehe fancy words) without the issue (bit blocky tho):

roNqdPK.png

 

Given that its something I wrote late at evening, doing the extension to N dimensions myself (I try to templatize my code), without examples I could find, Im surprised it works reasonably well in most cases.

 

The above image is a triangle rasterized into a voxel grid. Points A, B are at same height, point C is much lower.

 

 

 

However, as you can see, theres an issue with filling triangles (sometimes). Usually theres no holes like above, but in those cases the triangle face - although filled - is a bit blocky too.

 

The above triangle is filled by, for each horizontal slice, finding intersection points with the lines AB and AC, and using bresenham to draw a line between them. The red lines represent this. (note : since the triangle is tall, each red line is more like 3 rasterized lines with same endpoint on X,Z plane where Y is height like (0,0,0) (0,1,0) (0,2,0))

 

It is clear that this method wouldnt work even in 2D.

 

In 2D, you would want the red lines to be axis aligned.

 

I COULD change the axis on which I iterate through the triangle, but the issue would then just happen in another dimension.

 

 

So - since it is impossible for the lines to be axis-aligned, how is one supposed to rasterize a triangle in 3D, avoiding holes?

 

Obviously I can completely change approach and do something like for each voxel check if its contained in the shape, but Im interested whether something similar to this particular approach exists - without the flaw.

 

EDIT:

I guess this might fit math/physics or maybe graphics section better...?

 

EDIT2:

Hmm maybe I can replace Bresenham's with a line drawin algorithm that generates ALL pixels that are intersected by the line (instead of being restricted to one pixel for each unit interval on the main axis)


Initializer_list isnt working...?

28 August 2015 - 04:07 AM

math::Vec2f Font::getLineVerticalBounds() const
		{
			FT_Face face = reinterpret_cast<FT_Face>(mFace);
			return math::Vec2f{ static_cast<float>(face->size->metrics.descender) / 64.0f, static_cast<float>(face->size->metrics.ascender) / 64.0f };
		}

See the "math::Vec2f" right after the return statement?

 

If it IS there, this works.

 

If it IS NOT there, a default initialized vector is returned (0,0) (or garbage that happens to be close to 0 idk) where something like (-9,3) is expected.

 

Here is the initializer_list constructor thingy:

template<class VecType, ui32 ComCnt>
		template<typename T>
		Vector<VecType, ComCnt>::Vector(std::initializer_list<T> values)
		{
			assert(values.size() <= ComCnt);
			auto iter = values.begin();
			for (ui32 i = 0; i < values.size(); ++i) //I checked that size is always 2
			{
				(*this)[i] = static_cast<VecType>(*(iter++));
			}
		}

In debug mode, that initializer_list contains garbage (claims to have 12 elements and all are rubbish)

 

In release mode its harder to debug.

 

AND the funny thing is, if I turn optimization off, it works just fine. Sure it STILL returns absolute garbage, but it works...?

 

 

Spent the whole day trying to figure out why my FPS indicator magically disappears in release mode with optimizations enabled >.<

 

Is it even legal to return the arguments wrapped in {} and then having the returned object construct itself from that? I just realized this works fine without the second piece of code being present. edit: I mean legal with the initializer_list based constructor


Internal error in ms compiler

30 June 2015 - 11:27 PM

2>  Running Code Analysis for C/C++...
2>c:\users\waterlimon\documents\coopsurvivalgit\engine\src\Callback.h(29): fatal error C1001: An internal error has occurred in the compiler.
2>  (compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\yyaction.cpp', line 4860)
2>   To work around this problem, try simplifying or changing the program near the locations listed above.
2>  Please choose the Technical Support command on the Visual C++ 
2>   Help menu, or open the Technical Support help file for more information
2>          ..\..\Src\Game.cpp(30) : see reference to function template instantiation 'void wle::data::CallbackBase<void,wle::io::Window &,const wle::io::ButtonEvent &>::connectMemberFunction<game::Game,void game::Game::OnButtonEvent(wle::io::Window &,const wle::io::ButtonEvent &)>(ClassT *)' being compiled
2>          with
2>          [
2>              ClassT=game::Game
2>          ]
2>          ..\..\Src\Game.cpp(143) : see reference to function template instantiation 'void wle::data::CallbackBase<void,wle::io::Window &,const wle::io::ButtonEvent &>::connectMemberFunction<game::Game,void game::Game::OnButtonEvent(wle::io::Window &,const wle::io::ButtonEvent &)>(ClassT *)' being compiled
2>          with
2>          [
2>              ClassT=game::Game
2>          ]
2>c1xxast : fatal error C1001: An internal error has occurred in the compiler.
2>  (compiler file 'msc1ast.cpp', line 1325)
2>   To work around this problem, try simplifying or changing the program near the locations listed above.
2>  Please choose the Technical Support command on the Visual C++ 
2>   Help menu, or open the Technical Support help file for more information
2>

Well it looks likes theres two internal errors but whatever.

 

It compiles fine.

 

The line it complains about (29) is in a method in a class that looks like (removed some unrelevant stuff):

template<typename ReturnT, typename... ParamT>
class CallbackBase
{
	//Member func as free function
	typedef ReturnT(*MFuncT)(void*, ParamT...);
	//free function
	typedef ReturnT(*FuncT)(ParamT...);
public:
	template<typename ClassT, ReturnT(ClassT::*memberFunc)(ParamT...)>
	void connectMemberFunction(ClassT* object)
	{
		mObject = object;
                //THE FOLLOWING LINE CAUSES INTERNAL COMPILATOR CRASHERROR IN MICROSOFT OPTIMIZING COMPILER .exe
		mMemberFunction = &memberFunctionPtrAsFreeFunction < ClassT, decltype(memberFunc), memberFunc, ParamT... > ;
	}
protected:
	template<typename ClassT, typename MemberFuncT, MemberFuncT memberFunc, typename... SuppliedParamT>
	static ReturnT memberFunctionPtrAsFreeFunction(void* object, SuppliedParamT... params)
	{
		return (static_cast<ClassT*>(object)->*memberFunc)(params...);
	}
	void* mObject = nullptr;
	union
	{
		MFuncT mMemberFunction;
		FuncT mFunction;
	};
};

I mean Im just declaring a template class template method that sets a pointer to a static template method parametrized by a template parameter, the type of a member function pointer template parameter dependent on the first one, the value of that member function pointer template parameter, and an unpacked variadic template parameter list. How on earth could that hit some rarely visited and thus poorly tested corner in the compiler while running static analysis with 64 bit compile target?

 

EDIT: VS 2013 community edition, and compiles/runs fine


Avoid rewriting type to access member typedef

29 June 2015 - 01:16 PM

I often find myself doing something like

some::name::space::Foo<Bar> test;
some::name::space::Foo<Bar>::SomeTypedef stuff = test.hi();

Now obviously I dont want to retype the type... In this specific case I could just use 'auto' but this is just an example (maybe I need the type to pass it as a template parameter to a vector or whatever).

 

Id like to do

some::name::space::Foo<Bar> test;
test::SomeTypedef stuff = test.hi();

But thats ILLEGAL sad.png

 

Is typedef the only way to do this in C++ (apart from duplication)? (Its fine for many uses of the type, but if I use the type like twice, writing out the typedef just feels like it takes even more work)

 

EDIT:

This would save at least a few keystrokes and eliminate the need to move stuff around, yay!  But its only worth it if theres multiple places where the behavior is needed because ill need to #include the header with the macro T_T

#define WITH_ALIAS(type, alias) typedef type alias; type

//Rarely do macros, dont know if that even works xD EDIT2: seems to...

WITH_ALIAS(some::name::space::Foo<Bar>, fubar) test;
test::SomeTypedef stuff = test.hi();

PARTNERS