Better Inf map editing with sketchup

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Silver_Ibex

Member
Feb 27, 2001
654
0
16
While chatting on IRC I saw this posted during a discussion of better optimizing of workflow in Ued with external modeling programs, it is a handy ruby script for exporting multiple brushes out of Ued so they can be edited in Sketchup with less work then exporting them one at a time.

To make a new Ruby file, do the following
In your Google Sketchup plugins folder, make a new txt file and rename it “Ued_T3D_Multi-Brush_Import.rb”
And then copy and past into it the code below and save the file.

Code:
#===========================================================================================
# Ued_T3D_Multi-Brush_Import.rb                                                            
#===========================================================================================
# This script lets Ued mappers build better custom complex  
# brushes for their maps with the help of Sketchup.
# 
# Place this file in Sketchup "plugins" folder.
#
#
#
# To use follow these mapping steps. 
# 
# 1. Load your map in Ued. 
# 
# 2. Select the brushes you want to export in your map then 
#    invert the selection and delete everything else in the map.
# 
# 3. To make the exported file smaller/faster you can rebuild 
#    the paths (this is to clear the paths out so they don’t get 
#    exported as part of the .t3d file).
# 
# 4. Select all brushes and chose “transform permanently” (the 
#    Sketchup importer does not see any temporary transform 
#    scaling and rotations).
# 
# 5. You can rebuild the geometry and fix or align textures now 
#    if you want.     
# 
# 6. Export the map as a .t3d file.
# 
# 7. In Sketchup, chose import file type "Ued T3D Level File",
#    and you should then be able to open your .t3d file.
# 
# 8. Have fun :)  
# 
# 9. to get the stuff back out of Sketchup and back into Ued, 
#    use Google Sketchup T3D/PSK Exporter for UT3/UT2K4/UT2K3 
#    - HSKP2UNR found at 
#    http://forums.epicgames.com/showthread.php?t=619593 
# 
class Polygon
  def initialize(texname)
    @vertices = []
    @origin = nil
    @texname = texname
  end

  def parse(line)
    if (m = line.match(/Origin(.*),(.*),(.*)/i))
      @origin = Geom::Point3d.new Float(m[1]), Float(m[2]), Float(m[3])
    elsif (m = line.match(/Normal(.*),(.*),(.*)/i))
      @normal = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
    elsif (m = line.match(/TextureU(.*),(.*),(.*)/i))
      @texu = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
    elsif (m = line.match(/TextureV(.*),(.*),(.*)/i))
      @texv = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
    elsif (m = line.match(/Vertex(.*),(.*),(.*)/i))
      @vertices.push(Geom::Point3d.new(Float(m[1]), Float(m[2]), Float(m[3])))
    elsif line.match(/End Polygon/i)
      return true
    end
    return false
  end

  def build(transform, group)
    wverts = []
    uvs = []
    idx = 0
    if @vertices.length <= 3
      @vertices.each {|x|
        wverts.push(x.transform(transform))
      }
    else
        wverts.push(@vertices[0].transform(transform))
        wverts.push(@vertices[1].transform(transform))
        wverts.push(@vertices[2].transform(transform))
        v1 = wverts[1] - wverts[0]
        v2 = wverts[2] - wverts[0]
        n = v1.cross(v2)
        plane = [wverts[0], n]
        @vertices.each {|x|
          v = x.transform(transform)
          wverts.push(v.project_to_plane(plane))
        }
    end
    uvs.push(@origin.transform(transform))
    uvs.push(Geom::Point3d.new(0, 0, 0))
    u = @origin + @texu
    v = @origin + @texv
    uvs.push(u.transform(transform))
    uvs.push Geom::Point3d.new(1, 0, 0)
    uvs.push(v.transform(transform))
    uvs.push Geom::Point3d.new(0, 1, 0)
    face = group.entities.add_face wverts
    @texname = "default" if not @texname
    mat = Sketchup.active_model.materials[@texname]
    if not mat
      mat = Sketchup.active_model.materials.add @texname
      mat.texture = @texname + ".jpg"
      if not mat.texture
        file = Sketchup.find_support_file "default.png", "Plugins/"
        mat.texture = file
      end
    end
    face.material = mat
    face.position_material(face.material, uvs, true)
    face.position_material(face.material, uvs, false)
  end
end

class Brush
  def initialize(name)
    @group = Sketchup.active_model.entities.add_group
    @group.name = name
    @polygons = []
  end

  def parse(line)
    if @polygon
      if @polygon.parse(line)
        @polygon = nil
      end
      return false
    end
    if line.match(/Begin Polygon/i)
      m = line.match(/Texture=([._A-Za-z0-9]+)/)
      if m
        texname = m[1]
      else
        texname = "default"
      end
      @polygon = Polygon.new(texname)
      @polygons.push(@polygon)
    elsif line.match(/End Brush/i)
      return true
    end
    return false
  end

  def build(transform)
    @polygons.each { |poly|
      poly.build(transform, @group)
    }
  end
end

class Actor
  def initialize(name)
    @name = name
    @unit_adjust = Geom::Transformation.scaling(0.749906262,-0.749906262,0.749906262)
    @main_scale = Geom::Transformation.new
    @pre_pivot = Geom::Transformation.new
              @location = Geom::Transformation.new
    @brushes = []
  end

  def parse(line)
    if @brush
      if @brush.parse(line)
        @brush = nil
      end
      return false
    end
    if line.match(/OldLocation/)
      # Explicitly skip this
      return false
    elsif line.match(/Location/)
      pos = [0.0, 0.0, 0.0]
      m = line.match(/X=([-0-9.]*)/)
      pos[0] = Float(m[1]) if m
      m = line.match(/Y=([-0-9.]*)/)
      pos[1] = Float(m[1]) if m
      m = line.match(/Z=([-0-9.]*)/)
      pos[2] = Float(m[1]) if m
      @location = Geom::Transformation.translation(Geom::Vector3d.new(pos[0], pos[1], pos[2]))
    elsif line.match(/PrePivot/)
      pos = [0.0, 0.0, 0.0]
      m = line.match(/X=([-0-9.]*)/)
      pos[0] = Float(m[1]) if m
      m = line.match(/Y=([-0-9.]*)/)
      pos[1] = Float(m[1]) if m
      m = line.match(/Z=([-0-9.]*)/)
      pos[2] = Float(m[1]) if m
      @pre_pivot = Geom::Transformation.translation(Geom::Vector3d.new(-pos[0], -pos[1], -pos[2]))
    elsif line.match(/MainScale/)
      scale = [1.0, 1.0, 1.0]
      m = line.match(/X=([-0-9.]*)/)
      scale[0] = Float(m[1]) if m
      m = line.match(/Y=([-0-9.]*)/)
      scale[1] = Float(m[1]) if m
      m = line.match(/Z=([-0-9.]*)/)
      scale[2] = Float(m[1]) if m
      @main_scale = Geom::Transformation.scaling scale[0], scale[1], scale[2]
    elsif line.match(/PostScale/)
      scale = [1.0, 1.0, 1.0]
      m = line.match(/X=([-0-9.]*)/)
      scale[0] = Float(m[1]) if m
      m = line.match(/Y=([-0-9.]*)/)
      scale[1] = Float(m[1]) if m
      m = line.match(/Z=([-0-9.]*)/)
      scale[2] = Float(m[1]) if m
      elsif line.match(/Begin Brush/i)
      name = line.match(/NAME=([^\\b]*)/i)[1]
      @brush = Brush.new(name)
      @brushes.push(@brush)
    elsif line.match(/End Actor/i)
      return true
    end
    return false
  end

  def build
    transform = @unit_adjust * @location * @pre_pivot * @main_scale
    @brushes.each { |brush|
      brush.build(transform)
    }
  end
end

class UDKImporter < Sketchup::Importer
  def description
    return "Ued T3D Level File (*.t3d)"
  end

  def file_extension
    return "t3d"
  end

  def id
    return "com.tosos.sketchup.importers.UDK"
  end

  def supports_options?
    return false
  end

  def do_options
  end

  def parse_line(line)
    if @actor
      if @actor.parse(line)
        @actor = nil
      end
      return
    end
    if line.match(/Begin Actor/i)
      name = line.match(/NAME=([^\\b]*)/i)[1]
      @actor = Actor.new(name)
      @actors.push(@actor)
    end
  end

  def load_file(file_path, status)
    @actors = []

    File.open(file_path, "r") do |infile|
      while (line = infile.gets)
        parse_line line
      end
      @actors.each { |a|
       a.build
      }
      @actors = nil
      return 0
    end

    return 1
  end
end

Sketchup.register_importer(UDKImporter.new)
 

Corporal_Lib [BR]

Brazilian Graphic Designer & Gun Nut {=)
After all Inigo weapon releases, a Silver_Ibex map would breath a lil life to INF´s community... a map or that HUMVEE driveable in INF that could save a lot of COOP time or even better, a huuuge map, with your photorealistc landscape technique and scripted Humvees to transport the players around multiple objectives (an EAS map for sure...)

OK, just excuse my daydreaming, but I was aching to ask ya that ;D
 

Silver_Ibex

Member
Feb 27, 2001
654
0
16
Thought I should post a pic showing what imported and edited brushes look like in Sketchup, since they are imported as separate objects they can be moved around and adjusted in Sketchup, unlike HSKP2UNR which merges brushes on import into one object.

Sketchup is Free, and is extremely powerful for fast editing of brushes made in Ued, the plug-in allows multiple brushes to be imported into Sketchup and then selectively joined or split at will (use the “Explode” and “Make Group” options), brush faces can be modified with far more freedom then standard Ued, you can literally draw new features on the faces of a brush in Sketchup.

In Sketchup the grid scale options need set up to match an external editor like is talked about the page of this article here
http://www.maximumpc.com/article/howtos/howto_make_left_4_dead_map_using_google_sketchup?page=0,4

The one small problem I have with the plug-in is faces on imported brushes sometimes face the wrong way and some may need flipped before you export them back out of Sketchup. This is not a real big deal, just something to watch out for.

For a fast start, the Google Sketchup tutorial videos are a must watch.
 

Attachments

  • HouseTest.jpg
    HouseTest.jpg
    41 KB · Views: 40