Announcement

Collapse
No announcement yet.

WorldSpawn official WIP thread

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Oh man, I am stupid. What I said before about bytes is correct but, that wasn't the real problem with wad/miptexes. The problem was, I lost just enough scope not to realize that I had already set the colors from the palette in the stored mipstream and when I go to pull that saved mipstream from the library I was setting the colors again. It's "funny" how when you stop doing the wrong thing stuff starts working all-of-a-sudden.

    I'm not sad that I re-rewrote this part. haxe.io.Bytes is available on all platforms and it's as low as I can go among the APIs. ie... other APIs are extending haxe.io.Bytes, including openfl.utils.ByteArray (in one way or another, but also poorly). I like that my code is now working on the most base level it can.

    EDIT: Actually, I need to reverse that. Storing mipstreams in the library with the palette already applied will just make it 10 times more complicating to get it into a wad. I bet I already realized that and simply forgot to go to the wad class to make the change...and now I just got rid of the very thing I was trying to do... It's all good we're talking about half a line of code.
    Last edited by MadGypsy; 11-23-2016, 07:35 PM.
    http://www.nextgenquake.com

    Comment


    • mipping via pixel skipping


      mipping via scale


      In regards to the scale mipping, I believe the reason it is adding a little gray is due to pixel in pixel shading. In other words, if your lines do not exactly fill all the pixels they occupy, when it gets scaled down an "average" is made. This is "built in" as I am not telling it to do anything like that. It's also probably impossible to stop because even if you do perfectly fill pixels on the main mip it doesn't mean the sub mips will be scaled pixel perfect. I could try BitmapData.drawWithQuality but I actually expect that to give me worse results as quality will attempt to keep the pixel-in-pixel shading. I actually need BitmapData.drawWithShitty or summin like that.
      http://www.nextgenquake.com

      Comment


      • removed right and bottom clipping for pixel skipping method.


        for comparison, my scale method always did this...and a bit cleaner
        Last edited by MadGypsy; 11-24-2016, 05:26 PM.
        http://www.nextgenquake.com

        Comment


        • Yes, scaling looks more precise than pixel skipping but in my special case, tonal fidelity is more important than structural fidelity. Of course, if I could draw on the submips I could go with scaling and then correct the bad pixels by hand, thus having the best possible result, but you ruled that out as a possibility.
          ♪ I'm skiiiiiiinnin' in the pain, just skiiiiiiinnin' in the pain ♪
          ♪ What a glorious feelin' I'm haaaaaaappy again ♪

          Comment


          • @but you ruled that out as a possibility.

            You've mentioned this numerous times. I get it, you want to draw on pictures. I can't give you stuff that doesn't exist, and to make that possibility exist would be a hell of a lot of work. Color Picker, Drawing Tools, Canvas, Ruler, Grid...more. There is a lot more to drawing then telling some pixel to be a color.
            http://www.nextgenquake.com

            Comment


            • Yes, I realize that and I'm not asking you to go there just for lil' old me, it's already awesome that you're willing to strip this tool from your engine for me. I suspect, however, that should you decide to implement a submip editor functionality, the mapping community would be very interested in it (there's at least one other person who asked for something like that just a few days ago at Func_). I agree that your engine should remain your priority but when the rewrite is done, maybe consider the possibility for a future update?
              ♪ I'm skiiiiiiinnin' in the pain, just skiiiiiiinnin' in the pain ♪
              ♪ What a glorious feelin' I'm haaaaaaappy again ♪

              Comment


              • I'm currently rewriting my math expression parser and boy is it tough. Regular Expressions are utilized completely different in Haxe. I've been good at not using my other stuff as reference too much on this rewrite but, in this case I couldn't use the old stuff as much of a reference even if I wanted to.

                My expression parser relies heavily and almost entirely on the ability to get results out of a regex match. Getting these results in Haxe is substantially harder than the flash way. I may even be cheating but, I have read the entire EReg API and the way I am doing it is the only way I can see it to be done among the possibilities I am given.

                The only thing they give me that can be used as a loop is someRegEx.map(string, func). Basically this goes over a string looking for matches and every time it finds a match it runs the func. The func is supposed to ultimately return a replacement for the matched string. I actually have it returning the same thing it put in cause, I don't need to replace strings, I need to know the positions of certain characters. So, basically I am using a "low level" replace interface to get character positions. That doesn't sound good but, it's all I have. However, if I am really stuck doing it this way, it means I need to do it this way every time I need to do this, so, this code needs to be moved from expression parsing and put in some utility class... yep.
                Last edited by MadGypsy; 11-24-2016, 08:23 PM.
                http://www.nextgenquake.com

                Comment


                • I'm going to assume this means my parser works. In that example I use every base math operator, negative and parens, A math function and constant, as-well-as threw in a float for good measure. If it parsed all that and got the right answer there is no reason to believe you couldn't keep going and going. It's just going to keep doing all the stuff it just did.

                  http://www.nextgenquake.com

                  Comment


                  • I upgraded the expression parser to accommodate Math.(min|max|pow). It only mostly works though. I need to work on my system a little more. You can't currently do this

                    Math.min(math.pow(2,2), 5)

                    If you don't know what "this" is referring to - you can't put a pow, min or max inside of a pow, min or max. The reason is simple but the solution is not. The reason is, my parser grabs the guts of the function, splits on comma and sends each side of the comma to be evaluated. If you put min/max/pow in a min/max/pow my script splits on all of the (too many) commas and everything falls apart. I don't know if I really care...so you cant put min/max/pow in min/max/pow...how often would you really need to do that in the context that this script is to be used? Probably never. The whole point of the expression parser was to be able to write mathematical expressions in a JSON object and have them treated like actual math. Even then the ultimate goal was to be able to concoct the result of formulas for json driven particle effects. My parser already knows way more math than I do. I think I'm going to chalk up this max/min/pow flaw as whoopie-doo. I was using this parser when min/max/pow weren't supported at all.




                    regarding traversing a string with regex to grab inner and outer bounds positions of a parented group - I was able to code up a pretty clean solution even though I am technically using a find/replace function to accomplish it. I even managed to keep everything internal to the function.

                    Code:
                    /** GET_GROUP_BOUNDS
                     * @param	reg	- regex to match by
                     * @param	cases	- array of 2 delimiters to compare against matches  ex: ["(",")"]
                     * @param	expr	- the string expression to find groups in
                     * @return	a Bounds_t instance containing the inner and outer positions of the parent characters 
                     */
                    public static function getGroupBounds(reg:EReg, cases:Array<String>, expr:String):Null<Bounds_t>
                    {	
                    	var cnt:Int  = 0;		//the number of unclosed parents
                    	var group:Bounds_t = {		//struct for storing bounds
                    		inner:{
                    			open: -1,
                    			close:-1
                    		},
                    		outer:{
                    			open: -1,
                    			close:-1
                    		}
                    	};
                    	
                    	//find leftmost-outermost group bounds
                    	reg.map(expr, function(reg:EReg):String
                    	{
                    		var result	= reg.matched(0);		//the current matched string
                    		var index	= reg.matchedPos().pos;		//the position of this result
                    		
                    		var ibounds:GenBounds_t = group.inner;		//shorten names
                    		var obounds:GenBounds_t = group.outer;
                    		
                    		if( result == cases[0] )			//if this is an opening delimiter
                    		{	++cnt;					//increment unclosed parents
                    			if (ibounds.open == -1) 		//if this is the first opening delimiter
                    			{	ibounds.open = index + 1;	//store bounds
                    				obounds.open = index;
                    			}
                    		} else if ( result == cases[1] ) {		//if this is a closing delimiter
                    			--cnt;					//decrement unclosed parents
                    			if ((cnt == 0)&&(obounds.open > -1))	//if there are no unclosed parents and an open delim...
                    			{					//...has already been found, this is the group close delim
                    				obounds.close = index + 1;	//store bounds
                    				ibounds.close = index;
                    				cnt = -1;			//offset cnt in a way that no more groups will be found
                    			}
                    		}
                    		
                    		//to satisfy the expected condition. value is unchanged
                    		return result;
                    	});
                    	
                    	//if it's a valid group return it
                    	if ((group.inner.open > -1) && (group.inner.close > -1) && 
                    	    (group.outer.open > -1) && (group.outer.close > -1) && (cnt == -1))
                    		return group;
                    	
                    	//else return null
                    	return null;
                    }
                    Last edited by MadGypsy; 11-25-2016, 03:36 PM.
                    http://www.nextgenquake.com

                    Comment


                    • How many of you knew that, no matter what I said, there was no way I was going to leave my expression parser broken?

                      You can nest min/max/pow all you want. I also added ffloor, fceil, fround, POSITIVE_INFINITY, NEGATIVE_INFINITY, isNaN and isFinite

                      my regex threads expose the degree of compatibility with math that my parser possesses
                      Code:
                      private static inline var CONSTANT:String	= "PI|POSITIVE_INFINITY|NEGATIVE_INFINITY|(?<![0-9.])E";
                      private static inline var FUNCTION:String	= "isNaN|isFinite|cos|acos|sin|asin|tan|atan|atan2|random|abs|ffloor|floor|fceil|ceil|fround|round|sqrt|max|min|log|pow|exp";
                      I rewrote the entire script from the ground up with about a 60% (made up number that is probably close) difference in the old script. My new script is a bit more efficient and it will basically parse any concoction of math you could invent. I had to rewrite cause my original script really had no good way or place to handle commas. My new script handles the piss out of them.



                      this comment from my code gives a lot of clues as to how my system works
                      Code:
                      /** TOKENIZE
                       * 		by converting "inner expressions" to tokens, the expression can be easily and properly split on it's operators
                       * 
                       * 		Tokens_t:
                       * 		tokens.expression	- stores a "tokened" version of the original expression
                       * 		tokens.stack 		- stores the expressions that were replaced with tokens
                       * 
                       * 		ex:
                       * 		before: (-4/7) + (sin(pi*45) / 360) * sqrt(2)
                       * 		after:	
                       * 			tokens.expression = (TOKEN0) + (TOKEN1) * sqrt(TOKEN2)
                       * 			tokens.stack[0] = -4/7
                       * 			tokens.stack[1] = sin(pi*45) / 360
                       * 			tokens.stack[2] = 2
                       * 
                       * @param	expr - the expression to tokenize
                       * @return	an instance of Tokens_t
                       *
                      /
                      and this comment gives clues as to how I am handling commas
                      Code:
                      /** DETOKENIZE_PART_OF_A_TOKENED_EXPRESSION
                       * 		in the case of commas there needs to be a way to determine how much of the tokens.stack belongs on either side of the comma
                       * @param	part	- the expression to detoken - this is either the left or right of a comma in the tokens.expression value
                       * @param	tokens	- the tokens container that part was derived from
                       * @return	a detokened representation of part
                       */
                      Last edited by MadGypsy; 11-25-2016, 11:38 PM.
                      http://www.nextgenquake.com

                      Comment


                      • Originally posted by MadGypsy View Post
                        How many of you knew that, no matter what I said, there was no way I was going to leave my expression parser broken?
                        I did! You don't exactly strike me as being sloppy in your work.
                        ♪ I'm skiiiiiiinnin' in the pain, just skiiiiiiinnin' in the pain ♪
                        ♪ What a glorious feelin' I'm haaaaaaappy again ♪

                        Comment


                        • @You don't exactly strike me as being sloppy in your work.

                          Well, there is that but there is also 2 other things.

                          1) this rewrite was intended to put a big fat DONE stamp on all the stuff I have made so far

                          2) not using any old code as reference is so I can be sure I actually programed all this stuff and not just keep fixing errors til it worked. Regardless of what the situation with that was before (probably a combo), this run I can say everything I have rewritten so far is based on solid knowledge in my head.

                          When you put those goals together there is no room for "mostly works".

                          In the case of the expression parser, I was looking at the code I posted regarding character bounds and I started thinking "This could be used differently and more efficiently". I rewrote the function to spit out a different kind of results, couldn't merge it into what I already had so, I just rewrote everything using the new function as the starting point. Some of the stuff from the original parser got used, but mostly not, and the stuff that did get reused was more "this is the only way to get this data" than anything else.

                          There is still one error in the parser though. The condition is so incredibly specific that I should figure it out pretty soon.

                          if a number follows a parens and is followed by a math operator which is also followed by a math function it gets messed up.

                          ex this (2 / sin(pi/45))

                          but, oddly, this works (sin(pi/45) / 2)

                          that's crazy specific so, I'm thinking my regex for infix operators has some mistake, or more accurately, oversight. Or maybe haxe isn't honoring some portion of my regex. I already checked and the broken condition is not giving me the same results as the working condition so, it's not as simple as the expression becoming out of order.
                          Last edited by MadGypsy; 11-26-2016, 11:25 AM.
                          http://www.nextgenquake.com

                          Comment


                          • and there ya go. fixed in every conceivable way...well to the 5th decimal in this particular crazy-ass, nonsensical math problem. I really can live with accuracy to the 100 thousandth (and I guarantee you most of the time it will just be accurate period)
                            Last edited by MadGypsy; 11-26-2016, 01:38 PM.
                            http://www.nextgenquake.com

                            Comment


                            • for anyone that doesn't get why an expression parser that is only "pretty accurate" is good enough:

                              The inaccuracy comes from adding floating point numbers to the equation. In the example below I used the same formula from my last post but I removed the float. As you can see, the results are identical to every position. When you have a float (ex 0. it's only going to be as accurate as you made it. The parseFloat function might decide that's 0.801254254, and that's where inaccuracy comes in. There is nothing I can do from my expression parser end to stop this.

                              http://www.nextgenquake.com

                              Comment


                              • check it out, I added the float back in and included a trailing zero (ie 0.8 to 0.80) and full accuracy came back.



                                Well, now Expression2 can become Expression and I can move on to more rewriting.
                                Last edited by MadGypsy; 11-26-2016, 02:23 PM.
                                http://www.nextgenquake.com

                                Comment

                                Working...
                                X