sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Help: Plug in bug

    Scheduled Pinned Locked Moved Developers' Forum
    1 Posts 1 Posters 439 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