
	-- _test_line = _test_line or {}
	-- if keyDown("i") and mf(time*5)~=mf(time*5+main_dt*5) then 
	-- 	table.insert(_test_line,mouse.x)
	-- 	table.insert(_test_line,mouse.y)
	-- end
	-- gfx.setColor(1,0,0,1)
	-- if #_test_line>3 then 
	-- 	gfx.line(_test_line)
	-- 	splits = splitPolyLine(_test_line)
	-- 	gfx.push()
	-- 	for s,split in ipairs(splits)do
	-- 		gfx.translate(300,0)
	-- 		if #split>3 then 
	-- 			gfx.polygon("fill",split)
	-- 		end
	-- 	end
	-- 	gfx.pop()
	-- end


local boiserie
function createDepthMap(path,name)
	boiserie=boiserie or {width=1000,height=1000}
	if file_exists(LINK_DIR..path..name..".obj") then 
		boiserie.verts = obj.load(path..name..".obj")
		scene.calcVertNormals(boiserie.verts,nil,nil,nil,nil,5)
		local first = boiserie.verts[1]
		boiserie.t,boiserie.l,boiserie.r,boiserie.b = first[3],first[1],first[1],first[3]
		print(#boiserie.verts)
		print(inspect(boiserie.verts[1000]))
		for v=1,#boiserie.verts,1 do 
			boiserie.t=boiserie.verts[v][3]<boiserie.t and boiserie.verts[v][3] or boiserie.t
			boiserie.l=boiserie.verts[v][1]<boiserie.l and boiserie.verts[v][1] or boiserie.l
			boiserie.b=boiserie.verts[v][3]>boiserie.b and boiserie.verts[v][3] or boiserie.b
			boiserie.r=boiserie.verts[v][1]>boiserie.r and boiserie.verts[v][1] or boiserie.r
		end
		boiserie.width,boiserie.height = boiserie.r-boiserie.l,boiserie.b-boiserie.t
		local scale = 1
		
		print(boiserie.r,boiserie.l,boiserie.b,boiserie.t)
		print(boiserie.width,boiserie.height)

		boiserie.out = newCanvas(boiserie.width*scale,boiserie.height*scale)
		boiserie.depthMap = newCanvas(boiserie.width*scale,boiserie.height*scale)
		boiserie.normalMap = newCanvas(boiserie.width*scale,boiserie.height*scale)
		boiserie.mesh = gfx.newMesh(zformat4,boiserie.verts,"triangles")
		gfx.push("all")
			gfx.setShader(gfx.newShader[[
				#pragma language glsl3
				#ifdef VERTEX
				attribute vec3 VertexNormal;
				out vec3 vnorm;
				vec4 position(mat4 transform_projection, vec4 vertex_position) {
					vnorm = VertexNormal;
					return transform_projection*vec4(vertex_position.x,vertex_position.z,8-vertex_position.y,vertex_position.w);
				}

				#endif

				#ifdef PIXEL
				in vec3 vnorm;
				void effect() {
					love_Canvases[0] = vec4(vec3(gl_FragCoord.z),1);
					love_Canvases[1] = vec4((vnorm+1)*0.5,1);
				}

				#endif
			]])
			gfx.setColor(1,1,1,1)
			gfx.setCanvas({boiserie.depthMap,boiserie.normalMap,depth=true})
			gfx.setMeshCullMode("front")
			gfx.setDepthMode("less",true)
			gfx.draw(boiserie.mesh,-boiserie.l*scale,-boiserie.t*scale,0,scale,scale)
			combineMaps = gfx.newShader[[
				#pragma language glsl3
				#ifdef VERTEX
				vec4 position(mat4 transform_projection, vec4 vertex_position) {
					return transform_projection*vertex_position;
				}
				#endif
				#ifdef PIXEL
				uniform sampler2D depthMap;
				vec4 effect(vec4 color, Image tex, vec2 tc, vec2 sc) {
					vec2 tc2 = vec2(tc.x,1-tc.y);
					float dm = Texel(depthMap,tc2).r;
					return vec4(Texel(tex,tc2).rgb,dm);
				}
				#endif
			]]
			combineMaps:send("depthMap",boiserie.depthMap)
			gfx.setShader(combineMaps)
			gfx.setCanvas(boiserie.out)
			gfx.draw(boiserie.normalMap)	
			gfx.setCanvas()
			boiserie.data = boiserie.out:newImageData()
			boiserie.data:mapPixel(UnmultiplyGammaPixel)
			boiserie.data:encode("tga",name..".tga")
			os.rename(SAVE_DIR..name..".tga",GAME_DIR..path..name..".tga")
		gfx.pop()
		boiserie.depthMap:release()
		boiserie.normalMap:release()
		boiserie.out:release()
		boiserie.mesh:release()
		print("output depth/normals for"..name)
		boiserie.verts=nil
		collectgarbage()
		collectgarbage()
		ltimer.sleep(1)
	end
end

function createBoiserieMaps()
	for i=0,30, 1 do 
		createDepthMap("models/architecture/boiseries/",string.format("boiserie_%02d",i))
	end
end

	-- if game.testpolys and #game.testpolys>0 then 
	-- 	local s=24
	-- 	for p,poly in ipairs(game.testpolys)do
	-- 		if #poly>1 then 
	-- 			gfx.push()
	-- 			gfx.scale(s,s)
	-- 			gfx.setLineWidth(0.1,0.1)
	-- 			gfx.translate(70,5)
	-- 			gfx.setColor(1,p%2==0 and 0.2 or 1,0.4,1)
	-- 			gfx.line(poly)
	-- 			gfx.pop()
	-- 			for i=1,#poly,2 do 
	-- 				gfx.print((i+1)/2,(poly[i]+70)*s,(poly[i+1]+5)*s+i)
	-- 			end
	-- 			-- gfx.setColor(0,0,0,1)
	-- 			-- gfx.print(round(poly[1]).." "..round(poly[2]),(poly[1]+70)*8,(poly[2]+5)*8+10)
	-- 		end
	-- 	end
	-- end

local cube,cube2
function drawTests(view)


	if not view.bounds.l or level.isAnim or not editor.debug.draw_tests then 
		return 
	end
	bench.push("_draw_tests")
	
	normalPlane = normalPlane or {}

	normalPlane.mesh = gfx.newMesh(zformat,{
		{0,0,100,	   0, 0,0, 1,1,1,1},
		{100,0,100,  0, 1,0, 1,1,1,1},
		{100,0,0,	   0, 1,1, 1,1,1,1},
		{0,0,0, 		 0, 0,1, 1,1,1,1},
	},"fan")

	normalPlane.tex = normalPlane.tex or gfx.newImage(LINK_DIR.."models/architecture/boiseries/boiserie_01.tga")
	normalPlane.tex:setFilter("nearest","nearest")
	normalPlane.mesh:setTexture(normalPlane.tex)

	gfx.push("all")

	gfx.setColor(1,1,1,1)
	gfx.setShader(shaders.deferredStatic)
	-- shaders.deferredStatic:send("modelMatrix",mat4.identity())
	-- shaders.deferredStatic:send("MVP","column",gfx.camera.vp)
	gfx.draw3D(normalPlane.mesh)
	gfx.pop()
	

	-- if keyDown("m") or not grassMesh then 
	-- 	grassTexture = gfx.newImage("/models/grass.png")
	--if LOVE then 	grassTexture:setFilter("nearest","nearest") end
	-- 	grassVerts = {}
	-- 	local num,spread,height,width = 200,200,16,16
	-- 	local variants = grassTexture:getWidth()/width
	-- 	for i=1, num, 1 do 
	-- 		local bx,bz,br = math.random()*spread,math.random()*spread,math.random()*2*pi
	-- 		local ox,oz = math.sin(br)*16,math.cos(br)*16
	-- 		local px,pz = math.sin(br+pi/2)*16,math.cos(br+pi/2)*16
	-- 		local sway = 2
	-- 		local height = height * math.sin(bx+bz)
	-- 		local grassVariant = 1

	-- 		table.insert(grassVerts,{ bx-ox/2,0,bz-oz/2,1,  		0,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx+ox/2,0,bz+oz/2,1,  		1,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx-ox/2,-16,bz-oz/2,1,  	0,0,  1,1,1,1, sway,sway/8,sway})
	-- 		table.insert(grassVerts,{ bx+ox/2,0,bz+oz/2,1,  		1,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx-ox/2,-16,bz-oz/2,1,  	0,0,  1,1,1,1, sway,sway/8,sway})
	-- 		table.insert(grassVerts,{ bx+ox/2,-16,bz+oz/2,1, 		1,0,  1,1,1,1, sway,sway/8,sway})

	-- 		table.insert(grassVerts,{ bx-px/2,0,bz-pz/2,1,  		0,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx+px/2,0,bz+pz/2,1,  		1,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx-px/2,-16,bz-pz/2,1,  	0,0,  1,1,1,1, sway,sway/8,sway})
	-- 		table.insert(grassVerts,{ bx+px/2,0,bz+pz/2,1,  		1,1,  1,1,1,1, 0,0,0})
	-- 		table.insert(grassVerts,{ bx-px/2,-16,bz-pz/2,1,  	0,0,  1,1,1,1, sway,sway/8,sway})
	-- 		table.insert(grassVerts,{ bx+px/2,-16,bz+pz/2,1, 		1,0,  1,1,1,1, sway,sway/8,sway})

	-- 	end 
	-- 	grassMesh = gfx.newMesh(zformat,grassVerts,"triangles")
	-- 	grassMesh:setTexture(grassTexture)	
	-- 	grassModel = newModel(grassMesh,newTransform(340,180,0))
	-- 	--grassModel = newModel(grassMesh)

	-- end

	-- if grassMesh then 
	-- 	gfx.setColor(1,1,1,1)
	-- 	shaders.forwardRender:send("time",time)
	-- 	trace("grass?",#grassVerts)
	-- 	drawModel(grassModel)
	-- end



	--gfx.draw(editor.testTri)

	editor.testTexture = editor.testTexture or gfx.newImage(LINK_DIR.."models/castle.png")
	if LOVE then editor.testTexture:setFilter("nearest","nearest") end

	if not editor.tesMesh then 
		local castle = gfx.newMesh(zformat,obj.load("models/castle2.obj"),"triangles")
		local verts = {}
		local scale = 1000
		for i=1,1,1 do 
			local x,y,z,w,u,v
			local x1,y1,z1 = math.random()*scale,math.random()*scale,math.random()*scale
			for v=1,castle:getVertexCount(),1 do 
				x,y,z,w,u,v = castle:getVertex(v)
				table.insert(verts, {x+x1,y+y1,z+z1,w,u,v})
			end
		end
		editor.tesMesh = gfx.newMesh(zformat,verts,"triangles")
	end
	

	 if  cmdDown and keyDown("n") and keyDown("c")  then 	
	 	-- cube.mainTrack.time = 0
			-- 		cube.anim:update(0)
	 	-- cube.anim.playing=true
	 	-- cube.mainTrack = cube.anim:new_track(cube.nextAnim,1,1,function()  cube.nextAnim=cube.nextAnim end)
	 	-- cube.anim:play(cube.mainTrack)

		local testModel = {parent=room,transform=mat4(),mesh=editor.tesMesh,front=true}
		testModel.transform:translate(cpml.mat4():rotate(cpml.mat4(),-pi,vec3(1,0,0)),vec3(math.random()*10*50,math.random()*10*50,math.random()*10*50))
		testModel.matrix=scene.getMatrix(testModel)
		gfx.setTexture(testModel.mesh,editor.testTexture)	
		table.insert(testModels,testModel)
			--shaders.forwardRender:send("MVP", zcam.vp*ringModel.matrix)`
			--gfx.draw(ringShape)
		--drawModel(cube,true)
	end
	


	if not cube then
		cubez=0
		cubeTransform = mat4.identity()
		cubeTransform:scale(cubeTransform, vec3(1,1,1))
		cubeTransform:translate(cubeTransform, vec3(0,0,0))
		cubeTransform:rotate(cubeTransform,-pi/2,vec3(1,0,0))
		--buildings = gfx.newMesh(zformat, obj.load("/models/build.obj"), "triangles")

		local projectData = limage.newImageData(LINK_DIR.."models/project.png")
		local projectTex  = gfx.newImage(projectData)
		local w,h = projectTex:getDimensions()
		local col = function(x,y)
			return {projectData:getPixel( x*w, y*h )}
		end

		meshFile  = LINK_DIR.."models/project.iqm"
		animFile = LINK_DIR.."models/project.iqm"
		
		model = iqm.load(meshFile)

		local form = model.mesh:getVertexFormat( )
		
		-- print(inspect(form))

		local map = model.mesh:getVertexMap()
		local verts = {}
		for i=1,model.mesh:getVertexCount(),1 do 
			local x,y,z = model.mesh:getVertexAttribute(i,1)
			local bx,by,bz,bw = model.mesh:getVertexAttribute(i,5)
			local wx,wy,wz,ww = model.mesh:getVertexAttribute(i,6)
			table.insert(verts,lume.concat(
				{x,y,z},{1},
				{model.mesh:getVertexAttribute(i,2)},
				{model.mesh:getVertexAttribute(i,7)},
				{model.mesh:getVertexAttribute(i,3)},
				{0,1,1,1},
				{bx,by,bz,bw},
				{wx,wy,wz,ww}
			))
		end

		-- print("verts1",#verts)
		-- print("map1",#map)
		local verts2={}
		local match
		local remap = {}
		local map2 = {}
		for i=1,#verts,1 do 
			match = false
			for j=1,#verts2,1 do 
				if    verts[i][1]==verts2[j][1] 
					and verts[i][2]==verts2[j][2] 
					and verts[i][3]==verts2[j][3] then
					-- and simpleSame(col(verts[i][5],verts[i][6]), col(verts2[j][5],verts2[j][6])) then
					match=true
					remap[i]=j
				end
			end
			if not match then 
				table.insert(verts2,verts[i])
				remap[i]=#verts2
			end
		end
		for i=1,#map,1 do 
			map2[i] = remap[map[i]]
		end
		-- print("verts2",#verts2)

		cube = {
			iqm = true,
			nextAnim = "Walk",
			loopAnim 	= true,
			parent = room,
			transform = cubeTransform,
			mesh = model.mesh
		}	


		cube.iqmAnims = iqm.load_anims(animFile)
		-- print(inspect(cube.iqmAnims.skeleton))

		local anims = {}
		local frames = cube.iqmAnims.frames
		for a,anim in ipairs(cube.iqmAnims) do 
			anims[anim.name] = {}
			for i=anim.first,anim.last,1 do 
				table.insert(anims[anim.name],frames[i])
			end
		end

		editor.testModel = {
			verts = verts2,
			map = map2,
			texdir = GAME_DIR.."models/project.png",
			tex = projectData,
			skeleton = cube.iqmAnims.skeleton,
			anims = anims,
			mesh = gfx.newMesh(animatedVertexFormat,verts,"triangles")
			-- joints = cube.iqmAnims.joint_map
		}
		
		cube.anim = anim9(cube.iqmAnims)

		gfx.setTexture(cube.mesh,projectTex)	

		cube.mainTrack = cube.anim:new_track(cube.nextAnim,1,1,function(anim)  anim.time=0 cube.nextAnim=cube.nextAnim end)
		cube.anim:play(cube.mainTrack)
	end


	

	if cube  then 

		for a,anim in ipairs(cube.iqmAnims) do 
			-- trace(anim.name)
		end

		if cube.mainTrack then 
			cube.mainTrack.time = cube.mainTrack.time+0.01
			cube.anim:update(0)
			editor.testPose = cube.anim.current_pose
			cube.skelly=true--lume.map(cube.anim.current_pose,makeProper)
			-- trace(cube.mainTrack.time,cube.anim:length(cube.nextAnim),cube.mainTrack.playing)
			if ltimer.fourstep==1 then 
				--cube.anim:update(1/60)
				if  cube.nextAnim~="" then
					if cube.mainTrack.time >= cube.anim:length(cube.nextAnim)-0.1 then 
						-- cube.anim.playing=true
						-- cube.mainTrack = cube.anim:new_track(cube.nextAnim,1,1,function()  cube.nextAnim=cube.nextAnim end)
						-- cube.anim:play(cube.mainTrack)
					end
				end
			end
		end
		--gfx.setMeshCullMode("front")

	 -- 	shaders.forwardRender:send("skellyman",1)
		-- shaders.forwardRender:send("u_pose", "column", unpack(cube.anim.current_pose))
		-- -- gfx.draw(cube.mesh)
		-- shaders.forwardRender:send("skellyman",0)
		-- drawModel(cube)
	end

	cube.mesh = editor.testModel.mesh
	if cube2 then 
		editor.testcube2=cube2
		-- gfx.draw(cube2)
	end

	-- gfx.setWireframe(true)
	gfx.setColor(1,1,1,1)
	gfx.setMeshCullMode("front")

	-- trace("castles",#testModels)

	for i,test in ipairs(testModels) do
		drawModel(test)
		-- gfx.draw(test.mesh)
		if i==#testModels and  keyDown("m")  then 
			testModels[i] = nil
		end
	end

	-- --gfx.setMeshCullMode("none")



	--gfx.setWireframe(false)
	--gfx.setMeshCullMode("none")
	--shaders.forwardRender:send("skellyman",0)
	--gfx.draw(buildings)
	--gfx.setWireframe(true)
	--drawModel(ringModel)
	--gfx.setWireframe(false)

	--local dx,dy = (mouse.x-view.bounds.l-view.bounds.w/2)/(view.bounds.w/2),(mouse.y-view.bounds.t-view.bounds.h/2)/(--view.bounds.h/2)
--
	--local raw = vec3(-1*view.bounds.w,dy*view.bounds.h,100)
	--local new = 	vec3.rotate(vec3.rotate(raw, cam.angle.y, vec3.unit_x), pi-cam.angle.x, --vec3.unit_y) 
	--local p = camera.project(new-zcam.pos) 
	--local d = (p.x-view.bounds.l-view.bounds.w/2)/(view.bounds.w/2)
	--local mult=1/d
	--raw = vec3(-dx*view.bounds.w*mult,dy*view.bounds.h*mult,100)
	--new = 	vec3.rotate(vec3.rotate(raw, cam.angle.y, vec3.unit_x), pi-cam.angle.x, vec3.unit_y) 

	--cube.transform:translate(mat4(), vec3(0,0,0))
	--cube.transform:scale(mat4(), vec3(20,20,20))
	--local look = mat4():look_at(cube.transform,vec3(0,0,0),-zcam.pos,vec3(0,1,0))
	--cube.transform = cube.transform*-look
	
	--cube.transform:translate(cube.transform,new-zcam.pos )

	bench.pop("_draw_tests")
end