AABB to Hammer Brushes

Hello, im working on a Converter for converting props into Hammer brushes.
Because im doing this while playing with others, im doing it using Expression 2. Later i will (maybe) transfer it into Lua, so i hope i find some help in here.

Well, where to start…
The Hammer brush system adds brushes using sepperate faces declared in its VMF file. lets say, weve got a simple 6 face brush.

to be not confused: brush = cube / block in hammer, block = text / code part in vmf

(for example, this is a brush at position x64 y128 z192 with size x64 y128 z192. Ive deleted the header and footer of the vmf to keep it small. The whole vmf can be found here: http://pastebin.com/WcBLY9zB )



world
{
	"id" "1"
	"mapversion" "1"
	"classname" "worldspawn"
	"skyname" "sky_day01_01"
	"maxpropscreenwidth" "-1"
	"detailvbsp" "detail.vbsp"
	"detailmaterial" "detail/detailsprites"
	solid
	{
		"id" "2"
		side
		{
			"id" "1"
			"plane" "(64 256 384) (128 256 384) (128 128 384)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[1 0 0 0] 0.25"
			"vaxis" "[0 -1 0 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		side
		{
			"id" "2"
			"plane" "(64 128 192) (128 128 192) (128 256 192)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[1 0 0 0] 0.25"
			"vaxis" "[0 -1 0 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		side
		{
			"id" "3"
			"plane" "(64 256 384) (64 128 384) (64 128 192)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[0 1 0 0] 0.25"
			"vaxis" "[0 0 -1 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		side
		{
			"id" "4"
			"plane" "(128 256 192) (128 128 192) (128 128 384)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[0 1 0 0] 0.25"
			"vaxis" "[0 0 -1 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		side
		{
			"id" "5"
			"plane" "(128 256 384) (64 256 384) (64 256 192)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[1 0 0 0] 0.25"
			"vaxis" "[0 0 -1 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		side
		{
			"id" "6"
			"plane" "(128 128 192) (64 128 192) (64 128 384)"
			"material" "/BLACK_OUTLINE"
			"uaxis" "[1 0 0 0] 0.25"
			"vaxis" "[0 0 -1 0] 0.25"
			"rotation" "0"
			"lightmapscale" "16"
			"smoothing_groups" "0"
		}
		editor
		{
			"color" "0 142 183"
			"visgroupshown" "1"
			"visgroupautoshown" "1"
		}
	}
}

(to remember, solids are stored in “world” block. entities are sepperated from world block and represents an own block. world is usually ID 1, entity is 5 or 6 upwards.

The faces are written in vmf using this order: +Z -Z -X +X +Y -Y (found out by making an brush in Hammer, having an own texture on each face. Now when its true that Red, Green, Blue line represents X+ Y+ Z+ then the order is correct.)

Now i made a expression 2 looking for the Min and Max AABB of the Prop, and generating a brush using its coordinates.

It works, until the detected prop is having negativ angles. by a negative Pitch Yaw or Roll, like ang(0,-180,-90) hammer says something like x solids are broke, and needs to deleted.
This is because the first face of brush “solid” should be on top, but when theres an Inverted angle, its on bottom or side. Hammer doesnt like that.

Now i cant figure out how to fix this.
I tried to add an brush in hammer, rotate it by 180°, add a prop in gmod, rotate it by 180, save it to vmf and compare both.
some values was different, so i added a check:
if(Ent:up() != vec(0,0,1){ …new coordinates block…} but it didnt worked.

Heres the e2 code.


@name plates2vmfbrushes test
@inputs
@outputs State Indexer
@persist End:string State Props:array Indexer Ent:entity PropsC FN:string Content:string
@trigger none
interval(10)

if(first()){
    FN=randint(1,10000)+"data.txt" #filename
	
	##header of vmf
    fileWrite(FN,"versioninfo
    {
    	\"editorversion\" \"400\"
    	\"editorbuild\" \"6412\"
    	\"mapversion\" \"4\"
    	\"formatversion\" \"100\"
    	\"prefab\" \"0\"
    }
    visgroups
    {
    }
    viewsettings
    {
    	\"bSnapToGrid\" \"1\"
    	\"bShowGrid\" \"1\"
    	\"bShowLogicalGrid\" \"0\"
    	\"nGridSpacing\" \"64\"
    	\"bShow3DGrid\" \"0\"
    }
    world
    {
    	\"id\" \"1\"
    	\"mapversion\" \"4\"
    	\"classname\" \"worldspawn\"
    	\"detailmaterial\" \"detail/detailsprites\"
    	\"detailvbsp\" \"detail.vbsp\"
    	\"maxpropscreenwidth\" \"-1\"
    	\"skyname\" \"sky_day01_01\"
    ")
	
    Content="" 
	
	#footer of vmf
    End="
    cameras
    {
    	\"activecamera\" \"-1\"
    }
    cordon
    {
    	\"mins\" \"(-1024 -1024 -1024)\"
    	\"maxs\" \"(1024 1024 1024)\"
    	\"active\" \"0\"
    }
    "
	
	#setting counter to 0
    Indexer=0
	
	#state 1 is finding props, state 2 is collecting data, state 3 is writing file
    State = 1
	
}

if(findCanQuery() & State == 1){

    findIncludePlayerProps(owner())
    findByClass("prop_physics")

    Props = findToArray()  
	
    State = 2
	
    PropsC=Props:count()
    print("found props..."+PropsC)
}    

if(State == 2 & Indexer < PropsC){
    if(fileCanWrite()){
		for(Idx=1,10){ #accelerating everything quite a bit, adding 10 "solid" blocks to Variable Content, and then write content into file
			if(Indexer>=PropsC){continue} #skip remaining steps to x10
			
			Indexer++ #counting up the index
			
			Ent = Props[Indexer,entity]
			
			if(Ent:isValid() & Ent:type() == "prop_physics"){
			
				H = Ent:toWorld(Ent:aabbMax())
				L = Ent:toWorld(Ent:aabbMin())
				
				#this is a mess, i placed a 48^3 brush / prop on 0,0,0 having 0,0,0 angle in gmod and hammer, and compared the values.
				S1="("+L:x()+" "+H:y()+" "+H:z()+") "+"("+H:x()+" "+H:y()+" "+H:z()+") "+"("+H:x()+" "+L:y()+" "+H:z()+")"
				S2="("+L:x()+" "+L:y()+" "+L:z()+") "+"("+H:x()+" "+L:y()+" "+L:z()+") "+"("+H:x()+" "+H:y()+" "+L:z()+")"
				S3="("+L:x()+" "+H:y()+" "+H:z()+") "+"("+L:x()+" "+L:y()+" "+H:z()+") "+"("+L:x()+" "+L:y()+" "+L:z()+")"
				S4="("+H:x()+" "+H:y()+" "+L:z()+") "+"("+H:x()+" "+L:y()+" "+L:z()+") "+"("+H:x()+" "+L:y()+" "+H:z()+")"
				S5="("+H:x()+" "+H:y()+" "+H:z()+") "+"("+L:x()+" "+H:y()+" "+H:z()+") "+"("+L:x()+" "+H:y()+" "+L:z()+")"
				S6="("+H:x()+" "+L:y()+" "+L:z()+") "+"("+L:x()+" "+L:y()+" "+L:z()+") "+"("+L:x()+" "+L:y()+" "+H:z()+")"
				
				#writing solid block for vmf
				Data="
			solid
				{
					\"id\" \""+((Indexer)+1)+"\"
					side
					{
						\"id\" \"1\"
						\"plane\" \""+S1+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[1 0 0 0] 0.25\"
						\"vaxis\" \"[0 -1 0 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					side
					{
						\"id\" \"2\"
						\"plane\" \""+S2+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[1 0 0 0] 0.25\"
						\"vaxis\" \"[0 -1 0 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					side
					{
						\"id\" \"3\"
						\"plane\" \""+S3+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[0 1 0 0] 0.25\"
						\"vaxis\" \"[0 0 -1 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					side
					{
						\"id\" \"4\"
						\"plane\" \""+S4+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[0 1 0 0] 0.25\"
						\"vaxis\" \"[0 0 -1 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					side
					{
						\"id\" \"5\"
						\"plane\" \""+S5+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[1 0 0 0] 0.25\"
						\"vaxis\" \"[0 0 -1 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					side
					{
						\"id\" \"6\"
						\"plane\" \""+S6+"\"
						\"material\" \"TOOLS/TOOLSNODRAW\"
						\"uaxis\" \"[1 0 0 0] 0.25\"
						\"vaxis\" \"[0 0 -1 0] 0.25\"
						\"rotation\" \"0\"
						\"lightmapscale\" \"16\"
						\"smoothing_groups\" \"0\"
					}
					editor
					{
						\"color\" \"0 206 200\"
						\"visgroupshown\" \"1\"
						\"visgroupautoshown\" \"1\"
					}
				}
			"
			#adding it to Content variable. which stores 10 of them, and then writes it into a file.
			Content = Content + Data + "
"
					  
			}
        }
        if(Content != ""){
            fileAppend(FN,Content) # write content into a file and clear it then
        } 
        Content = ""
        if(Indexer >= PropsC){ #if all props in array are processed, go to next state
            State=3 #pre-end state
        }
    }
}
if(State == 3 & fileCanWrite()){

    fileAppend(FN,"   }
"+End) #now add the footer of the vmf
	
    print("done")
	
    State = 4 #doesnt exist, lets say its END
}



using the props as prop_static isnt a problem, i allready made a e2 doing that, and successfully tested it with 8020 prop_statics.

Sorry for bad spelling, my english isnt that great.