defaultOrientation = {x=0,y=0.001,z=0,w=1}
function scene.newEntity(raw)
	local obj = deepcopy(raw)
	local obj2 =   objects[obj.key] or objects["_controller"]

	if obj.spawn and (not editingLevel) and (not game.spawned[obj.spawn]) then 
		game.spawned[obj.spawn] = true
		scene.newEntity(lume.merge(obj,{
			spawn = false,
			key   = game.characters[obj.spawn],
		}))
		return
	end

	local entity = {
		 	isEntity 	= 	true
		, 	data 		= 	obj2
		, 	key         =   obj.key 		or "_controller"
		, 	name        =   obj.name		or "Untitled "..tostring(nextUntitled(room.entities))
		, 	uid         =   obj.uid			or uuid()
		, 	alpha       =   obj.alpha		or 1
		
		, 	scale       =   vec3(obj.scale 		or {x=1,y=1,z=1} or 1)
		, 	orientation =   quat(obj.orientation or defaultOrientation)
		, 	position 		= 	vec3(obj.position  or {obj.x,obj.y,obj.z} or 0)
		
		, 	x           =   obj.position and obj.position.x or  obj.x 			or 0
		, 	y           =   obj.position and obj.position.y or  obj.y 			or 0
		, 	z       		=   obj.position and obj.position.z or  obj.z  			or 0

		,  spawn  			=   obj.spawn 

		,  static 			=  obj.static
		, 	visible 		= 	(obj.visible==nil or tostring(obj.visible)=="true")
		, 	gravity     =   obj.gravity
		,   light 		  =   type(obj.light)=="table" and obj.light or {enabled=false,color={r=1,g=1,b=1},range=1,strength=1}
		, 	surface 		= 	obj.surface

		, 	spin        =   1   
		, 	v 					=   obj.v or {x=0,	y=0,	z=0}
		, 	vmax 				=   {x=999,	y=999,	z=999}
		, 	vmin 				=   {x=-999,y=-999,	z=-999}
		, 	vdamp 			=   {x=1, 	y=1,	z=1}

		, 	default 		= 	obj.default or nil
		, 	panim       =   ""
		, 	anim        =   obj.default or obj2.default
		, 	frame       =   1
		, 	frame2      =   1
		, 	frame3      =   1
		, 	fps         =   24
		, 	tick        =   0
		, 	animTime 		=   0
		, 	playbackSpeed = 1
		, 	playing = true


		, 	color 			= 	{r=1,g=1,b=1,a=1}
		, 	brightness  =   1

		,  planePos1 		= {}
		,  planePos2 		= {}

		, 	curve       =   obj.curve or nil

		, 	opacity     =   1
		, 	img         =   obj2.image
		, 	thumb       =   getImageThumb(obj.key)

		, 	paths       =   obj.paths       or {}
		, 	ramps       =   obj.ramps       or {}
		, 	floors      =   obj.floors      or {}

		, 	parent      =   obj.parent      or {id="", d=0, r=0, rl=0, r2=0}
		, 	parentE     =   nil

		, 	delete      =   false
		, 	onstage     =   true
		, 	simple      =   obj.simple      
		, 	life        =   obj.life        or nil
		, 	lifespan    =   obj.lifespan    or nil
		, 	particle    =   obj.life 
		, 	spinEnabled =   obj.spinEnabled or false

		, 	index       =   obj.i           or i
		, 	i 					= 	#room.entities+1
		, 	time 				=  	0

		, 	scripts  		=   obj.scripts  or {}
		, 	variables   =   obj.variables   or {}
		, 	emitter     =   obj.emitter     or {}
		, 	wobbles 		= 	obj.wobbles 	or {}
		, 	plane 			=  	{}
		, 	children 		= 	{}
		, 	shapes      =   {}
		, 	fdata       =   {}
		, 	sdata       =   {}
		, 	adata       =   {}
		, 	shpdata     =   {}
		, 	bounds      =   {{0,0,0,0,0,0}}
		,	transferring = false
	}

	entity.layer = entity.surface and -0.25 or 0
	entity.nextScale     	=   vec3(obj.scale 		)
	entity.nextOrientation =   quat(obj.orientation)
	entity.nextPosition 		= 	vec3(obj.position  )

	entity.pos = entity.position

	entity.transferring =false
	entity.prev 		={x=entity.x,y=entity.y,z=entity.z}

	startZ  		   =    entity.z	
	entity.prevZ   	   =    entity.z

	entity.oscale      =    entity.scale    
	entity.oangle      =    entity.angle 
	entity.ox          =    entity.x
	entity.oy          =    entity.y
	entity.oz          =    entity.z
	

	if not (entity.particle) then 
		scene.setPlayer       (entity)
		scene.computePath     (entity)
		scene.addPlanes  			(entity)
	end
	
	
	scene.setScripts      (entity)


	entity.models 	= {}


	if entity.simple then 
		-- entity.models 			= {{nocopy=true,mesh=editor.simpleMesh,transform=mat4(),parent=entity}}
	end

	scene.updateEntityAnimData(entity)

	entity:updateTransform()


	if obj.dropped then 
		scene.orientEntity(entity,editor.dropMode or "camera")
	end
	
	table.insert(room.entities, entity)
	room.entitiesByID[entity.uid] = entity
	
	return entity
end

function scene.orientEntity(entity,mode)
	if mode == "camera" then 
		entity:rotate(cam.angle.y,"x")
		entity:rotate(cam.angle.x,"y")
	elseif mode == "camera x" then 
		entity:rotate(cam.angle.x,"y")
	elseif mode == "surface" then 
		log("normalll",editor.intersectNormal)
		entity:rotate(math.angle(0,0,math.dist(0,0,editor.intersectNormal.x,editor.intersectNormal.z),editor.intersectNormal.y),"x")
		entity:rotate(math.angle(0,0,editor.intersectNormal.x,editor.intersectNormal.z)+pi/2,"y")
		entity:move(-editor.intersectNormal*0.2)
		entity.surface = true
	end
end


function editor.newEntity(key,props) 

	local obj 	= {
		key 	 			=	key ,
		x 		 			=	0	,
		y 		 			=	0	,
		z 	 				=	0 ,
	}

	for k, o in pairs( props or {} ) do
		if type(o)=="table" then 
			for j, t in pairs(o) do
				if obj[k] then 
					obj[k][j] = t
				end
			end
		else 
			obj[k] = o
		end
	end

	return scene.newEntity(obj)
end


function scene.returnObject(entity)
	local obj = {
			name 	 		= entity.name 
		, key 		= entity.key	
		,	default 	= entity.default 
		,	x 		 		= entity.position.x or entity.x		
		,	y 		 		= entity.position.y or entity.y
		,	z 	 			= entity.position.z or entity.z		
		, position  = entity.position or {x=entity.x,y=entity.y,z=entity.z}--entity.position:clone()
		,	orientation = {x=entity.orientation.x,y=entity.orientation.y,z=entity.orientation.z,w=entity.orientation.w} 
		,	scale 	 		= {x=entity.scale.x or 1,y=entity.scale.y or 1,z=entity.scale.z or 1} 

		, static 		= entity.static
		, visible 		= entity.visible
		, gravity 		= entity.gravity
		, light 			= entity.light
		, surface 			= entity.surface
		, castShadow  = entity.castShadow
		, recieveShadow  = entity.recieveShadow
		
		,	parent 		= entity.parentE and {id=entity.parent.id,ptype=entity.parent.ptype} or nil	
		,	uid 			= entity.uid 		

		,	paths 		= lume.count(entity.paths)				~= 0 and entity.paths or nil
		,	scripts 	= lume.count(entity.scripts) 			~= 0 and deepcopy(entity.scripts)	or nil
		,	variables = lume.count(entity.variables)  	~= 0 and deepcopy(entity.variables)	or nil
		,	emitter 	= lume.count(entity.emitter)			~= 0 and deepcopy(entity.emitter) 	or nil
	}
	return obj
end

function scene.returnSimpleObject(entity)
	local obj 	= deepcopy(scene.returnObject(entity))
	obj.paths 	= nil
	obj.simple 	= true
	obj.parent 	= nil
	return obj
end




