Browse Source

Merge remote branch 'alteredq/master'

Mr.doob 14 years ago
parent
commit
11d29f464b

+ 19 - 0
utils/exporters/blender/2.56/scripts/op/io_mesh_threejs/__init__.py

@@ -42,6 +42,8 @@ from io_utils import ExportHelper, ImportHelper
 bpy.types.Object.THREE_castsShadow = bpy.props.BoolProperty()
 bpy.types.Object.THREE_castsShadow = bpy.props.BoolProperty()
 bpy.types.Object.THREE_meshCollider = bpy.props.BoolProperty()
 bpy.types.Object.THREE_meshCollider = bpy.props.BoolProperty()
 
 
+bpy.types.Material.THREE_useVertexColors = bpy.props.BoolProperty()
+
 class OBJECT_PT_hello( bpy.types.Panel ):
 class OBJECT_PT_hello( bpy.types.Panel ):
     
     
     bl_label = "THREE"
     bl_label = "THREE"
@@ -62,7 +64,24 @@ class OBJECT_PT_hello( bpy.types.Panel ):
         row = layout.row()
         row = layout.row()
         row.prop( obj, "THREE_meshCollider", text="Mesh collider" )
         row.prop( obj, "THREE_meshCollider", text="Mesh collider" )
 
 
+
+class MATERIAL_PT_hello( bpy.types.Panel ):
+    
+    bl_label = "THREE"
+    bl_space_type = "PROPERTIES"
+    bl_region_type = "WINDOW"
+    bl_context = "material"
+ 
+    def draw(self, context):
+        layout = self.layout
+        mat = context.material
         
         
+        row = layout.row()
+        row.label(text="Selected material: " + mat.name )
+
+        row = layout.row()
+        row.prop( mat, "THREE_useVertexColors", text="Use vertex colors" )
+
 # ################################################################
 # ################################################################
 # Importer
 # Importer
 # ################################################################
 # ################################################################

+ 28 - 24
utils/exporters/blender/2.56/scripts/op/io_mesh_threejs/export_threejs.py

@@ -165,20 +165,20 @@ TEMPLATE_CAMERA_ORTHO = """\
     }"""
     }"""
 
 
 TEMPLATE_LIGHT_DIRECTIONAL = """\
 TEMPLATE_LIGHT_DIRECTIONAL = """\
-	%(light_id)s: {
-		"type"		 : "directional",
-		"direction"	 : %(direction)s,
-		"color" 	 : %(color)d,
-		"intensity"	 : %(intensity).2f
-	}"""
+    %(light_id)s: {
+        "type"		 : "directional",
+        "direction"	 : %(direction)s,
+        "color" 	 : %(color)d,
+        "intensity"	 : %(intensity).2f
+    }"""
 
 
 TEMPLATE_LIGHT_POINT = """\
 TEMPLATE_LIGHT_POINT = """\
-	%(light_id)s: {
-		"type"	     : "point",
-		"position"   : %(position)s,
-		"color"      : %(color)d,
-		"intensity"	 : %(intensity).3f
-	}"""
+    %(light_id)s: {
+        "type"	     : "point",
+        "position"   : %(position)s,
+        "color"      : %(color)d,
+        "intensity"	 : %(intensity).3f
+    }"""
 
 
 TEMPLATE_VEC4 = '[ %f, %f, %f, %f ]'
 TEMPLATE_VEC4 = '[ %f, %f, %f, %f ]'
 TEMPLATE_VEC3 = '[ %f, %f, %f ]'
 TEMPLATE_VEC3 = '[ %f, %f, %f ]'
@@ -628,7 +628,7 @@ def generate_mtl(materials):
     return mtl
     return mtl
 
 
 def value2string(v):
 def value2string(v):
-    if type(v) == str and v[0] != "0":
+    if type(v) == str and v[0:2] != "0x":
         return '"%s"' % v
         return '"%s"' % v
     elif type(v) == bool:
     elif type(v) == bool:
         return str(v).lower()
         return str(v).lower()
@@ -649,7 +649,7 @@ def generate_materials(mtl, materials, use_colors, draw_type):
         mtl[m]['DbgName'] = m
         mtl[m]['DbgName'] = m
         mtl[m]['DbgIndex'] = index
         mtl[m]['DbgIndex'] = index
         mtl[m]['DbgColor'] = generate_color(index)
         mtl[m]['DbgColor'] = generate_color(index)
-        mtl[m]['vertexColors'] = use_colors
+        mtl[m]['vertexColors'] = use_colors and mtl[m]["useVertexColors"]
 
 
         if draw_type in [ "BOUNDS", "WIRE" ]:
         if draw_type in [ "BOUNDS", "WIRE" ]:
             mtl[m]['wireframe'] = True
             mtl[m]['wireframe'] = True
@@ -671,16 +671,16 @@ def extract_materials(mesh, scene):
             material = materials[m.name]
             material = materials[m.name]
             
             
             material['colorDiffuse'] = [m.diffuse_intensity * m.diffuse_color[0],
             material['colorDiffuse'] = [m.diffuse_intensity * m.diffuse_color[0],
-                                       m.diffuse_intensity * m.diffuse_color[1],
-                                       m.diffuse_intensity * m.diffuse_color[2]]
+                                        m.diffuse_intensity * m.diffuse_color[1],
+                                        m.diffuse_intensity * m.diffuse_color[2]]
 
 
             material['colorSpecular'] = [m.specular_intensity * m.specular_color[0],
             material['colorSpecular'] = [m.specular_intensity * m.specular_color[0],
-                                        m.specular_intensity * m.specular_color[1],
-                                        m.specular_intensity * m.specular_color[2]]
+                                         m.specular_intensity * m.specular_color[1],
+                                         m.specular_intensity * m.specular_color[2]]
 
 
             material['colorAmbient'] = [m.ambient * world.ambient_color[0],
             material['colorAmbient'] = [m.ambient * world.ambient_color[0],
-                                       m.ambient * world.ambient_color[1],
-                                       m.ambient * world.ambient_color[2]]
+                                        m.ambient * world.ambient_color[1],
+                                        m.ambient * world.ambient_color[2]]
 
 
             material['transparency'] = m.alpha
             material['transparency'] = m.alpha
 
 
@@ -695,10 +695,14 @@ def extract_materials(mesh, scene):
                 fn_strip = os.path.basename(fn)
                 fn_strip = os.path.basename(fn)
                 material['mapDiffuse'] = fn_strip
                 material['mapDiffuse'] = fn_strip
                 
                 
-            if m.specular_intensity > 0.0 and (m.specular_color[0] > 0 or m.specular_color[1] > 0 or m.specular_color[2] > 0):
-                material['shading'] = "Phong"
-            else:
-                material['shading'] = "Lambert"
+            material["useVertexColors"] = m.THREE_useVertexColors
+            
+            # can't really use this reliably to tell apart Phong from Lambert
+            # as Blender defaults to non-zero specular color
+            #if m.specular_intensity > 0.0 and (m.specular_color[0] > 0 or m.specular_color[1] > 0 or m.specular_color[2] > 0):
+            #    material['shading'] = "Phong"
+            #else:
+            #    material['shading'] = "Lambert"
 
 
     return materials
     return materials
 
 

+ 116 - 11
utils/exporters/blender/2.56/scripts/op/io_mesh_threejs/import_threejs.py

@@ -36,13 +36,83 @@ from io_utils import load_image, unpack_list, unpack_face_list
 # #####################################################
 # #####################################################
 # Generators
 # Generators
 # #####################################################
 # #####################################################
+def setColor(c, t):
+    c.r = t[0]
+    c.g = t[1]
+    c.b = t[2]
+
+def create_texture(filename, modelpath):
+    name = filename
+    texture = bpy.data.textures.new(name, type='IMAGE')
+    
+    image = load_image(filename, modelpath)
+    has_data = False
+
+    if image:
+        texture.image = image
+        has_data = image.has_data
+    
+    return texture
+    
+def create_materials(data, modelpath):
+    materials = []
+    materials_data = data.get("materials", [])
+    
+    for i, m in enumerate(materials_data):
 
 
-def create_mesh_object(name, vertices, face_data, flipYZ, recalculate_normals):
+        name = m.get("DbgName", "material_%d" % i)
+        
+        colorAmbient = m.get("colorAmbient", None)
+        colorDiffuse = m.get("colorDiffuse", None)
+        colorSpecular = m.get("colorSpecular", None)
+        alpha = m.get("transparency", 1.0)
+        specular_hardness = m.get("specularCoef", 0)
+        
+        mapDiffuse = m.get("mapDiffuse", None)
+        mapLightmap = m.get("mapLightmap", None)
+        
+        useVertexColors = m.get("vertexColors", False)
+        
+        material = bpy.data.materials.new(name)
+        
+        material.THREE_useVertexColors = useVertexColors
+        
+        if colorDiffuse:
+            setColor(material.diffuse_color, colorDiffuse)
+            material.diffuse_intensity = 1.0
+
+        if colorSpecular:
+            setColor(material.specular_color, colorSpecular)
+            material.specular_intensity = 1.0
+            
+        if alpha < 1.0:
+            material.alpha = alpha
+            material.use_transparency = True
+            
+        if specular_hardness:
+            material.specular_hardness = specular_hardness
+            
+        if mapDiffuse:
+            texture = create_texture(mapDiffuse, modelpath)
+            mtex = material.texture_slots.add()
+            mtex.texture = texture
+            mtex.texture_coords = 'UV'
+            mtex.use = True
+            mtex.use_map_color_diffuse = True
+            
+            material.active_texture = texture
+
+        materials.append(material)
+        
+    return materials
+    
+def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate_normals):
 
 
     faces   = face_data["faces"]
     faces   = face_data["faces"]
     vertexNormals = face_data["vertexNormals"]
     vertexNormals = face_data["vertexNormals"]
     vertexColors = face_data["vertexColors"]
     vertexColors = face_data["vertexColors"]
     vertexUVs = face_data["vertexUVs"]
     vertexUVs = face_data["vertexUVs"]
+    faceMaterials = face_data["materials"]
     
     
     edges = []
     edges = []
     
     
@@ -88,14 +158,14 @@ def create_mesh_object(name, vertices, face_data, flipYZ, recalculate_normals):
                         
                         
                         if flipYZ:
                         if flipYZ:
                             tmp = y
                             tmp = y
-                            y = z
+                            y = -z
                             z = tmp
                             z = tmp
 
 
                             # flip normals (this make them look consistent with the original before export)
                             # flip normals (this make them look consistent with the original before export)
 
 
-                            x = -x
-                            y = -y
-                            z = -z
+                            #x = -x
+                            #y = -y
+                            #z = -z
 
 
                         vi = me.faces[fi].vertices[j]
                         vi = me.faces[fi].vertices[j]
                         
                         
@@ -146,8 +216,8 @@ def create_mesh_object(name, vertices, face_data, flipYZ, recalculate_normals):
 
 
                 if layer[fi]:
                 if layer[fi]:
                     
                     
-                    face_uvs = me.uv_textures[li].data[fi]
-                    face_uvs = face_uvs.uv1, face_uvs.uv2, face_uvs.uv3, face_uvs.uv4
+                    uv_face = me.uv_textures[li].data[fi]
+                    face_uvs = uv_face.uv1, uv_face.uv2, uv_face.uv3, uv_face.uv4
                     
                     
                     for vi in range(len(layer[fi])):
                     for vi in range(len(layer[fi])):
                         
                         
@@ -156,13 +226,39 @@ def create_mesh_object(name, vertices, face_data, flipYZ, recalculate_normals):
                     
                     
                         face_uvs[vi].x = u
                         face_uvs[vi].x = u
                         face_uvs[vi].y = 1.0 - v
                         face_uvs[vi].y = 1.0 - v
+                        
+                    active_texture = materials[faceMaterials[fi]].active_texture
+                    
+                    if active_texture:
+                        uv_face.use_image = True
+                        uv_face.image = active_texture.image
+
+
+    # Handle materials # 1
+    
+    if face_data["hasMaterials"]:
+        
 
 
+        print("setting materials (mesh)")
+    
+        for m in materials:
+            
+            me.materials.append(m)
+
+        print("setting materials (faces)")    
+
+        for fi in range(len(faces)):
+            
+            if faceMaterials[fi] >= 0:
+                
+                me.faces[fi].material_index = faceMaterials[fi]
 
 
     # Create a new object
     # Create a new object
     
     
     ob = bpy.data.objects.new(name, me) 
     ob = bpy.data.objects.new(name, me) 
     ob.data = me                                # link the mesh data to the object
     ob.data = me                                # link the mesh data to the object
 
 
+
     scene = bpy.context.scene                   # get the current scene
     scene = bpy.context.scene                   # get the current scene
     scene.objects.link(ob)                      # link the object into the scene
     scene.objects.link(ob)                      # link the object into the scene
 
 
@@ -187,7 +283,8 @@ def extract_faces(data):
     
     
     "hasVertexNormals"  : False,
     "hasVertexNormals"  : False,
     "hasVertexUVs"      : False,
     "hasVertexUVs"      : False,
-    "hasVertexColors"   : False
+    "hasVertexColors"   : False,
+    "hasMaterials"      : False
     }
     }
     
     
     faces = data.get("faces", [])
     faces = data.get("faces", [])
@@ -228,6 +325,7 @@ def extract_faces(data):
         result["hasVertexUVs"] = result["hasVertexUVs"] or hasFaceVertexUv
         result["hasVertexUVs"] = result["hasVertexUVs"] or hasFaceVertexUv
         result["hasVertexNormals"] = result["hasVertexNormals"] or hasFaceVertexNormal
         result["hasVertexNormals"] = result["hasVertexNormals"] or hasFaceVertexNormal
         result["hasVertexColors"] = result["hasVertexColors"] or hasFaceVertexColor
         result["hasVertexColors"] = result["hasVertexColors"] or hasFaceVertexColor
+        result["hasMaterials"] = result["hasMaterials"] or hasMaterial
         
         
         # vertices
         # vertices
         
         
@@ -431,7 +529,10 @@ def extract_json_string(text):
 
 
 def get_name(filepath):
 def get_name(filepath):
     return os.path.splitext(os.path.basename(filepath))[0]
     return os.path.splitext(os.path.basename(filepath))[0]
-    
+
+def get_path(filepath):
+    return os.path.dirname(filepath)
+
 # #####################################################
 # #####################################################
 # Parser
 # Parser
 # #####################################################
 # #####################################################
@@ -464,7 +565,7 @@ def load(operator, context, filepath, option_flip_yz = True, recalculate_normals
     vertices = splitArray(data["vertices"], 3)
     vertices = splitArray(data["vertices"], 3)
     
     
     if option_flip_yz:
     if option_flip_yz:
-        vertices[:] = [(v[0], v[2], v[1]) for v in vertices]        
+        vertices[:] = [(v[0], -v[2], v[1]) for v in vertices]        
 
 
     # extract faces
     # extract faces
     
     
@@ -484,9 +585,13 @@ def load(operator, context, filepath, option_flip_yz = True, recalculate_normals
     print('\tbuilding geometry...\n\tfaces:%i, vertices:%i, vertex normals: %i, vertex uvs: %i, vertex colors: %i, materials: %i ...' % ( 
     print('\tbuilding geometry...\n\tfaces:%i, vertices:%i, vertex normals: %i, vertex uvs: %i, vertex colors: %i, materials: %i ...' % ( 
         nfaces, nvertices, nnormals, nuvs, ncolors, nmaterials ))
         nfaces, nvertices, nnormals, nuvs, ncolors, nmaterials ))
 
 
+    # Create materials
+    
+    materials = create_materials(data, get_path(filepath))
+    
     # Create new obj
     # Create new obj
     
     
-    create_mesh_object(get_name(filepath), vertices, face_data, option_flip_yz, recalculate_normals)
+    create_mesh_object(get_name(filepath), vertices, materials, face_data, option_flip_yz, recalculate_normals)
 
 
     scene = bpy.context.scene 
     scene = bpy.context.scene 
     scene.update()
     scene.update()