{"id":8668,"date":"2024-03-29T16:22:21","date_gmt":"2024-03-29T16:22:21","guid":{"rendered":"https:\/\/www.katsbits.com\/codex\/?p=8668"},"modified":"2024-04-04T16:10:22","modified_gmt":"2024-04-04T15:10:22","slug":"export-map-blender","status":"publish","type":"post","link":"https:\/\/www.katsbits.com\/codex\/export-map-blender\/","title":{"rendered":"MAP Prep &#038; Export (*.map) files from Blender"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-light-blue ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69fe1af49f5d5\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69fe1af49f5d5\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#description\" >Description<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#blender-compatibility\" >Blender Compatibility<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#radiant-grid-setup\" >Radiant Grid Setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#blender-grid-setup\" >Blender Grid Setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#inverted-faces\" >Inverted Faces<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#generic-map-export-settings\" >Generic Map Export Settings<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.katsbits.com\/codex\/export-map-blender\/#timestamps\" >Timestamps<\/a><\/li><\/ul><\/nav><\/div>\n<div style=\"background-color: black; position: relative; padding-bottom: 56.25%; padding-top: 25px; height: 0; overflow: hidden; max-width: 100%;\"><center><iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%;\" src=\"https:\/\/rumble.com\/embed\/v4k6b78\/?pub=d3lcu\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/center><\/div>\n<h3><span class=\"ez-toc-section\" id=\"description\"><\/span>Description<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>IN this exercise we&#8217;ll take a look at using Blender to make levels to be exported as <strong>*.map<\/strong> files using the third-party <a href=\"https:\/\/github.com\/c-d-a\/io_export_qmap\" rel=\"noopener\" target=\"_blank\">Blender MAP Export script<\/a>. First the *.py <strong>Python<\/strong> script is downloaded and installed using <a href=\"https:\/\/www.katsbits.com\/codex\/user-preferences\/\">Blender Preferences<\/a>. Once installed, following some basic rules to ensure compatibility, a test level is created from a number of mesh primitive objects that will become Brush Volumes once exported to MAP file.<\/p>\n<p><b>Duration<\/b>: total c. 35 mins (00:35:00).<br \/>\n<b>Info<\/b>: 1080p.<br \/>\n<b>Suitability<\/b>: Beginner+.<br \/>\n<b>Source<\/b>: <a href=\"https:\/\/www.katsbits.com\/files\/blender\/katsbits - example map.zip\">KatsBits \u2013 Example Map<\/a> (c. 200 KB | *.blend, *.map).<br \/>\n<b>Product ID<\/b>: n\/a.<\/p>\n<blockquote style=\"background-color: #ddecf3; color: #000;\"><p><b>Download<\/b>: <a href=\"https:\/\/github.com\/c-d-a\/io_export_qmap\" rel=\"noopener\" target=\"_blank\">Blender MAP Export script<\/a> (external link).<\/p><\/blockquote>\n<blockquote><p><strong>Design note<\/strong>: depending on the editing environment being used, some trial and error may be required to export a fully compatible *.map file. To assist in making levels in Blender use the <a href=\"https:\/\/www.katsbits.com\/files\/blender\/katsbits_map-entity-kit.zip\">Radiant Entity Kit<\/a>.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"blender-compatibility\"><\/span>Blender Compatibility<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Although <strong>Blender 3.6 LTS<\/strong> was used throughout the <a href=\"https:\/\/github.com\/c-d-a\/io_export_qmap\" rel=\"noopener\" target=\"_blank\">Blender MAP Export script<\/a> is compatible with Blender 2.83 or above, including Blender 4.(x). To verify, install the script and perform a simple test export.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"radiant-grid-setup\"><\/span>Radiant Grid Setup<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Most *.map and *.bsp level editing tools use an environment defined by the &#8216;<em>power of two rule<\/em>&#8216;, so 2, 16, 64, 512 etc, all generally divisible, and using a minimum object size of 8 units (smaller can be used but are generally to be discouraged). This essentially means one minor grid subdivision is 8 units on the XYZ, one larger subdivision is 64 units or 8 x 1 minor division on the XYZ (8 x 8 units = 64 units).<\/p>\n<p><a href=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/radiant-unit-scale.jpg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" style=\"width: 98.5%; height: auto;\" src=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/radiant-unit-scale.jpg\" alt=\"Radiant grid scale\" width=\"900px\" height=\"500px\" border=\"0\" \/><\/a><br \/>\n<i>The default grid setup in GtkRadiant is 8 x 8 units.<\/i><\/p>\n<h4><span class=\"ez-toc-section\" id=\"blender-grid-setup\"><\/span>Blender Grid Setup<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>To replicate Radiant, or other similar editors grid in Blender, ensure Units is set to None so the grid subdivisions can be changed &#8211; this is crucial to match up between Blender and Radiant et al. In <strong>Scene Properties<\/strong> make sure <strong>Unit System<\/strong> is set to <strong>None<\/strong> [1] (Metric default is Metric). Then in Viewport Overlays change both <strong>Scale<\/strong> and <strong>Subdivisions<\/strong> to &#8220;<strong>8<\/strong>&#8221; [2] &#8211; <strong>Scale: 8<\/strong>, <strong>Subdivisions: 8<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/blender-grid-scale.jpg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" style=\"width: 98.5%; height: auto;\" src=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/blender-grid-scale.jpg\" alt=\"Blender grid scale\" width=\"900px\" height=\"500px\" border=\"0\" \/><\/a><br \/>\n<i>Mirroring Radiants grid and units of measurement in Blender by setting <strong>None<\/strong> [1] as the <strong>Unit System<\/strong> then changing grid <strong>Scale<\/strong> and <strong>Subdivisions<\/strong> [2].<\/i><\/p>\n<h4><span class=\"ez-toc-section\" id=\"inverted-faces\"><\/span>Inverted Faces<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Typically maps are built using a lot of object duplication, flipping and mirroring. Doing so however tends to cause issues insomuch as mesh faces can be inverted or flipped inside-out [3] when transforms are applied. When this happens face <strong>Normals<\/strong> have to be reverted so they all faces outwards for valid brush volume generation. To do this, select the object and in <strong>Edit Mode<\/strong> select the offending face(s), or select everything &#8211; <strong><em>Select \u00bb All<\/em><\/strong> (<span class=\"shortcutkey\">A<\/span>), then from the <strong>Mesh<\/strong> menu select <strong>Normals<\/strong>, <strong>Flip<\/strong>, or <strong>Recalculate Outside<\/strong> [4] to force everything to point outwards &#8211; <strong><em>Mesh \u00bb Normals \u00bb Flip<\/em><\/strong>\/<strong><em>Recalculate Outside<\/em><\/strong>.<\/p>\n<div style=\"background-color: #eee; color: #000; width:98.5%; padding: 1.0em;\">By default material render two-sided so any face orientation issues won&#8217;t be immediately noticeable. To address this, in <strong>Material Properties<\/strong>, enable <strong>Backface Culling<\/strong> in <strong>Settings<\/strong>, or enable <a href=\"https:\/\/www.katsbits.com\/codex\/flip-normals\/\">Face Orientation<\/a> in Viewport Overlays.<\/div>\n<p><a href=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/flip-faces-outside.jpg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" style=\"width: 98.5%; height: auto;\" src=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/flip-faces-outside.jpg\" alt=\"[descriptive alt image text here]\" width=\"900px\" height=\"500px\" border=\"0\" \/><\/a><br \/>\n<i>Inverted faces [3] need to be fixed to ensure valid brush volumes are generated during export. This can be done using <strong>Flip<\/strong> or <strong>Recalculate Outside<\/strong> [4], forcing faces to point in the right direction, outwards.<\/i><\/p>\n<h4><span class=\"ez-toc-section\" id=\"generic-map-export-settings\"><\/span>Generic Map Export Settings<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>When exporting meshes and other objects from Blender, either; 1) select only those parts that are to be included in the *.map file, or optionally 2) delete unwanted items. The settings used to export a properly compatible *.map file [5] will vary depending on the editing environment being exported to. For generic &#8216;idTech&#8217; for example, these might be (<em><strong>bold<\/strong><\/em> highlights are important);<\/p>\n<p><strong>Checkboxes<\/strong><br \/>\n &#8211; <strong>Selection Only<\/strong><br \/>\n &#8211; <strong>Apply transforms<\/strong><br \/>\n &#8211; <strong>Apply modifiers<\/strong><\/p>\n<p><strong>Object types<\/strong><br \/>\n &#8211; <strong>Mesh: Brush<\/strong><br \/>\n &#8211; Nurbs: Ignore<br \/>\n &#8211; Lights: Ignore (if not present)<br \/>\n &#8211; Empty: Ignore (if not used)<\/p>\n<p><strong>Coordinates<\/strong><br \/>\n &#8211; <strong>Grid: 8.00<\/strong><br \/>\n &#8211; <strong>Depth: 0.00<\/strong><br \/>\n &#8211; Scale: 1.00<br \/>\n &#8211; Precision: 5<\/p>\n<p><strong>Output format<\/strong><br \/>\n &#8211; <strong>Planes: Quake<\/strong><br \/>\n &#8211; <strong>UVs: Standard<\/strong><br \/>\n &#8211; Flags: None<br \/>\n &#8211; <strong>Output: File<\/strong><\/p>\n<p>Miscellaneous<br \/>\n &#8211; Grouping: Generic<br \/>\n &#8211; Class: func_group<br \/>\n &#8211; Material: skip (or caulk)<br \/>\n &#8211; Tex size: 64<\/p>\n<p><a href=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/generic-map-export-options.jpg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" style=\"width: 98.5%; height: auto;\" src=\"https:\/\/www.katsbits.com\/images\/tutorials\/map-editing\/generic-map-export-options.jpg\" alt=\"Generic map export settings\" width=\"900px\" height=\"500px\" border=\"0\" \/><\/a><br \/>\n<i>Export options [5] vary depending on the editing environment being used. For Radiant ensure <strong>Brush<\/strong> is set as the <strong>Mesh<\/strong> type.<\/i>\n<\/p><\/blockquote>\n<h3><span class=\"ez-toc-section\" id=\"timestamps\"><\/span>Timestamps<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Times are approximate;<br \/>\n&#8211; 00:00 : Overview &#038; Install<br \/>\n&#8211; 02:00 : Units, Grid &#038; Snap<br \/>\n&#8211; 08:00 : Valid Objects &#038; Example<br \/>\n&#8211; 18:00 : Materials &#038; Caulk<br \/>\n&#8211; 25:00 : Object Prep &#038; Export<br \/>\n&#8211; 29:00 : Radiant Editor Import<\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":8671,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,237,230],"tags":[1078,522,72,720,380,79,1079,1081,1056,1083,1082,1080,695,286,393],"class_list":["post-8668","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blender","category-misc3d","category-tutorials","tag-map","tag-blender-preferences","tag-export","tag-face-orientation","tag-flip-normal","tag-import","tag-level-design","tag-level-editor","tag-py","tag-python","tag-quark","tag-radiant","tag-scene-properties","tag-units","tag-units-of-measurement"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/posts\/8668","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/comments?post=8668"}],"version-history":[{"count":17,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/posts\/8668\/revisions"}],"predecessor-version":[{"id":8693,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/posts\/8668\/revisions\/8693"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/media\/8671"}],"wp:attachment":[{"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/media?parent=8668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/categories?post=8668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.katsbits.com\/codex\/wp-json\/wp\/v2\/tags?post=8668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}