{"id":277,"date":"2011-12-27T03:44:00","date_gmt":"2011-12-27T09:44:00","guid":{"rendered":"http:\/\/elysianshadows.com\/2011\/12\/tile-flip-and-rotate-entity-vs-terrain-collision-and-property-editor\/"},"modified":"2011-12-27T03:44:00","modified_gmt":"2011-12-27T09:44:00","slug":"tile-flip-and-rotate-entity-vs-terrain-collision-and-property-editor","status":"publish","type":"post","link":"http:\/\/elysianshadows.com\/updates\/tile-flip-and-rotate-entity-vs-terrain-collision-and-property-editor\/","title":{"rendered":"Tile Flip and Rotate, Entity vs Terrain Collision, and Property Editor"},"content":{"rendered":"\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Yeah, I guess I should have said Merry Christmas and all that too&#8230; Unfortunately mine was completely ruined this year by a certain bitch. Hope all of you had far better holidays.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[b]Big-Picture Goals[\/b]:<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">First of all, I am not working on the Toolkit to work on the Toolkit. My development this last month began with the Engine. I made a considerable amount of progress and was finally able to implement some long-awaited features for artists. Unfortunately these features must also be implemented in the Toolkit before I can even begin testing in the Engine&#8230; so that&#8217;s why I have once again returned to the land of QT.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[u]Tile Flipping and Rotating[\/u]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">has actually been implemented within the engine, FINALLY. I am VERY pleased with with my implementation. Believe it or not, since this data effects the entire map, it could potentially have serious implications on Area sizes within the engine&#8230; I devised a solution that would require a single extra byte per tile location (represented as uint16 now, rather than unsigned char), and would not break any existing levels. I have done this by using 3 of the 8 new bits to represent tile orientation flags. These flags are implemented per-platform at the LibGyro level:<\/p>\n<pre>typedef enum _GY_RECT_TEX_ORIENT { GY_RECT_TEX_ORIENT_NORMAL, GY_RECT_TEX_ORIENT_FLIP_HORIZ, GY_RECT_TEX_ORIENT_FLIP_VERT, GY_RECT_TEX_ORIENT_ROT_90, GY_RECT_TEX_ORIENT_ROT_180, GY_RECT_TEX_ORIENT_ROT_270 } GY_RECT_TEX_ORIENT; <\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">These flags may now be used with the LibGyro Rect API to tell libGyro how to orient the texture coordinates of the following rect:<\/p>\n<pre>void gyVidRectListBegin(const GYColor4 *const color); void gyVidRectListEnd(void); void gyVidRectTexOrient(const GY_RECT_TEX_ORIENT orient); void gyVidRect(const unsigned int frame);  <\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">From an application standpoint, with a little bit of crazy C-style bit manipulation and unsafe enumeration casting, we arrive at a pristine solution that is both quick and memory efficient.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[i]Object-layer rendering loop. Notice the call to gyVidRectTexOrient[\/i]<\/p>\n<pre>gyVidTexBind(_curLevel-&gt;objectsheet); gyVidRectListBegin(&amp;terrainColor); for(unsigned j = startY; j &lt;= endY; ++j) { \tfor(unsigned i = startX; i &lt;= endX; ++i) { \t\tif(_curArea-&gt;objectLayer[0][j] != 0) { \t\t\tgyMatPush(); \t\t\tgyMatTranslateScale(i*32.0f, j*32.0f, ELYSIAN_ZCOORD_OBJECT1, 32.0f, 32.0f, 1.0f); \t\t\tgyVidRectTexOrient((GY_RECT_TEX_ORIENT)((_curArea-&gt;tileLayer[0][j]&gt;&gt;8) &amp; 0x0007)); \t\t\tgyMatPop(); \t\t\t++_renderCount; \t\t} \t\tif(_curArea-&gt;objectLayer[1][j] != 0) { \t\t\tgyMatPush(); \t\t\tgyMatTranslateScale(i*32.0f, j*32.0f, ELYSIAN_ZCOORD_OBJECT2, 32.0f, 32.0f, 1.0f); \t\t\tgyVidRectTexOrient((GY_RECT_TEX_ORIENT)((_curArea-&gt;tileLayer[0][j]&gt;&gt;8) &amp; 0x0007)); \t\t\tgyMatPop(); \t\t\t++_renderCount; \t\t} \t} } gyVidRectListEnd(); <\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">And of course, since the existing levels did not have any special orientation, those bits will be 0, which will map into the first enumeration of NORMAL&#8230; So we haven&#8217;t broken anything. \ud83d\ude00<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[u]Entity vs Terrain Collision[\/u]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">I am well aware of how ridiculously long this has taken to fucking implement. You can blame it all my overly ambitious plan for our physics engine&#8230; Not only do we need to efficiently check for OBB vs OBB collision between free-standing entities, but we also had to devise an algorithm to check each AABB\/OOBB against its neighboring terrain tiles&#8230; This has proven to be suuuch a pain in the ass. I have two moderately complex ideas that I&#8217;m toying with. The basic algorithm is complete, but I am unable to do serious testing until I am able to lay tile solidity within the Toolkit&#8230; hence I&#8217;ve had to drop the engine and implement it in the Toolkit before further development.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\"><img decoding=\"async\" src=\"http:\/\/www.elysianshadows.com\/random\/terrainCol.png\" border=\"0\" alt=\"\" \/><\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[i]My work so far on Entity vs Terrain collision. Shit works, but I need a better test bed with the Toolkit&#8230;[\/i]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[b]Toolkit Development and Achieving My Fucking Goals[\/b]:<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[u]Unfucked toolkit_debug.txt[\/u]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">I actually didn&#8217;t realize that I had fucked it up so badly&#8230; but good ol&#8217; Jarrod pointed out the fact. It was because I was constructing\/initializing an ofstream object at static\/global scope before the rest of the C++ standard library&#8230; fixed. It should be logging pristinely.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[u]Big Ass Surprise[\/u]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">In order to implement terrain collision, I had to implement some mechanism for displaying\/editing tile\/object attributes. I realized that &#8220;Entity View&#8221; could be greatly improved upon. Since Entity is no longer the only type of object that can be selected (you can now select terrain), I have opted to change &#8220;Component View&#8221; to &#8220;Selection View.&#8221;<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Selection view will now be a property editor for any &#8220;Selectable.&#8221;<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[list][*] Entities<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[*] Terrain<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[*] Projects<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[*] Levels<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[*] Areas[\/list]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">One of the biggest issues that I have always had with the &#8220;Entity\/Component&#8221; view has been the nonorthogonality of its widgets&#8230; I have had to hand-code each and every &#8220;widget&#8221; for the attributes&#8230;&nbsp;<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Borrowing from both Unity3D and QT Designer, I have devised a new &#8220;Property Editor&#8221; for use with the Toolkit. I am far from done with it, but I have implemented some basic functionality. I will be slowly converting all of the Entity stuff to use this paradigm&#8230;<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[i]&#8212;&#8212;&#8212;&#8211; If you don&#8217;t give a shit about code, PLEASE skip this part, because it&#8217;s pretty advanced &#8212;&#8212;&#8212;-[\/i]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[u]PropertyStackModel[\/u]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Borrowing heavily from my Debug Log, I have opted to make our property editor &#8220;Stack based&#8221; as well. I came to a profound realization the other day that using an internal stack is the best EVER way to populate a tree&#8230;<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">The PropertyStackModel inherits from QT&#8217;s QStandardItemModel. It extends QT&#8217;s model through a stack API and gives you access to convenience functions for adding labels and properties to the model with a single line:<\/p>\n<pre>class PropertyStackModel: public QStandardItemModel { \tprivate: \t\tstatic bool _staticInit; \t\tstatic void _StaticConstructor(void); \t\t  \t\tstatic QColor _bgRowColor[PROPERTY_STACK_MODEL_COLOR_DEPTH][2]; \t\t  \t\tQStandardItem *_curParent; \tpublic: \t\t  \t\tPropertyStackModel(QObject *parent=0); \t\t  \t\tvirtual QVariant data(const QModelIndex &amp;index, int role) const; \t\tvirtual void PopulateModel(void)=0; \t\tvoid ClearStack(void); \t\tvoid InsertHeaders(void); \t\t \t\tvoid PushLabel(const QString label); \t\tvoid PopLabel(void); \t\t \t\tvoid AddProperty(const QString name, QStandardItem *const item); }; <\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">That&#8217;s cute and everything&#8230; but there&#8217;s still a HUGE problem. QT&#8217;s QStandardModel is populated with QStandardItem objects, each encapsulating its own piece of data and exposing get\/set functions. So how the fuck do we pull that off? 99% of our data in the Toolkit is in the elysian:: namespace from the Engine. It cannot be encapsulated by QT datatypes, because there is no QT within the engine&#8230; So how the fuck do we keep our data in-synch between these abstract &#8220;model items&#8221; and the actual elysian:: AssetIO data?<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Well, bitches, after many hours of pondering this predicament, the solution presented itself in probably one of the most useful and powerful applications that I have ever coded with C++ templates&#8230; Rather than encapsulating the data within the QT items, I devised a class template to tie the item&#8217;s get\/set functions to the engine&#8217;s get\/set functions&#8230; [i]I give you the PropertyStandardItem[\/i] class template:<\/p>\n<pre>template <typename t=\"\" typename=\"\" c=\"\"> class PropertyStandardItem: public QStandardItem { \tprivate: \t\tC *const _objInst; \t\tT (C::*const _getAccessor)(void) const; \t\tvoid (C::*const _setAccessor)(const T); \tpublic: \t\tPropertyStandardItem(C *const object, T (C::*const get)(void)const, void (C::*const set)(const T)=NULL): \t\t_objInst(object), _getAccessor(get), _setAccessor(set) { \t\t  \t\t\tsetFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | ((_setAccessor)? Qt::ItemIsEditable : Qt::NoItemFlags)); \t\t  \t\t} \t\t  \t\tvirtual int type(void) const { return QStandardItem::UserType; } \t\t  \t\tvirtual QVariant data(int role) const { \t\t\tswitch((Qt::ItemDataRole)role) { \t\t\t\tcase Qt::DisplayRole: \t\t\t\tcase Qt::EditRole: \t\t\t\t\treturn (_objInst-&gt;*_getAccessor)(); \t\t\t\tdefault: \t\t\t\t\treturn QStandardItem::data(role); \t\t\t} \t\t} \t\t  \t\tvirtual void setData(const QVariant &amp;value, int role) { \t\t\tswitch((Qt::ItemDataRole)role) { \t\t\t\tcase Qt::DisplayRole: \t\t\t\tcase Qt::EditRole: \t\t\t\t\t(_objInst-&gt;*_setAccessor)(value.value<t>()); \t\t\t\tdefault: \t\t\t\t\treturn QStandardItem::setData(value, role); \t\t\t} \t\t} }; <\/t><\/typename><\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">When instantiated, this template dynamically inherits from QStandardItem and accepts both a get\/set callback pointer-to-member function for the actual data. It does not store the data, rather it references it through existing accessor methods.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">This class template also automagically sets properties lacking a set function to read-only (via the default argument of NULL for the set function).<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">So here is a very rough implementation of the Area model using this paradigm. You can at least notice that it&#8217;s super pretty and takes almost no time at all. Everything is handled automatically by the stack and template:<\/p>\n<pre>void Area::PopulateModel(void) { \tClearStack(); \t  \tInsertHeaders(); \t  \tPushLabel(\"Area\"); \t\tAddProperty(\"name\", new PropertyStandardItem&lt;QString, Area&gt;(this, &amp;Area::getName, &amp;Area::setName)); \t\tAddProperty(\"path\", new PropertyStandardItem&lt;QString, Area&gt;(this, &amp;Area::getLocation)); \t\tPushLabel(\"size\"); \t\t\tAddProperty(\"width\", new PropertyStandardItem<unsigned short=\"\" area=\"\">(this, &amp;Area::getMapWidth, &amp;Area::setMapWidth)); \t\t\tAddProperty(\"height\", new PropertyStandardItem<unsigned short=\"\" area=\"\">(this, &amp;Area::getMapHeight, &amp;Area::setMapHeight)); \t\tPopLabel(); \tPopLabel(); } <\/unsigned><\/unsigned><\/pre>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[i]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- Continue Reading After Here &nbsp;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;[\/i]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">And here is the result:<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\"><img decoding=\"async\" src=\"http:\/\/www.elysianshadows.com\/random\/propertyEditor.png\" border=\"0\" alt=\"\" \/><\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">EDIT: The orange background was just me flexing my dick at you&#8230; just wanted to show that I could still modify QT&#8217;s item properties easily with the class template.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">I&#8217;m sure that this will 1) save us a SHITLOAD of time from having to handcode widgets and 2) make our Toolkit look more professional, because the look of each selectable is consistent with the new property editor.<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">[b]So Now What?[\/b]<\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">The main portion of this question will be answered by Tyler&#8217;s impending post. Jarrod, I would like for me and you to compile a list of must-haves before the next Toolkit release. I would like for you to begin working on bug-fixes and other features while I finish these babies up. Hopefully after this, we&#8217;ll be able to meet up, get everything stable, and release the Toolkit, the video, and the site. As I have said before, I am ready to get back on my own level. I&#8217;m out for blood, bitches, and the sooner I&#8217;m on Youtube, the sooner my thirst will be quenched. \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\"><strong>Originally posted in our Private Development forums on 12.27.11.<\/strong><\/p>\n<p style=\"color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15px;\">Anyway, we have spent a considerable amount of time discussing getting the video and project back on track. I will let Tyler post the details. For now, I&#8217;m providing an update on my own development throughout the holidays. At very least, this will hopefully ensure that Jarrod and I are on the same page.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-277","post","type-post","status-publish","format-standard","hentry","category-underlying-technology"],"_links":{"self":[{"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/posts\/277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/comments?post=277"}],"version-history":[{"count":0,"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/posts\/277\/revisions"}],"wp:attachment":[{"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/media?parent=277"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/categories?post=277"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/elysianshadows.com\/updates\/wp-json\/wp\/v2\/tags?post=277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}