-
Notifications
You must be signed in to change notification settings - Fork 67
249 How It Works Materials
The material model from 2.49 is very different from 2.7x's file.
- XPlaneExport.py
- line 269-475, definition of getTextures and checkdup
- XPlaneExport8_util.py
- line 182, definition of DEFMAT
- line 349-408, class definition of Prim (the heart of the obj exporter)
- line 574-618, OBJexport8.init's definitions of a bunch of class attributes and state variables
- line 1190-1501, sortMesh (collection of data)
- line 1223-1248, finding material props
- lines 1262, 1276, important looking lines
- line 1293-1348, finding face props
- line 1391-1514, more of the same as 1293-1348?
- line 1642-1984, XPlaneExport8_util.updateAttr - the thing that actually writes ATTRs
- XPlaneMat2Tex.py, only a helper script. Doesn't help much, except with intentions?
- XPlanePanelRegions.py, dialog box to interact with PanelRegionHandler in XPlaneUtils.py
- XPlaneUtils.py
- line 718, def tex_exists (but we might not need this)
- Make your Mesh
- Make your UV unwrap
- Do your made artistry, save a .png, .dds. (.bmp is only used in X-Plane 7)
- Assign this texture to your mesh's UV
Although you can have multiple UVs per object (Mesh > Data > UV Texture > Click New), only the active will be used. Some artists use this as part of a texture baking flow.
- Make a mesh
- Unwrap it anyway you're going to
- Go into the UV/Image Editor, assign an image from disk
- You can make another by going to Buttons > Data > Editing (aka Data in 2.7x) > Mesh > UV Texture (But again, we only ever use the active one)
The exporter finds this texture on disk, but can also look for _LIT
and _NML
files (hard-coded case sensitive names, looked up with os.path.exists)
If encountered it turns on normal and lit stuff.
For instance, this set: {tex.png, tex_LIT.png, tex_NML.png}
- Do the regular steps 1-4
- Give the object a game property (any type, any value) call "ATTR_draped"
- Select your draped face and change the texture to your draped texture (no name requirements)
- Go to Buttons > Data > Editing and ensure "Tex" and "Tiles" are checked.
- There is no
_LIT
texture lookup because draped texture can't be_LIT
XPlaneExport.py
def getTexture(...):
...
if objType == "Mesh":
mesh=object.getData(mesh=True)
if isLight(...)
# Custom light stuff
....
elif mesh.faceUV: # Blender 2.49 api, a bool. "The mesh contains UV-mapped textured faces."
#print '%s (%d)' % (object.getName(), len(mesh.faces))
for face in mesh.faces:
has_draped = (face.mode&Mesh.FaceModes.TILES) and has_prop(object,'ATTR_draped')
if (face.mode&Mesh.FaceModes.TEX) and face.image and has_draped == want_draped:
# Draped stuff
...
else:
#face.image.filename is the file from the UV/Image editor's editor
#thisdir is the dir of the blend file
#texture by this point is None
#texlist = []
texture=checkdup(face.image.filename, thisdir, texture, texlist, multierr, object)
texlist at this point will have multiple textures and we do..... nothing with it!
Materials are far less used in 2.49. They are only used (per object or, gulp, per face) for specific buttons and setting the Specularity slider. A material's texture is ignored (unlike 2.7x)
A list of buttons that concern us:
2.49 Location | 2.49 API Name | 2.7x Material Location* | Blender 2.7x API Name |
---|---|---|---|
Texture Face > Tex | Mesh.FaceModes.TEX | Hidden, material.c, line 1856 | Not exposed*** |
Texture Face > Tiles | Mesh.FaceModes.TILES | Parse name, find flag | Not exposed*** |
Texture Face > Light | Mesh.FaceModes.LIGHT | Hidden, material.c, line 1862 | Not exposed*** |
Texture Face > Invisible | Mesh.FaceModes.INVISIBLE | Game Settings > Invisible | game_settings.invisible |
Texture Face > Collision | Mesh.FaceModes.DYNAMIC | [ ] Physics | game_settings.physics |
Texture Face > Two Side | Mesh.FaceModes.TWOSIDE | Game Settings > Backface Culling | game_settings.use_backface_culling |
Texture Face > Shadow | Mesh.FaceModes.SHADOW | Game Settings > Face Orientation > Shadow | game_settings.face_orientation = "SHADOW" |
2.49 Location | 2.49 API Name | 2.7x Material Location* | Blender 2.7x API Name |
---|---|---|---|
Texture Face > Alpha | Mesh.FaceTranspModes.ALPHA | Game Settings > Alpha Blend > Alpha | game_settings.alpha_blend = "ALPHA" |
Texture Face > Clip Alpha | Mesh.FaceTranspModes.CLIP | Game Settings > Alpha Blend > Alpha Clip? | game_settings.alpha_blend = "CLIP" |
*Texture Face = Select Mesh > Edit Mode > Select Face > Editing (aka Data) > Texture Face
**Blender's Render Engine must be "Blender Game" to see it in the UI
***See blender/blenkernel/intern/material.c
, lines 1834 to 1869 for whats really up! By using CTypes we can get
the real value per face.
All in XPlaneExport8_util.py
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
558 | if TEX |
TEX must be active to get the image for the face | None/exporter internals |
1276 | if TEX |
TEX takes UV from face's UV for VT table | None/exporter internals |
1474 | if TEX |
TEX takes UV from face's UV for VT table | None/exporter internals |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1320, 1416 | if TEX and f.transp == Mesh.FaceTranspModes.ALPHA and has_prop("ATTR_shadow_blend") |
Writes ATTR_shadow_blend 0.5 (default) |
mat.xplane.blend_v1000 = "shadow" |
1322, 1419 | if TEX and f.transp == Mesh.FaceTranspModes.ALPHA and has_prop("GLOBAL_shadow_blend") |
Writes GLOBAL_shadow_blend 0.5 (default) |
mat.xplane.blend_v1000 = "shadow" |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1327, 1424 | if TEX and f.transp == Mesh.FaceTranspModes.CLIP and has_prop("ATTR_no_blend") |
Writes ATTR_no_blend 0.5 (default) |
mat.xplane.blend_v1000 = "off" |
1327, 1426 | if TEX and f.transp == Mesh.FaceTranspModes.CLIP and has_prop("GLOBAL_no_blend") |
Writes GLOBAL_no_blend 0.5 (default) |
mat.xplane.blend_v1000 = "off" |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1343+ | if TEX and self.ispanelok and mode&Mesh.FaceModes.TEX |
Sets flags and regions | None? |
1347 | if TEX and f.image and 'panel.' in f.image.name.lower() |
Sets PANEL, enables others to write ATTR_(no)_cockpit , ATTR_cockpit_region , ATTR_manip_panel
|
line 1338-1341, 1435-1438 (repeats because of giant if hasanim block {?})
2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|
if not ISCOCKPIT and (has TILES or LIGHT) and no "ATTR_draped" |
Writes ATTR_poly_os 2 and resets to ATTR_poly_os 0
|
mat.xplane.poly_os = 2 (see line 1752) |
if not ISCOCKPIT and (has TILES or LIGHT) and "ATTR_draped" |
Writes ATTR_draped
|
mat.xplane.draped = True |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1266 | if not INVISIBLE |
Prevents geometry for this {face? This Object?} from becoming part of VT Table | mat.xplane.draw = False, a small performance hit until we can implement #409 |
1300, 1396 | if not INVISIBLE, append material |
write ATTR_diffuse_rgb, ATTR_emission_rgb, ATTR_shiny_rat | if INVISIBLE we don't get to here anyway |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1350, 1447 | if not INVISIBLE and not self.iscockpit and (self.additive_lod or object.Layer&1) and not DYNAMIC |
DYNAMIC = True by default, DYNAMIC = False semantically means on. Writes, ATTR_hard
|
mat.xplane.solid_camera = True |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
1334, 1431 | if TWOSIDE write ATTR_cull |
writes ATTR_cull | None. We don't use ATTR_cull or ATT_no_cull. Easy! |
Line # | 2.49 Use | 2.49 Effect | 2.78 Use |
---|---|---|---|
903 | if instanced and not DRAPED and SHADOW, set GLOBAL_no_shadow | None, we turn on GLOBAL_no_shadow differently | |
1354, 1452 | if SHADOW | Writes ATTR_shadow
|
We don't have ATTR_shadow! |
has_prop | type | default | Dest |
---|---|---|---|
'GLOBAL_no_blend' | float-like | 0.5 | Force "Instanced Scenery", make something "ATTR_no_blend" (maybe make a new empty "FORCE_GLOBALS" to fake it during conversion?) |
'GLOBAL_specular' | anything (but hopefully a float-like) | 'XXX' | Force "Instanced Scenery" |
'GLOBAL_shadow_blend' | float-like | 0.5 | Force "Instanced Scenery" |
'GLOBAL_tint' | (but hopefully a float-like) | 'XXX' | Force "Instanced Scenery" and some mat.options.tint |
'COCKPIT_REGION' | exists at all. Forces ATTR_cockpit_region 0 for all.... | Set cockpit region 0 for all? | Unsure? |
'NORMAL_METALNESS' | check exists | None | make all materials have NORMAL_METALNESS (otherwise we'd throw an error) |
'BLEND_GLASS' | check exists | None | make all materials have BLEND_GLASS (otherwise we'd throw an error) |
'additive_lod' | int | ||
'instanced' | int-like | int('additive_lod') | hint layer type xplane.layer.export_type |
has_prop | type | default | Dest |
---|---|---|---|
'lit_level' | dref str stripped | '' | mat.xplane.lightlevel_dataref # A synonym of ATTR_light_level (overwrite this) |
'ATTR_light_level' | dref str stripped | '' | mat.xplane.lightlevel_dataref |
'ATTR_light_level_v1' | str | '0.0' | mat.xplane.lightlevel_v1 |
'ATTR_light_level_v2' | str | '1.0' | mat.xplane.lightlevel_v2 |
has_prop | type | default | Dest |
---|---|---|---|
'ATTR_draw_disable' | check exists | None | not mat.xplane.draw, for us (for now until #409) it is an alternative for INVISIBLE |
'ATTR_solid_camera' | check exists | None | None, used internally for error checking |
'surface' | str | "" | mat.xplane.surfaceType |
'deck' | bool like | False | mat.xplane.deck (shown when a surface type is shown) |
'up_norm' | int or float | 0 | Makes Normals face up always? if up_nrm: norm=Vertex(0,0,1, anim_matrix from makeAnim)
|
'ATTR_no_blend' | int or float | 0.5 | mat.xplane.blendRatio |
'ATTR_shadow_blend' | int or float | 0.5 | mat.xplane.blendRatio |
'ATTR_draped' | bool? check exists | None | mat.xplane.draped |
2.49 doesn't have many. Diffuse and Emissive RGB have been deprecated, so Buttons > Material > Shaders > Spec
is really all we care about.
Object-linked Material Datablocks are ignored by XPlane2Blender 2.49.
Then in 2.7x we'll
- Take each object, and separate the odd faces out in terms of non-uniform buttons, into as few Meshes as possible
- For each mesh, make sure the material has the relevant buttons copied over to the new properties
- That the texture assigned to the face's UV, and put it in the Material's Texture Slot.
Also, if they have a _LIT and _NML texture on disk where it is supposed to be, make texture slots for those too