sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.6a introduces important bugfixes for Fredo's Extensions Update

    Help: Plug in bug

    Scheduled Pinned Locked Moved Developers' Forum
    1 Posts 1 Posters 458 Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • genma saotomeG Offline
      genma saotome
      last edited by

      I'm not a programmer and I need some help fixing a ruby plug-in. The author wrote it largely as an educational exercise (it seemed to work as he now has a job with a cad company) and he is no longer available to deal with this problem. It's a simple export to game format plug-in with one flaw: it doesn't export the correct position of a manually moved texture when the poly displaying that texture is in a component. If the poly is not in a component, any adjustment to the textures position exports properly.

      I'd would be very grateful if someone here was willing to take a look at the code and see if the problem jumps out / is easilly corrected.

      WRT copyright: Any suggested fix will be returned to the author (on the chance he wants it). I'll edit my own copy for my own use.

      ###======================================================
      # Copyright © 2006-2008. All rights reserved.
      # version 1.0 24th June 2006.
      # version 1.3 29/2/2008 - adjusted for polymaster
      
      ###======================================================
      # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
      # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      #-----------------------------------------------------------------------------
      
      require "3dmath.rb"
      
      
      #####################################################
      # Single class instance
      class SFile
       attr_accessor ;name, ;fileName, ;newFolder, ;fh , ;specular, ;message
      
      	# scan the model groups for geometry
      	def scanModel1(startEnt,parentSeg,dlevel,trans,lay)
      		
      		showFaces=true
      		
      		# if component instance, set grp to be the definition
      		grp=startEnt
      		if(grp.kind_of? Sketchup;;ComponentInstance) then
      			# matrix id
      			id=parentSeg
      			trans=Geom;;Transformation.new() if not trans
      			trans =  trans * grp.transformation
      			# get component definition
      			grp = grp.definition
      		else
      			# grp could be a group or a model
      			#
      			# @lastMatrixid is nil for first LOD, 0+ for later passes
      			if @lastMatrixid then
      				id=@lastMatrixid
      				oMatrix=@matrices[id]
      				@lastMatrixid+=1
      			else
      				oMatrix=Matrix.new()
      				oMatrix.polys=0
      		
      				if(grp.kind_of? Sketchup;;Model) then
      					oMatrix.name = "main"
      				else
      					oMatrix.name=grp.name.tr(" ","_")
      				end
      				
      				oMatrix.name="default" if oMatrix.name.length==0
      				
      				oMatrix.name = "x" + oMatrix.name if oMatrix.name =~ /^\d/
      				if parentSeg>=0 then
      					# get the transform matrix
      					oMatrix.setFromSU startEnt.transformation.to_a
      				end
      				
      				# count faces
      				
      				id=@matrices.length
      				
      				@matrices.push oMatrix
      			end
      			# if group lod
      			if id>0 then
      				showFaces=(dlevel==0 or grp.lod==0 or grp.lod >= lay)
      			end
      			@distance_levels[dlevel].hierarchy.push parentSeg
      		end
      		
      		# scan faces
      		if showFaces then
      			for ent in grp.entities
      				if(ent.kind_of? Sketchup;;Face) then
      					if dlevel==0 or ent.lod==0 or ent.lod >= lay then
      						scanVerts ent,id,startEnt,dlevel,trans
      					end
      				end
      			end
      		end
      		
      		# recursive call to sub groups
      		for ent in grp.entities
      		
      			# scan sub groups
      			if(ent.kind_of? Sketchup;;Group)
      				scanModel1 ent, id,dlevel,trans,lay
      				
      			# don't show instances if group is disabled
      			elsif( ent.kind_of? Sketchup;;ComponentInstance and showFaces )
      				# ignore component if it'd LOD is not visible
      				if dlevel==0 or ent.lod==0 or ent.lod >= lay then
      					scanModel1 ent, id,dlevel,trans,lay
      				end
      				
      			elsif( ent.kind_of? Sketchup;;ComponentDefinition )
      				scanModel1 ent, id,dlevel,trans,lay
      				
       			end
      		end
      	end
      	
      	# save the vertices for a face
      	def scanVerts(o,id,ent,dlevel,trans)
      		# o is a face
      		# ent - original entity
      		
      		mf=o.material
      		mb=o.back_material
      		scaleu,scalev,shade1,shade2=nil,nil,nil,nil
      		polys=0
      		
      		# get the instance material if definition material is nil
      		if not mf 
      			mf=ent.material if ent.kind_of? Sketchup;;ComponentInstance
      			if mf and mf.texture then
      				scaleu=mf.texture.width.inch
      				scalev=mf.texture.height.inch
      			end
      		end
      		
      		mat,matb=nil,nil
      		uvhelp=o.get_UVHelper(true, true, @tw)
      		
      		subobj1=@distance_levels[dlevel].sub_objects.at(0)
      		subobj2=subobj1
      
      		mesh = o.mesh 7
      		p1,p2,p3 = 0
      		pr2,fNormal2,shade2,pstat2,vst2,lmc2,vset2,nx2=nil,nil,nil,nil,nil,nil,nil,nil
      		pr1,fNormal1,shade1,pstat1,vst1,lmc1,vset1,nx1=nil,nil,nil,nil,nil,nil,nil,nil
      		
      		if mf or not mb
      			fNormal1=findItem(o.normal,@normals)
      			# use front face material		
      			mat = findTexture(mf)
      			
      			shade1=findShader(mf)
      			lmc1=findLightCnf(shade1)
      			vst1=findVState(mf,id,lmc1)
      			
      			# calc prim_state
      			ps=SPState.new()
      			ps.shader=shade1
      			ps.lightCfg=lmc1
      			ps.vState=vst1
      			ps.tex_idxs.push mat if mat
      			# gloss
      			if @light_model_cfgs.at(lmc1)==2 then
      				img=@images.index("env_map.ace")
      				# compare image properties
      				ps.tex_idxs.push @textures.index(img)
      			end
      
      
      			# no material alpha is for solid/transparent
      			# alpha of 99% is for alpha but no sub-object
      			# 98% and lower will create a sub-object for alpha sorting
      			
      			if mf
      				# set alphatest to 1 for transparent, 0 for solid or alpha
      				if mf.texture
      					stex =  mf.texture.filename.upcase
      					if stex.index(".TGA") then
      						ps.alphatestmode=1
      					end
      				end
      				if mf.alpha < 1.0
      					ps.alphatestmode=0
      					ps.priority=mf.alpha*100
      					if ps.priority<99
      						subobj1=setSubObj(dlevel)
      					end
      				end
      			end
      	
      	
      	
      			pstat1=findItem(ps,@prim_states)
      			
      			findItem shade1,subobj1.shaders
      			findItem lmc1,subobj1.lightcfgs
      			
      			vset=SVtxset.new(vst1)
      			vset1=findItem(vset,subobj1.vtx_sets)
      			
      			node= SGeomnode.new(id)
      			nx1=findItem node,subobj1.geometry_nodes
      			findItem pstat1,subobj1.geometry_nodes[nx1].pStates
      			
      			pr1=getPrim(subobj1,vset1,pstat1)
      		end
      		
      		if mb
      			fNormal2=findItem(o.normal.reverse,@normals)
      			matb=findTexture(mb)
      			shade2=findShader(mb)
      			lmc2=findLightCnf(shade2)
      			vst2=findVState(mb,id,lmc2)
      
      			# calc prim_state
      			ps=SPState.new()
      			ps.shader=shade2
      			ps.lightCfg=lmc2
      			ps.vState=vst2
      			ps.tex_idxs.push matb if matb
      			
      			if @light_model_cfgs.at(lmc2)==2 then
      				img=@images.index("env_map.ace")
      				# compare image properties
      				ps.tex_idxs.push @textures.index(img)
      			end
      			
      			# set alphatest to 1 for transparent, 0 for solid or alpha
      			if mb.texture
      				stex =  mb.texture.filename.upcase
      				if stex.index(".TGA") then
      					ps.alphatestmode=1
      				end
      			end
      			
      			if mb.alpha < 1.0 
      				ps.alphatestmode=0
      				ps.priority=mb.alpha*100
      				if ps.priority<99
      					subobj2=setSubObj(dlevel)
      				end
      			end
      			pstat2=findItem(ps,@prim_states)
      		
      			findItem shade2,subobj2.shaders
      			findItem lmc2,subobj2.lightcfgs
      			vset=SVtxset.new(vst2)
      			vset2=findItem(vset,subobj2.vtx_sets)
      			
      			node= SGeomnode.new(id)
      			nx2=findItem node,subobj2.geometry_nodes
      			findItem pstat2,subobj2.geometry_nodes[nx2].pStates
      			
      			pr2=getPrim(subobj2,vset2,pstat2)
      		end
      		
      		1.upto(mesh.count_polygons) do |j|
      			p3,p2,p1 = mesh.polygon_at(j)
      			
      			p1 = p1.abs
      			pt1=mesh.point_at p1
      			p2 = p2.abs
      			pt2=mesh.point_at p2
      			p3 = p3.abs
      			pt3=mesh.point_at p3
      			if trans
      				pt1.transform! trans
      				pt2.transform! trans
      				pt3.transform! trans
      			end
      			
      			# make sure we have a triangle
      			if  not pt3.on_line? [pt1,pt2]
      			
      				if mf or not mb
      					@bb.add pt1
      					@bb.add pt2
      					@bb.add pt3
      					if mat
      						uv1=uvhelp.get_front_UVQ pt1
      						uv1.x/=scaleu if scaleu
      						uv1.y/=scalev if scalev
      					
      						uv2=uvhelp.get_front_UVQ pt2
      						uv2.x/=scaleu if scaleu
      						uv2.y/=scalev if scalev
      					
      						uv3=uvhelp.get_front_UVQ pt3
      						uv3.x/=scaleu if scaleu
      						uv3.y/=scalev if scalev
      					else
      						uv1,uv2,uv3=nil,nil,nil
      					end
      					pn=mesh.normal_at(p1)
      					pn.transform! trans if trans
      					pr1.vert_idxs.push storeVertex(subobj1,pt1,pn,uv1,vset1)
      					pn=mesh.normal_at(p2)
      					pn.transform! trans if trans
      					pr1.vert_idxs.push storeVertex(subobj1,pt2,pn,uv2,vset1)
      					pn=mesh.normal_at(p3)
      					pn.transform! trans if trans
      					pr1.vert_idxs.push storeVertex(subobj1,pt3,pn,uv3,vset1)
      					
      					subobj1.faceNormals +=1
      					polys+=1
      					pr1.normal_idxs.push fNormal1
      					subobj1.geometry_nodes[nx1].count+=1
      					
      					#print uv1.to_s + "\n" + uv2.to_s + "\n" + uv3.to_s + "\n"
      				end
      				if mb then
      					if matb
      						uv1=uvhelp.get_back_UVQ pt1
      						uv2=uvhelp.get_back_UVQ pt2
      						uv3=uvhelp.get_back_UVQ pt3
      					else
      						uv1,uv2,uv3=nil,nil,nil
      					end
      					
      					# adjust order if reflected odd number of times
      					if trans
      						if trans.to_a[0]*trans.to_a[5]*trans.to_a[10]<0
      							p3,p1=p1,p3
      							uv3,uv1=uv1,uv3
      							pt3,pt1=pt1,pt3
      						end
      					end
      					
      					# reverse order
      					pn=mesh.normal_at(p3).reverse
      					pn.transform! trans if trans
      					pr2.vert_idxs.push storeVertex(subobj2,pt3,pn,uv3,vset2)
      					pn=mesh.normal_at(p2).reverse
      					pn.transform! trans if trans
      					pr2.vert_idxs.push storeVertex(subobj2,pt2,pn,uv2,vset2)
      					pn=mesh.normal_at(p1).reverse
      					pn.transform! trans if trans
      					pr2.vert_idxs.push storeVertex(subobj2,pt1,pn,uv1,vset2)
      					
      					#print uv1.to_s + "\n" + uv2.to_s + "\n" + uv3.to_s + "\n"
      
      					subobj2.faceNormals +=1
      					polys+=1
      					pr2.normal_idxs.push fNormal2
      					subobj2.geometry_nodes[nx2].count+=1
      				end
      			end
      		end
      		@matrices[id].polys+=polys if dlevel==0
      	end
      	
      	def storeVertex(so,p,n,u,vset)
      		
      		ip=findItem(p,@points)
      		ix=findItem(n,@normals)
      		iu=findItem(u,@uv_points)
      		vert=SVertex.new
      		vert.pointIdx=ip
      		vert.normalIdx=ix
      		vert.vertex_uvs.push iu if u
      	
      		findItem(vert,so.vtx_sets[vset].vertices)
      	end
      	
      	def setSubObj(dl)
      		if @distance_levels[dl].sub_objects.length==1 then
      			so=SSObject.new()
      			@distance_levels[dl].sub_objects.push so
      			so.flags="00000500"
      			so.vol=0
      			return so
      		else
      			return @distance_levels[dl].sub_objects[1]
      		end
      	end
      
      	def getPrim(so,vs,ps)
      		prim=SPrimitive.new
      		prim.primstate=ps
      		x=so.vtx_sets[vs]
      		
      		# 2 primitive entries
      		prind=findItem prim,x.primitives
      		
      		if prind==(x.primitives.length-1) then
      			x.primitives.push SPrimitive.new()
      		end
      		
      		prind+=1
      		pr=x.primitives[prind]
      		while pr.normal_idxs.length>2700 and not pr.primstate do
      			# at very end - add new one
      			if prind==(x.primitives.length-1) then
      				x.primitives.push SPrimitive.new()
      			end
      			prind+=1
      			pr=x.primitives[prind]
      		end
      		if pr.primstate then
      			x.primitives[prind]=[SPrimitive.new(),pr]
      			x.primitives.flatten!
      		end
      		return x.primitives[prind]
      	end
      
      
      	def findTexture(m)
      		if m and m.texture 
      			img=findImage(m.texture)
      		end
      		if not(img) 
      			return nil
      		end
      		# compare image properties
      		0.upto(@textures.length-1) do |e|
      			if @textures.at(e).img==img
      				return e
      			end
      		end
      		
      		t=STex.new(img)
      		
      		n=m.name.upcase.index("/BIAS")
      		t.mipbias=m.name[n+5..n+7].to_i if n
      		
      		@textures.push t
      		return @textures.length-1
      		
      	end
      
      	# used for points, normals, UV points and other objects that support ==
      	def findItem(v,array)
      		if not v 
      			return nil
      		end
      		return array.addSearch(v)
      	end
      
      
      	# find vstate from material
      	def findVState(m,id,cnf)
      		vs=SVState.new(id)
      		vs.lightCfg=cnf
      		stex=""
      		if m
      			if m.name.upcase.index("HISHINE")
      				vs.lightMat=-6
      				@specular=true
      			elsif m.name.upcase.index("LOSHINE")
      				vs.lightMat=-7
      				@specular=true
      			elsif m.name.upcase.index("AMBIENT")
      				vs.lightMat=-9
      			elsif m.name.upcase.index("DARKSHADE")
      				vs.lightMat=-12
      			elsif m.name.upcase.index("HALFBRIGHT")
      				vs.lightMat=-11
      			end
      			
      			if m.texture then 
      				stex=m.texture.filename
      			end
      		end
      				#'''''' color of material
      		if m then
      			if stex.length==0 
      				col = m.color
      			end
      		else
      			col = Sketchup.active_model.rendering_options["FaceFrontColor"]
      		end
      		
      		# new colour and light material
      		if col then
      			if @colours.length==0
      				# add black & white
      				findItem(Sketchup;;Color.new(0,0,0),@colours)
      				findItem(Sketchup;;Color.new(255,255,255),@colours)
      			end
      			c1=findItem(col,@colours)
      			lm=c1.to_s + " " + c1.to_s + " 1 0 0"
      			vs.lightMat = findItem(lm,@light_materials)
      		end
      
      		return findItem(vs,@vtx_states)
      	end
      
      	# find shader from material
      	def findShader(m)
      		if m and m.texture
      			stex =  m.texture.filename.upcase
      			s="Tex"
      			s << "Diff" if not m.name.upcase.index("BRIGHT")
      			if stex.index(".TGA") then 
      				s="BlendA" + s
      			end
      			if m.name.upcase.index("GLOSS") then 
      				s="GlossMap"
      				img=@images.addSearch("env_map.ace")
      				# compare image properties
      				0.upto(@textures.length-1) do |e|
      					if @textures.at(e).img==img
      						return @shader_names.addSearch(s)
      					end
      				end		
      				t=STex.new(img)
      				t.mipbias=0
      				@textures.push t
      			end
      		else
      			s="Diffuse"
      		end
      		
      		return @shader_names.addSearch(s)
      	end
      
      	# given a shader index, find the light config
      	def findLightCnf(s)
      		cn=1
      		cn=2 if @shader_names.at(s)=="GlossMap"
      		cn=3 if @shader_names.at(s).index("Bumpmap")
      		cn=4 if @shader_names.at(s)=="Diffuse"
      		return @light_model_cfgs.addSearch(cn)
      	end
      
      	# find image ID
      	def findImage(t)
      		i=t.filename.rindex("\\")
      		i=-1 if not i
      		s=t.filename[i+1..t.filename.rindex(".")].upcase << "ACE"
      		return @images.addSearch(s)
      	end
      	
      
      
      	#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      
      	# perform the actual file save
      	def saveS()
      		# unicode file
      		@fh.write "\377\376"
      		$\="\015\012"
      		@fh.uprintln "SIMISA@@@@@@@@@@JINX0s1t______"
      		@fh.uprintln ""
      		@fh.uprintln "shape ("
      		
      		
      		shape_header
      		volumes
      		shader_names
      		texture_filter_names
      		points
      		uv_points
      		normals
      		sort_vectors
      		colours
      		matrices
      		images
      		textures
      		light_materials
      		light_model_cfgs
      		vtx_states
      		prim_states
      		lod_controls
      		
      		animations if @anim_nodes.length>0
      		
      		@fh.uprint ")"
      		@fh.close
      	end
      
      	def	shape_header
      		@fh.uprintln "\tshape_header sketchup20 ( 00000000 00000000 )"
      	end
      	
      	def vector(v)
      		@fh.uprint "vector ( "
      		@fh.uprint v.x.to_m.fix.to_s + " "
      		@fh.uprint v.z.to_m.fix.to_s + " "
      		@fh.uprint v.y.to_m.fix
      		@fh.uprintln " )"
      	end
      
      	def normal(v)
      		@fh.uprint "vector ( "
      		@fh.uprint v.x.fix.to_s + " "
      		@fh.uprint v.z.fix.to_s + " "
      		@fh.uprint v.y.fix
      		@fh.uprintln " )"
      	end
      
      	def vol_sphere(v,r)
      		$\=nil
      		@fh.uprint "\t\tvol_sphere ( \015\012\t\t\t"
      		vector v
      		$\="\015\012"
      		@fh.uprintln " " + r.to_m.fix.to_s
      		@fh.uprintln "\t\t)"
      	end
      
      	def volumes
      		@fh.uprint "\tvolumes ( "
      		@fh.uprintln @volumes
      		vol_sphere @bb.center, @bb.diagonal/2.0
      		@fh.uprintln "\t)"
      	end
      	
      	def named_shader(s)
      		@fh.uprintln "\t\tnamed_shader ( " + s + " )"
      	end
      	
      	def shader_names
      		@fh.uprint "\tshader_names ( "
      		@fh.uprintln @shader_names.length
      		@shader_names.each { |s| named_shader s }
      		@fh.uprintln "\t)"				
      	end
      	
      	def	texture_filter_names
      		@fh.uprint "\ttexture_filter_names ( "
      		@fh.uprintln 1
      		@fh.uprintln "\t\tnamed_filter_mode ( MipLinear )"
      		@fh.uprintln "\t)"		
      	end
      	
      	def point(v)
      		@fh.uprint "\t\tpoint ( " + v.x.to_m.fix.to_s + " " + v.z.to_m.fix.to_s + " " + v.y.to_m.fix.to_s
      		@fh.uprintln " )"
      	end
      
      	def	points
      		@fh.uprint "\tpoints ( "
      		@fh.uprintln @points.length
      		@points.each { |e| point e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def uv_point(v)
      		@fh.uprintln "\t\tuv_point ( " + v.x.fix.to_s + " " + (-v.y.fix).to_s + " )"
      	end
      
      	def	uv_points
      		@fh.uprint "\tuv_points ( "
      		@fh.uprintln @uv_points.length
      		@uv_points.each { |e| uv_point e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def	normals
      		@fh.uprint "\tnormals ( "
      		@fh.uprintln @normals.length
      		@normals.each { |e| @fh.uprint "\t\t"; normal e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def	sort_vectors	
      		@fh.uprintln "\tsort_vectors ( 0 )"
      	end
      	
      	def colour(v)
      		@fh.uprintln "\t\tcolour ( " + (v.alpha/255.0).to_s + " " + (v.red/255.0).to_s + " " + (v.green/255.0).to_s  + " " + (v.blue/255.0).to_s + " )"
      	end
      
      	def	colours
      		@fh.uprint "\tcolours ( "
      		@fh.uprintln @colours.length
      		@colours.each { |e| colour e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def matrix(v)
      		
      		@fh.uprint "\t\tmatrix "
      		@fh.uprint v.name
      		@fh.uprint " ( "
      		@fh.uprint v.m[0].fix.to_s + " " + v.m[1].fix.to_s + " " + v.m[2].fix.to_s + " "
      		@fh.uprint v.m[4].fix.to_s + " " + v.m[5].fix.to_s + " " + v.m[6].fix.to_s + " "
      		@fh.uprint v.m[8].fix.to_s + " " + v.m[9].fix.to_s + " " + v.m[10].fix.to_s + " "
      		@fh.uprintln v.m[12].to_m.fix.to_s + " " + v.m[13].to_m.fix.to_s + " " + v.m[14].to_m.fix.to_s + " )"
      		
      		@message << v.name + " " + v.polys.to_s + " Polygons " + (v.polys>2700 ? "<< Primitives split\n" ; "\n")
      		
      	end
      	
      	def	matrices
      		@message="Groups ;\n"
      		@fh.uprint "\tmatrices ( "
      		@fh.uprintln @matrices.length
      		@matrices.each { |e| matrix e }
      		@fh.uprintln "\t)"
      	end
      	
      	def image(v)
      		@fh.uprint "\t\timage ( "
      		@fh.uprint v
      		@fh.uprintln " )"
      	end
      	
      	def	images
      		@fh.uprint "\timages ( "
      		@fh.uprintln @images.length
      		@images.each { |e| image e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def texture(v)
      		@fh.uprint "\t\ttexture ( "
      		@fh.uprint v.to_s
      		@fh.uprintln " ff000000 )"	
      	end
      	
      	def	textures
      		@fh.uprint "\ttextures ( "
      		@fh.uprintln @textures.length
      		@textures.each { |e| texture e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def light_material(v)
      		@fh.uprint "\t\tlight_material ( 00000000 "
      		@fh.uprint v
      		@fh.uprintln " )"		
      	end
      	
      	def	light_materials
      		@fh.uprint "\tlight_materials ( "
      		@fh.uprintln @light_materials.length
      		@light_materials.each { |e| light_material e }
      		@fh.uprintln "\t)"		
      	end
      	
      	def light_model_cfg(v)
      	
      		case v
      		when 1   #  single stage
      			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
      			@fh.uprintln "\t\t\tuv_ops ( 1"
      			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
      			@fh.uprintln "\t\t\t)"
      			@fh.uprintln "\t\t)"
      		when 2  # GlossMap
      			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
      			@fh.uprintln "\t\t\tuv_ops ( 2"
      			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
      			@fh.uprintln "\t\t\t\tuv_op_reflectmapfull ( 1 )"
      			@fh.uprintln "\t\t\t)"
      			@fh.uprintln "\t\t)"
      		when 3  # 3 stage bump maps
      			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
      			@fh.uprintln "\t\t\tuv_ops ( 3"
      			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
      			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
      			@fh.uprintln "\t\t\t\tuv_op_reflectmapfull ( 1 )"
      			@fh.uprintln "\t\t\t)"
      			@fh.uprintln "\t\t)"
      		when 4   #  no texture or uv
      			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
      			@fh.uprintln "\t\t\tuv_ops ( 0 )"
      			@fh.uprintln "\t\t)"
      		end
      	
      	end
      	
      	def	light_model_cfgs
      		@fh.uprint "\tlight_model_cfgs ( "
      
      		@fh.uprintln @light_model_cfgs.length
      		@light_model_cfgs.each { |e| light_model_cfg e }
      
      		@fh.uprintln "\t)"		
      	end
      	
      	def vtx_state(v)
      		@fh.uprint "\t\tvtx_state ( 00000000 "
      		@fh.uprint v.to_s
      		@fh.uprintln " 00000002 )"	
      	end
      	
      	def	vtx_states
      		@fh.uprint "\tvtx_states ( "
      
      		@fh.uprintln @vtx_states.length
      		@vtx_states.each { |e| vtx_state e }
      
      		@fh.uprintln "\t)"		
      	end
      	
      	def prim_state(v)
      		@fh.uprint "\t\tprim_state " + @matrices[@vtx_states[v.vState].matrix].name + "_Prim" + v.sequence.to_s + " ( 00000000 "
      		@fh.uprint v.to_s
      		@fh.uprintln " 1\n\t\t)"	
      	end
      	
      	def	prim_states
      		@fh.uprint "\tprim_states ( "
      		@fh.uprintln @prim_states.length
      		seq=0
      		# sort the states in order, and sort the sequence
      		100.downto(96) do |pri|
      			@prim_states.each do |e|
      				if e.priority==pri
      					e.sequence=seq
      					seq+=1
      					prim_state e
      				end
      			end
      		end
      		@prim_states.each do |e|
      			if e.priority<97
      				prim_state e
      				e.sequence=seq
      				seq+=1
      			end
      		end		
      		@fh.uprintln "\t)"		
      	end
      	
      	def geometry_node(v)
      		@fh.uprintln "\t\t\t\t\t\t\t\t\t\tgeometry_node ( 1 0 0 0 0"
      		@fh.uprintln "\t\t\t\t\t\t\t\t\t\t\tcullable_prims ( " + v.pStates.length.to_s + " " + v.count.to_s + " " + (v.count*3).to_s + " )"
      		@fh.uprintln "\t\t\t\t\t\t\t\t\t\t)"
      	end
      	
      	def vertex(v)
      		v.uprint @fh
      	end
      	
      	def vertex_set(v,cnt)
      		@fh.uprintln "\t\t\t\t\t\t\t\tvertex_set ( " + v.vtx_state.to_s + " " + cnt.to_s + " " + v.vertices.length.to_s + " )"
      		
      	end
      	
      	def primitive(v,cnt)
      		v.offset=cnt
      		if v.primstate then
      			@fh.uprintln "\t\t\t\t\t\t\t\tprim_state_idx ( " + @prim_states[v.primstate].sequence.to_s + " )"
      		else
      			v.uprint @fh
      		end
      	end
      	
      	def sub_object(v)
      		@fh.uprintln "\t\t\t\t\t\tsub_object ( "
      		@fh.uprintln "\t\t\t\t\t\t\tsub_object_header ( " + v.flags + " " + v.sortVector.to_s + " " + v.vol.to_s + " 000001d2 " + v.destFlag
      		@fh.uprintln "\t\t\t\t\t\t\t\tgeometry_info ( " + v.faceNormals.to_s + " " + v.vtx_sets.length.to_s + " 0 " + (v.faceNormals*3).to_s + " 0 0 " + (v.primitives/2).to_s + " 0 0 0"
      		@fh.uprint "\t\t\t\t\t\t\t\t\tgeometry_nodes ( "
      		@fh.uprintln v.geometry_nodes.length
      
      		v.geometry_nodes.each { |e| geometry_node e }
      		
      		@fh.uprintln "\t\t\t\t\t\t\t\t\t)"
      		#							geometry_node_map ( 1 0 )
      		@fh.uprint "\t\t\t\t\t\t\t\t\tgeometry_node_map ( "
      		@fh.uprint @matrices.length
      		0.upto(@matrices.length-1) do |e|
      			@fh.uprint " "
      			ind=v.geometry_nodes.index(SGeomnode.new(e))
      			@fh.uprint ind ? ind ; -1
      		end
      		@fh.uprintln " )"
      
      		@fh.uprintln "\t\t\t\t\t\t\t\t)"
      		
      		#						subobject_shaders ( 1 0 )
      		@fh.uprint "\t\t\t\t\t\t\t\tsubobject_shaders ( "
      		@fh.uprint v.shaders.length
      		v.shaders.each { |e| @fh.uprint " "; @fh.uprint e }
      		@fh.uprintln " )"
      
      		#						subobject_light_cfgs ( 1 0 ) 0
      		@fh.uprint "\t\t\t\t\t\t\t\tsubobject_light_cfgs ( "
      		@fh.uprint v.lightcfgs.length
      		v.lightcfgs.each { |e| @fh.uprint " "; @fh.uprint e }
      		@fh.uprintln " ) " + v.id.to_s
      
      		@fh.uprintln "\t\t\t\t\t\t\t)"
      		@fh.uprint "\t\t\t\t\t\t\tvertices ( "
      		@fh.uprintln v.vertices
      
      		v.vtx_sets.each { |x| x.vertices.each { |e| vertex e } }
      		
      		@fh.uprintln "\t\t\t\t\t\t\t)"
      
      		@fh.uprint "\t\t\t\t\t\t\tvertex_sets ( "
      		@lastv=0
      		@fh.uprintln v.vtx_sets.length
      		count=0
      		v.vtx_sets.each { |e| vertex_set e,count ; count+=e.vertices.length }
      		
      		@fh.uprintln "\t\t\t\t\t\t\t)"
      
      
      		@fh.uprint "\t\t\t\t\t\t\tprimitives ( "
      		@fh.uprintln v.primitives
      		
      		count=0
      		v.vtx_sets.each { |x| x.primitives.each { |e| primitive e,count} ; count+=x.vertices.length }
      
      		@fh.uprintln "\t\t\t\t\t\t\t)"
      		# end of sub_object
      		@fh.uprintln "\t\t\t\t\t\t)"
      
      	end
      	
      	def distance_level(v)
      	
      		@fh.uprintln "\t\t\t\tdistance_level ( "
      		@fh.uprintln "\t\t\t\t\tdistance_level_header ("
      		@fh.uprint "\t\t\t\t\t\tdlevel_selection ( "
      		@fh.uprint v.distance
      		@fh.uprintln " )"
      		
      		@fh.uprint "\t\t\t\t\t\thierarchy ( "
      		@fh.uprint v.hierarchy.length
      		v.hierarchy.each { |e| @fh.uprint " "; @fh.uprint e }
      		@fh.uprintln " )"
      		
      		@fh.uprintln "\t\t\t\t\t)"		
      
      		@fh.uprint "\t\t\t\t\tsub_objects ( "
      		@fh.uprintln v.sub_objects.length
      		v.sub_objects.each { |e| sub_object e }
      		@fh.uprintln "\t\t\t\t\t)"		
      
      		@fh.uprintln "\t\t\t\t)"		
      	
      	end
      	
      	def lod_control
      		@fh.uprintln "\t\tlod_control ("
      		@fh.uprintln "\t\t\tdistance_levels_header ( 0 )"
      		@fh.uprint "\t\t\tdistance_levels ( "
      		@fh.uprintln @distance_levels.length
      		
      		@distance_levels.each { |e| distance_level e }
      
      		@fh.uprintln "\t\t\t)"
      		@fh.uprintln "\t\t)"
      	end
      	
      	def	lod_controls
      		@fh.uprintln "\tlod_controls ( 1"
      		lod_control
      		@fh.uprintln "\t)"		
      	end
      	
      	def anim_node(v)
      		@fh.uprint "\t\t\t\tanim_node "
      		@fh.uprint v.name
      		@fh.uprintln " ("
      		
      		# still to do
      		
      		@fh.uprintln "\t\t\t\t)"
      	end
      	
      	def	animations
      		@fh.uprintln "\tanimations ( 1"
      		@fh.uprintln "\t\tanimation ( " + @keys.to_s + " " + @fps.to_s
      		@fh.uprint "\t\t\tanim_nodes ( "
      		
      		@fh.uprint @anim_nodes.length
      		@anim_nodes.each { |e| anim_node e }
      		
      		@fh.uprintln "\t\t\t)"
      		@fh.uprintln "\t\t)"
      		@fh.uprintln "\t)"		
      	end
      
      
      	# on creation of the TMXfile object
      	def initialize(model,file)
      		# set a few properties
      		@model=model
      		@name=model.title
      		@fileName=file
      		@shader_names=[]
      		@points=[]
      		@normals=[]
      		@uv_points=[]
      		@matrices=[]
      		@colours=[]
      		@images=[]
      		@textures=[]
      		@light_materials=[]
      		@light_model_cfgs=[]
      		@vtx_states=[]
      		@prim_states=[]
      		@distance_levels=[]
      		@anim_nodes=[]
      		@keys=8
      		@fps=30
      		@specular=false
      		@fh = File.new(file,"wb")
      		
      		if @fh then
      			@tw = Sketchup.create_texture_writer
      			# get model bound box
      			@bb=model.bounds
      			@volumes=1
      			# add a single distance level
      			@distance_levels.push SDLevel.new()
      			# add first sub-object
      			@distance_levels[0].sub_objects.push SSObject.new()
      			l=@model.lods[0]
      			@distance_levels[0].distance=l
      			print "\nLOD #{l} 0"
      			# scan the model geometry
      			@lastMatrixid=nil
      			scanModel1(model,-1,0,nil,l)
      			
      			# more layers?
      			1.upto(@model.lods.length-1) do |lay|
      				@lastMatrixid=0
      				l=@model.lods[lay]
      				# add a single distance level
      				@distance_levels.push SDLevel.new()
      				dl=@distance_levels.length-1
      				# add first sub-object
      				@distance_levels[dl].sub_objects.push SSObject.new()
      				# adjust previous DL
      				@distance_levels[dl].distance=l
      				print "\nLOD #{l} #{dl}"
      				scanModel1(model,-1,dl,nil,l.to_i)
      			end
      			
      			
      			# sum up vertices and primitives
      			@distance_levels.each do |dl|
      				dl.sub_objects.each do |so|
      					so.vtx_sets.each do |v|
      						so.vertices+=v.vertices.length
      						so.primitives+=v.primitives.length
      					end
      					if @specular
      						if so.flags=="00000400"
      							so.flags="00000000"
      						else
      							so.flags="00000100"
      						end
      					end
      				end
      			end
      		end
      		# model processing finished - time to save the S file
      	end
      	
      	def saveSD()
      		@fh = File.new(@fileName + "D","wb")
      		# unicode file
      		@fh.write "\377\376"
      		$\="\015\012"
      		@fh.uprintln "SIMISA@@@@@@@@@@JINX0s1t______"
      		@fh.uprintln ""
      		@fh.uprint "shape ( "
      		s=@fileName
      		i=s.rindex("\\")
      		s=s[(i+1)..s.length] if i
      		@fh.uprintln s
      		@fh.uprintln "    ESD_Detail_Level (0)"
      		@fh.uprintln "    ESD_Software_DLev (0)"
      		@fh.uprintln "    ESD_Alternative_Texture (0)"
      		@fh.uprintln "    ESD_Bounding_Box ( " + @bb.min.x.fix.to_m.to_s + " " + @bb.min.z.fix.to_m.to_s + " " + @bb.min.y.fix.to_m.to_s + " " + @bb.max.x.fix.to_m.to_s + " " + @bb.max.z.fix.to_m.to_s + " " + @bb.max.y.fix.to_m.to_s + " )"
      		@fh.uprintln ")"
      		@fh.close()
      	end
      end
      
      
      
      ####################################################################
      # add unicode write to File class
      class File
      	def uprint(s)
      		# print unicode version of ascii
      		s.to_s.each_byte { |c| write [c,0].pack("cc") } if s
      	end
      	def uprintln(s)
      		uprint s
      		uprint $\ if $\
      	end
      end
      
      ####################################################################
      # used by textures array
      class STex
      	attr_accessor ;img,;filter,;mipbias
      	def initialize(id)
      		@mipbias = -3
      		@filter=0
      		@img=id
      	end
      	def to_s
      		@img.to_s + " " + @filter.to_s + " " + @mipbias.to_s
      	end
      end
      
      ####################################################################
      # used by vtx_states
      class SVState
      	attr_accessor ;matrix,;lightMat,;lightCfg
      	def initialize(id)
      		@lightCfg=0
      		@lightMat=-5
      		@matrix=id
      	end
      	def ==(vs)
      		return (@lightMat==vs.lightMat and @lightCfg == vs.lightCfg and @matrix==vs.matrix)
      	end
      	def to_s
      		@matrix.to_s + " " + @lightMat.to_s + " " + @lightCfg.to_s
      	end
      end
      
      ####################################################################
      # prim state
      class SPState
      	attr_accessor ;shader, ;tex_idxs,;zBias,;vState,;alphatestmode,;lightCfg,;priority,;sequence
      	def initialize
      		@tex_idxs=[]
      		@zBias=0
      		@priority=100
      		@alphatestmode=0
      	end
      	
      	def ==(o)
      		if @tex_idxs.length>0
      			return false if @tex_idxs.length!=o.tex_idxs.length
      			return false if @tex_idxs[0]!=o.tex_idxs[0]
      		end
      		return (@shader==o.shader and @vState==o.vState and @alphatestmode==o.alphatestmode and @lightCfg==o.lightCfg)
      	end
      	
      	def to_s
      		s=@shader.to_s + "\n\t\t\ttex_idxs ( " + @tex_idxs.length.to_s
      		tex_idxs.each { |e| s << " " << e.to_s  }
      		s << " ) " + @zBias.to_s + " " + @vState.to_s + " " + @alphatestmode.to_s + " " + @lightCfg.to_s
      	end
      end
      ####################################################################
      class SDLevel
      	attr_accessor ;distance, ;hierarchy,;sub_objects
      	def initialize
      		@hierarchy=[]
      		@distance=2000
      		@sub_objects=[]
      	end
      end
      
      ####################################################################
      class SSObject
      	attr_accessor ;vertices,;primitives,;vtx_sets,;sortVector,;vol,;destFlag,;flags,;faceNormals,;txLightCmds,;trilistIdxs,;trilists,;geometry_nodes,;lightcfgs,;shaders,;id
      	def initialize
      		@vertices=0
      		@primitives=0
      		@vtx_sets=[]
      		@sortVector=-1
      		@vol=-1
      		@destFlag="000001c4"
      		@flags="00000400"
      		@geometry_nodes=[]
      		@lightcfgs=[]
      		@shaders=[]
      		@id=0
      		@faceNormals=0
      		@txLightCmds=0
      		@trilistIdxs=0
      		@trilists=0
      	end
      end
      ####################################################################
      class SVertex
      	attr_accessor ;pointIdx, ;normalIdx ,;colour1,;colour2, ;vertex_uvs
      	def initialize
      		@vertex_uvs=[]
      		@colour1="ffffffff"
      		@colour2="ff000000"
      	end
      	def ==(o)
      		if @vertex_uvs.length>0
      			return false if @vertex_uvs.length!=o.vertex_uvs.length
      			return false if @vertex_uvs[0]!=o.vertex_uvs[0]
      		end
      		return (@pointIdx==o.pointIdx and @normalIdx==o.normalIdx)
      	end
      	def uprint(fh)
      		fh.uprint "\t\t\t\t\t\t\t\tvertex ( 00000000 " + @pointIdx.to_s + " " + @normalIdx.to_s + " " + @colour1 + " " + @colour2 + "\n\t\t\t\t\t\t\t\t\t vertex_uvs ( " + @vertex_uvs.length.to_s
      		@vertex_uvs.each { |e| fh.uprint " " + e.to_s }
      		fh.uprintln " )\n\t\t\t\t\t\t\t\t)"
      	end
      end
      
      class SVtxset
      
      	attr_accessor ;vtx_state,  ;vertices, ;primitives
      	
      	def initialize(vs)
      		@vtx_state=vs
      		@vertices=[]
      		@primitives=[]
      	end
      	def ==(o)
      		return @vtx_state==o.vtx_state
      	end
      end
      
      
      ####################################################################
      class SGeomnode
      	attr_accessor ;pStates, ;count,;matrix
      	def initialize(id)
      		@pStates=[]
      		@count=0
      		@matrix=id
      	end
      	def ==(o)
      		return (@matrix == o.matrix)
      	end
      end
      
      ####################################################################
      class SPrimitive
      	attr_accessor ;vert_idxs, ;normal_idxs, ;primstate, ;offset
      	def initialize
      		@vert_idxs=[]
      		@normal_idxs=[]
      	end
      	def ==(o)
      		return @primstate==o.primstate
      	end
      	def uprint(fh)
      		fh.uprintln "\t\t\t\t\t\t\t\tindexed_trilist ("
      		fh.uprint "\t\t\t\t\t\t\t\t\tvertex_idxs ( " + @vert_idxs.length.to_s
      		width=0
      		@vert_idxs.each do |e|
      			fh.uprint " " + (e+@offset).to_s
      			if width>1000 then
      				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
      				width=0
      			else
      				width+=e.to_s.length
      			end
      		end
      		fh.uprintln " )"
      		fh.uprint "\t\t\t\t\t\t\t\t\tnormal_idxs ( " + @normal_idxs.length.to_s
      		
      		width=0
      		@normal_idxs.each do |e|
      			fh.uprint " " + e.to_s + " 3"
      			if width>1000 then
      				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
      				width=0
      			else
      				width+=e.to_s.length
      			end
      		end
      		fh.uprintln " )"
      		
      		fh.uprint "\t\t\t\t\t\t\t\t\tflags ( " + @normal_idxs.length.to_s
      		width=0
      		@normal_idxs.each do |e|
      			fh.uprint " 00000000"
      			if width>1000 then
      				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
      				width=0
      			else
      				width+=9
      			end
      		end
      		
      		fh.uprintln " )"
      		fh.uprintln "\t\t\t\t\t\t\t\t)"
      	end
      end
      ####################################################################
      # extend 3dmath class matrix
      class Matrix
      	# add name attribute
      	attr_accessor ;name,;polys
      	# copy array to matrix (from SU transromation.to_a
      	def setFromSU(mIn)
      		@m=mIn
      		# swap 2nd/3rd rows and cols
      		@m[2],@m[1]=@m[1],@m[2]
      		@m[10],@m[5]=@m[5],@m[10]
      		@m[14],@m[13]=@m[13],@m[14]
      		@m[4],@m[8]=@m[8],@m[4]
      		@m[6],@m[9]=@m[9],@m[6]
      		@m[7],@m[11]=@m[11],@m[7]
      	end
      end
      ####################################################################
      class Numeric
      	# use 6 decimal places only
      	def fix
      		(self*1000000.0).to_i.to_f/1000000.0
      	end
      end
      
      ####################################################################
      # return index, but add if not found in array
      class Array
      	def addSearch(s)
      		e=index(s)
      		if e then
      			return e
      		else
      			push s
      			return length-1
      		end
      	end
      end
      
      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Buy SketchPlus
      Buy SUbD
      Buy WrapR
      Buy eBook
      Buy Modelur
      Buy Vertex Tools
      Buy SketchCuisine
      Buy FormFonts

      Advertisement