[DEV] start integration of the emf file ==> has more capabilities than obj (emf is specific ewol mesh file)

This commit is contained in:
Edouard DUPIN 2013-08-05 20:49:58 +02:00
parent 7fecf6cd89
commit a70ca277e0
15 changed files with 1427 additions and 2683 deletions

View File

@ -0,0 +1,286 @@
# add this folder in ~/.config/blender/2.66/scripts/addons
bl_info = {
"name": "Ewol Mesh file format emf",
"author": "Edouard DUPIN",
"blender": (2, 53, 0),
"location": "File > Import-Export",
"description": "Import-Export emf, Import EMF mesh, UV's, materials and textures",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/EwolMechFile_EMF",
"tracker_url": "",
"support": 'OFFICIAL',
"category": "Import-Export"}
if "bpy" in locals():
import imp
if "import_emf" in locals():
imp.reload(import_emf)
if "export_emf" in locals():
imp.reload(export_emf)
import bpy
from bpy.props import (BoolProperty,
FloatProperty,
StringProperty,
EnumProperty,
)
from bpy_extras.io_utils import (ExportHelper,
ImportHelper,
path_reference_mode,
axis_conversion,
)
class ImportEMF(bpy.types.Operator, ImportHelper):
"""Load a Wavefront EMF File"""
bl_idname = "import_scene.emf"
bl_label = "Import EMF"
bl_options = {'PRESET', 'UNDO'}
filename_ext = ".emf"
filter_glob = StringProperty(
default="*.emf",
options={'HIDDEN'},
)
use_ngons = BoolProperty(
name="NGons",
description="Import faces with more than 4 verts as ngons",
default=True,
)
use_edges = BoolProperty(
name="Lines",
description="Import lines and faces with 2 verts as edge",
default=True,
)
use_smooth_groups = BoolProperty(
name="Smooth Groups",
description="Surround smooth groups by sharp edges",
default=True,
)
use_split_objects = BoolProperty(
name="Object",
description="Import EMF Objects into Blender Objects",
default=True,
)
use_split_groups = BoolProperty(
name="Group",
description="Import EMF Groups into Blender Objects",
default=True,
)
use_groups_as_vgroups = BoolProperty(
name="Poly Groups",
description="Import EMF groups as vertex groups",
default=False,
)
use_image_search = BoolProperty(
name="Image Search",
description="Search subdirs for any associated images "
"(Warning, may be slow)",
default=True,
)
split_mode = EnumProperty(
name="Split",
items=(('ON', "Split", "Split geometry, omits unused verts"),
('OFF', "Keep Vert Order", "Keep vertex order from file"),
),
)
global_clamp_size = FloatProperty(
name="Clamp Size",
description="Clamp bounds under this value (zero to disable)",
min=0.0, max=1000.0,
soft_min=0.0, soft_max=1000.0,
default=0.0,
)
axis_forward = EnumProperty(
name="Forward",
items=(('X', "X Forward", ""),
('Y', "Y Forward", ""),
('Z', "Z Forward", ""),
('-X', "-X Forward", ""),
('-Y', "-Y Forward", ""),
('-Z', "-Z Forward", ""),
),
default='-Z',
)
axis_up = EnumProperty(
name="Up",
items=(('X', "X Up", ""),
('Y', "Y Up", ""),
('Z', "Z Up", ""),
('-X', "-X Up", ""),
('-Y', "-Y Up", ""),
('-Z', "-Z Up", ""),
),
default='Y',
)
def execute(self, context):
# print("Selected: " + context.active_object.name)
from . import import_obj
if self.split_mode == 'OFF':
self.use_split_objects = False
self.use_split_groups = False
else:
self.use_groups_as_vgroups = False
keywords = self.as_keywords(ignore=("axis_forward",
"axis_up",
"filter_glob",
"split_mode",
))
global_matrix = axis_conversion(from_forward=self.axis_forward,
from_up=self.axis_up,
).to_4x4()
keywords["global_matrix"] = global_matrix
return import_obj.load(self, context, **keywords)
def draw(self, context):
layout = self.layout
row = layout.row(align=True)
box = layout.box()
row = box.row()
row.prop(self, "split_mode", expand=True)
row = box.row()
if self.split_mode == 'ON':
row.label(text="Split by:")
row.prop(self, "use_split_objects")
row.prop(self, "use_split_groups")
else:
row.prop(self, "use_groups_as_vgroups")
row = layout.split(percentage=0.67)
row.prop(self, "global_clamp_size")
layout.prop(self, "axis_forward")
layout.prop(self, "axis_up")
layout.prop(self, "use_image_search")
class ExportEMF(bpy.types.Operator, ExportHelper):
"""Save a Wavefront EMF File"""
bl_idname = "export_scene.emf"
bl_label = 'Export EMF'
bl_options = {'PRESET'}
filename_ext = ".emf"
filter_glob = StringProperty(
default="*.emf",
options={'HIDDEN'},
)
# context group
use_selection = BoolProperty(
name="Selection Only",
description="Export selected objects only",
default=True,
)
# generate binary file
use_binary = BoolProperty(
name="Binary",
description="Export the filein binary mode",
default=False,
)
global_scale = FloatProperty(
name="Scale",
description="Scale all data",
min=0.01, max=1000.0,
soft_min=0.01,
soft_max=1000.0,
default=1.0,
)
axis_forward = EnumProperty(
name="Forward",
items=(('X', "X Forward", ""),
('Y', "Y Forward", ""),
('Z', "Z Forward", ""),
('-X', "-X Forward", ""),
('-Y', "-Y Forward", ""),
('-Z', "-Z Forward", ""),
),
default='-Z',
)
axis_up = EnumProperty(
name="Up",
items=(('X', "X Up", ""),
('Y', "Y Up", ""),
('Z', "Z Up", ""),
('-X', "-X Up", ""),
('-Y', "-Y Up", ""),
('-Z', "-Z Up", ""),
),
default='Y',
)
path_mode = path_reference_mode
check_extension = True
def execute(self, context):
from . import export_emf
from mathutils import Matrix
keywords = self.as_keywords(ignore=("axis_forward",
"axis_up",
"global_scale",
"check_existing",
"filter_glob",
))
global_matrix = Matrix()
global_matrix[0][0] = \
global_matrix[1][1] = \
global_matrix[2][2] = self.global_scale
global_matrix = (global_matrix *
axis_conversion(to_forward=self.axis_forward,
to_up=self.axis_up,
).to_4x4())
keywords["global_matrix"] = global_matrix
return export_emf.save(self, context, **keywords)
def menu_func_import(self, context):
self.layout.operator(ImportEMF.bl_idname, text="Ewol mesh file (.emf)")
def menu_func_export(self, context):
self.layout.operator(ExportEMF.bl_idname, text="Ewol mesh File (.emf)")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func_import)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()

View File

@ -0,0 +1,487 @@
import os
import time
import bpy
import mathutils
import bpy_extras.io_utils
def name_compat(name):
if name is None:
return 'None'
else:
return name.replace(' ', '_')
def mesh_triangulate(me):
import bmesh
bm = bmesh.new()
bm.from_mesh(me)
bmesh.ops.triangulate(bm, faces=bm.faces)
bm.to_mesh(me)
bm.free()
def write_mtl(scene, file, filepath, path_mode, copy_set, mtl_dict):
from mathutils import Color
world = scene.world
if world:
world_amb = world.ambient_color
else:
world_amb = Color((0.0, 0.0, 0.0))
source_dir = os.path.dirname(bpy.data.filepath)
dest_dir = os.path.dirname(filepath)
fw = file.write
fw('\nMaterials : %i\n' % len(mtl_dict))
mtl_dict_values = list(mtl_dict.values())
mtl_dict_values.sort(key=lambda m: m[0])
# Write material/image combinations we have used.
# Using mtl_dict.values() directly gives un-predictable order.
for mtl_mat_name, mat, face_img in mtl_dict_values:
# Get the Blender data for the material and the image.
# Having an image named None will make a bug, dont do it :)
fw('\t%s\n' % mtl_mat_name) # Define a new material: matname_imgname
if mat:
# convert from blenders spec to 0 - 1000 range.
if mat.specular_shader == 'WARDISO':
tspec = (0.4 - mat.specular_slope) / 0.0004
else:
tspec = (mat.specular_hardness - 1) * 1.9607843137254901
fw('\t\tNs %.6f\n' % tspec)
del tspec
fw('\t\tKa %.6f %.6f %.6f\n' % (mat.ambient * world_amb)[:]) # Ambient, uses mirror color,
fw('\t\tKd %.6f %.6f %.6f\n' % (mat.diffuse_intensity * mat.diffuse_color)[:]) # Diffuse
fw('\t\tKs %.6f %.6f %.6f\n' % (mat.specular_intensity * mat.specular_color)[:]) # Specular
if hasattr(mat, "ior"):
fw('\t\tNi %.6f\n' % mat.ior) # Refraction index
else:
fw('\t\tNi %.6f\n' % 1.0)
fw('\t\td %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
if mat.use_shadeless:
fw('\t\tillum 0\n') # ignore lighting
elif mat.specular_intensity == 0:
fw('\t\tillum 1\n') # no specular.
else:
fw('\t\tillum 2\n') # light normaly
else:
#write a dummy material here?
fw('\t\tNs 0\n')
fw('\t\tKa %.6f %.6f %.6f\n' % world_amb[:]) # Ambient, uses mirror color,
fw('\t\tKd 0.8 0.8 0.8\n')
fw('\t\tKs 0.8 0.8 0.8\n')
fw('\t\td 1\n') # No alpha
fw('\t\tillum 2\n') # light normaly
# Write images!
if face_img: # We have an image on the face!
filepath = face_img.filepath
if filepath: # may be '' for generated images
# write relative image path
filepath = bpy_extras.io_utils.path_reference(filepath,
source_dir,
dest_dir,
path_mode,
"",
copy_set,
face_img.library)
fw('\t\tmap_Kd %s\n' % filepath) # Diffuse mapping image
del filepath
else:
# so we write the materials image.
face_img = None
if mat: # No face image. if we havea material search for MTex image.
image_map = {}
# backwards so topmost are highest priority
for mtex in reversed(mat.texture_slots):
if mtex and mtex.texture and mtex.texture.type == 'IMAGE':
image = mtex.texture.image
if image:
# texface overrides others
if (mtex.use_map_color_diffuse and
(face_img is None) and
(mtex.use_map_warp is False) and
(mtex.texture_coords != 'REFLECTION')):
image_map["map_Kd"] = image
if mtex.use_map_ambient:
image_map["map_Ka"] = image
# this is the Spec intensity channel but Ks stands for specular Color
if mtex.use_map_color_spec: # specular color
image_map["map_Ks"] = image
if mtex.use_map_hardness: # specular hardness/glossiness
image_map["map_Ns"] = image
if mtex.use_map_alpha:
image_map["map_d"] = image
if mtex.use_map_translucency:
image_map["map_Tr"] = image
if mtex.use_map_normal and (mtex.texture.use_normal_map is True):
image_map["map_Bump"] = image
if mtex.use_map_normal and (mtex.texture.use_normal_map is False):
image_map["map_Disp"] = image
if mtex.use_map_color_diffuse and (mtex.texture_coords == 'REFLECTION'):
image_map["map_refl"] = image
if mtex.use_map_emit:
image_map["map_Ke"] = image
for key, image in image_map.items():
filepath = bpy_extras.io_utils.path_reference(image.filepath,
source_dir,
dest_dir,
path_mode,
"",
copy_set,
image.library)
fw('\t\t%s %s\n' % (key, repr(filepath)[1:-1]))
"""
" @brief Basic write function. The context and options must be already set.
"""
def write_file(filepath,
objects,
scene,
EXPORT_GLOBAL_MATRIX=None,
EXPORT_PATH_MODE='AUTO',
):
if EXPORT_GLOBAL_MATRIX is None:
EXPORT_GLOBAL_MATRIX = mathutils.Matrix()
def veckey3d(v):
return round(v.x, 6), round(v.y, 6), round(v.z, 6)
def veckey2d(v):
return round(v[0], 6), round(v[1], 6)
print('EMF Export path: %r' % filepath)
time1 = time.time()
mtlfilepath = os.path.splitext(filepath)[0] + ".mtl"
file = open(filepath, "w", encoding="utf8", newline="\n")
fw = file.write
# Write Header
fw('EMF(STRING)\n') # if binary : fw('EMF(BINARY)\n')
fw('# Blender v%s EMF File: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
# Initialize totals, these are updated each object
totverts = totuvco = totno = 1
face_vert_index = 1
globalNormals = {}
# A Dict of Materials
# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
mtl_dict = {}
# Used to reduce the usage of matname_texname materials, which can become annoying in case of
# repeated exports/imports, yet keeping unique mat names per keys!
# mtl_name: (material.name, image.name)
mtl_rev_dict = {}
copy_set = set()
# Get all meshes
for ob_main in objects:
# ignore dupli children
if ob_main.parent and ob_main.parent.dupli_type in {'VERTS', 'FACES'}:
# XXX
print(ob_main.name, 'is a dupli child - ignoring')
continue
obs = []
if ob_main.dupli_type != 'NONE':
# XXX
print('creating dupli_list on', ob_main.name)
ob_main.dupli_list_create(scene)
obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list]
# XXX debug print
print(ob_main.name, 'has', len(obs), 'dupli children')
else:
obs = [(ob_main, ob_main.matrix_world)]
idMesh=0
for ob, ob_mat in obs:
try:
# apply the mesh modifieur at the curent object :
me = ob.to_mesh(scene, True, 'PREVIEW', calc_tessface=False)
except RuntimeError:
me = None
if me is None:
continue
idMesh = idMesh+1;
fw('Mesh : %d\n' % idMesh)
me.transform(EXPORT_GLOBAL_MATRIX * ob_mat)
# _must_ do this first since it re-allocs arrays
# triangulate all the mesh :
mesh_triangulate(me)
# export UV mapping :
faceuv = len(me.uv_textures) > 0
if faceuv:
uv_texture = me.uv_textures.active.data[:]
uv_layer = me.uv_layers.active.data[:]
me_verts = me.vertices[:]
# Make our own list so it can be sorted to reduce context switching
face_index_pairs = [(face, index) for index, face in enumerate(me.polygons)]
# faces = [ f for f in me.tessfaces ]
edges = me.edges
if not (len(face_index_pairs) + len(edges) + len(me.vertices)): # Make sure there is somthing to write
# clean up
bpy.data.meshes.remove(me)
continue # dont bother with this mesh.
# calculated normals:
me.calc_normals()
materials = me.materials[:]
material_names = [m.name if m else None for m in materials]
# avoid bad index errors
if not materials:
materials = [None]
material_names = [name_compat(None)]
# Sort by Material, then images
# so we dont over context switch in the obj file.
if faceuv:
face_index_pairs.sort(key=lambda a: (a[0].material_index, hash(uv_texture[a[1]].image), a[0].use_smooth))
elif len(materials) > 1:
face_index_pairs.sort(key=lambda a: (a[0].material_index, a[0].use_smooth))
else:
# no materials
face_index_pairs.sort(key=lambda a: a[0].use_smooth)
# Set the default mat to no material and no image.
contextMat = 0, 0 # Can never be this, so we will label a new material the first chance we get.
contextSmooth = None # Will either be true or false, set bad to force initialization switch.
# use : blen obs ??? what is this ....
if True:
name1 = ob.name
name2 = ob.data.name
if name1 == name2:
obnamestring = name_compat(name1)
else:
obnamestring = '%s_%s' % (name_compat(name1), name_compat(name2))
fw('\tName : %s\n' % obnamestring) # Write Object name
###########################################################
## Vert
###########################################################
fw('\tVertex : %d\n\t\t' % len(me_verts))
for v in me_verts:
fw('%.6f %.6f %.6f|' % v.co[:])
fw('\n')
###########################################################
## UV
###########################################################
fw('\tUV-mapping :\n\t\t')
if faceuv:
# in case removing some of these dont get defined.
uv = uvkey = uv_dict = f_index = uv_index = None
uv_face_mapping = [None] * len(face_index_pairs)
uv_dict = {} # could use a set() here
for f, f_index in face_index_pairs:
uv_ls = uv_face_mapping[f_index] = []
for uv_index, l_index in enumerate(f.loop_indices):
uv = uv_layer[l_index].uv
uvkey = veckey2d(uv)
try:
uv_k = uv_dict[uvkey]
except:
uv_k = uv_dict[uvkey] = len(uv_dict)
fw('%.6f %.6f|' % uv[:])
uv_ls.append(uv_k)
uv_unique_count = len(uv_dict)
del uv, uvkey, uv_dict, f_index, uv_index, uv_ls, uv_k
# Only need uv_unique_count and uv_face_mapping
fw('\n')
###########################################################
## NORMAL
###########################################################
if f.use_smooth:
localIsSmooth = 'vertex'
else:
localIsSmooth = 'face'
fw('\tNormal(%s) : %d\n\t\t' % (localIsSmooth, len(face_index_pairs)) )
for f, f_index in face_index_pairs:
if f.use_smooth:
for v_idx in f.vertices:
v = me_verts[v_idx]
noKey = veckey3d(v.normal)
if noKey not in globalNormals:
globalNormals[noKey] = totno
totno += 1
fw('%.6f %.6f %.6f|' % noKey)
else:
# Hard, 1 normal from the face.
noKey = veckey3d(f.normal)
if noKey not in globalNormals:
globalNormals[noKey] = totno
totno += 1
fw('%.6f %.6f %.6f|' % noKey)
fw('\n')
if not faceuv:
f_image = None
###########################################################
## faces
###########################################################
fw('\tFace : %d' % len(face_index_pairs))
for f, f_index in face_index_pairs:
f_smooth = f.use_smooth
f_mat = min(f.material_index, len(materials) - 1)
if faceuv:
tface = uv_texture[f_index]
f_image = tface.image
# MAKE KEY
if faceuv and f_image: # Object is always true.
key = material_names[f_mat], f_image.name
else:
key = material_names[f_mat], None # No image, use None instead.
# CHECK FOR CONTEXT SWITCH
if key == contextMat:
pass # Context already switched, dont do anything
else:
if key[0] is None and key[1] is None:
# inform the use of a material :
fw("\n\t\t---:") # mat, image
else:
mat_data = mtl_dict.get(key)
if not mat_data:
# First add to global dict so we can export to mtl
# Then write mtl
# Make a new names from the mat and image name,
# converting any spaces to underscores with name_compat.
# If none image dont bother adding it to the name
# Try to avoid as much as possible adding texname (or other things)
# to the mtl name (see [#32102])...
mtl_name = "%s" % name_compat(key[0])
if mtl_rev_dict.get(mtl_name, None) not in {key, None}:
if key[1] is None:
tmp_ext = "_NONE"
else:
tmp_ext = "_%s" % name_compat(key[1])
i = 0
while mtl_rev_dict.get(mtl_name + tmp_ext, None) not in {key, None}:
i += 1
tmp_ext = "_%3d" % i
mtl_name += tmp_ext
mat_data = mtl_dict[key] = mtl_name, materials[f_mat], f_image
mtl_rev_dict[mtl_name] = key
# set the use of a material :
fw("\n\t\t%s:" % mat_data[0]) # can be mat_image or (null)
contextMat = key
f_v = [(vi, me_verts[v_idx]) for vi, v_idx in enumerate(f.vertices)]
if faceuv:
# export the normals :
if f_smooth: # Smoothed, use vertex normals
for vi, v in f_v:
fw(" %d/%d/%d" %
(v.index + totverts-1,
totuvco + uv_face_mapping[f_index][vi]-1,
globalNormals[veckey3d(v.normal)]-1,
)) # vert, uv, normal
else: # No smoothing, face normals
no = globalNormals[veckey3d(f.normal)]
for vi, v in f_v:
fw(" %d/%d/%d" %
(v.index + totverts-1,
totuvco + uv_face_mapping[f_index][vi]-1,
no-1,
)) # vert, uv, normal
face_vert_index += len(f_v)
else: # No UV's
# export the normals :
if f_smooth: # Smoothed, use vertex normals
for vi, v in f_v:
fw(" %d//%d" % (
v.index + totverts-1,
globalNormals[veckey3d(v.normal)]-1,
))
else: # No smoothing, face normals
no = globalNormals[veckey3d(f.normal)]
for vi, v in f_v:
fw(" %d//%d" % (v.index + totverts-1, no-1))
fw('|')
fw('\n')
# Write edges. ==> did not know what it is ...
#fw('Faces : %d' % len(edges))
#for ed in edges:
# if ed.is_loose:
# fw('%d %d\n' % (ed.vertices[0] + totverts, ed.vertices[1] + totverts))
# Make the indices global rather then per mesh
totverts += len(me_verts)
if faceuv:
totuvco += uv_unique_count
# clean up
bpy.data.meshes.remove(me)
if ob_main.dupli_type != 'NONE':
ob_main.dupli_list_clear()
###########################################################
## Now we have all our materials, save them
## material generation :
###########################################################
write_mtl(scene, file, mtlfilepath, EXPORT_PATH_MODE, copy_set, mtl_dict)
file.close()
# copy all collected files.
bpy_extras.io_utils.path_reference_copy(copy_set)
print("EMF Export time: %.2f" % (time.time() - time1))
"""
" @brief generate the requested object file ... with his material inside and ...
"
"""
def _write(context,
filepath,
EXPORT_SEL_ONLY,
EXPORT_GLOBAL_MATRIX,
EXPORT_PATH_MODE,
):
#
base_name, ext = os.path.splitext(filepath)
# create the output name :
context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
# get the curent scene :
scene = context.scene
# Exit edit mode before exporting, so current object states are exported properly.
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT')
# get the curent frame selected :
frame = scene.frame_current
# Loop through all frames in the scene and export.
scene.frame_set(frame, 0.0)
# get only the object that are selected or all ...
if EXPORT_SEL_ONLY:
objects = context.selected_objects
else:
objects = scene.objects
full_path = ''.join(context_name)
write_file(full_path,
objects,
scene,
EXPORT_GLOBAL_MATRIX,
EXPORT_PATH_MODE,
)
"""
" @brief Save the current element in the file requested.
"
"""
def save(operator,
context,
filepath="",
use_selection=True,
use_binary=False,
global_matrix=None,
path_mode='AUTO'
):
_write(context,
filepath,
EXPORT_SEL_ONLY=use_selection,
EXPORT_GLOBAL_MATRIX=global_matrix,
EXPORT_PATH_MODE=path_mode,
)
return {'FINISHED'}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2
external/etk vendored

@ -1 +1 @@
Subproject commit 3c27f446f4f33bede07292ab3512c4ab4c531f9e
Subproject commit 35b678fb65f9d6a86fcf0b8a4ea8f6c51417df4d

View File

@ -6,44 +6,77 @@
* @license BSD v3 (see license file)
*/
#include <ewol/renderer/ResourceManager.h>
#include <ewol/renderer/Material.h>
#include <ewol/debug.h>
ewol::MaterialGlId::MaterialGlId(void) :
m_GL_ambientFactor(0),
m_GL_diffuseFactor(0),
m_GL_specularFactor(0),
m_GL_shininess(0),
m_GL_texture0(0)
{
// nothing to do else ...
}
void ewol::MaterialGlId::Link(ewol::Program* _prog, const etk::UString& _baseName)
{
if (NULL == _prog) {
return;
}
m_GL_ambientFactor = _prog->GetUniform(_baseName+".ambientFactor");
m_GL_diffuseFactor = _prog->GetUniform(_baseName+".diffuseFactor");
m_GL_specularFactor = _prog->GetUniform(_baseName+".specularFactor");
m_GL_shininess = _prog->GetUniform(_baseName+".shininess");
m_GL_texture0 = _prog->GetUniform("EW_texID");
}
ewol::Material::Material(void) :
m_ambientFactor(0,0,0,0),
m_diffuseFactor(0,0,0,0),
m_specularFactor(0,0,0,0),
m_shininess(0),
m_GL_ambientFactor(0),
m_GL_diffuseFactor(0),
m_GL_specularFactor(0),
m_GL_shininess(0)
m_texture0(NULL)
{
// nothing to do else ...
}
ewol::Material::~Material(void)
{
if(NULL!=m_texture0) {
ewol::resource::Release(m_texture0);
}
}
void ewol::Material::Link(ewol::Program* prog, const etk::UString& baseName)
void ewol::Material::Draw(ewol::Program* _prog, const MaterialGlId& _glID)
{
if (NULL == prog) {
_prog->Uniform4(_glID.m_GL_ambientFactor, m_ambientFactor);
_prog->Uniform4(_glID.m_GL_diffuseFactor, m_diffuseFactor);
_prog->Uniform4(_glID.m_GL_specularFactor, m_specularFactor);
_prog->Uniform1f(_glID.m_GL_shininess, m_shininess);
if (NULL != m_texture0) {
_prog->SetTexture0(_glID.m_GL_texture0, m_texture0->GetId());
}
}
void ewol::Material::SetTexture0(const etk::UString& _filename)
{
ivec2 tmpSize(256, 256);
// prevent overloard error :
ewol::TextureFile* tmpCopy = m_texture0;
m_texture0 = NULL;
if (false == ewol::resource::Keep(_filename, m_texture0, tmpSize)) {
EWOL_ERROR("Can not load specific texture : " << _filename);
// retreave previous texture:
m_texture0 = tmpCopy;
return;
}
m_GL_ambientFactor = prog->GetUniform(baseName+".ambientFactor");
m_GL_diffuseFactor = prog->GetUniform(baseName+".diffuseFactor");
m_GL_specularFactor = prog->GetUniform(baseName+".specularFactor");
m_GL_shininess = prog->GetUniform(baseName+".shininess");
}
void ewol::Material::Draw(ewol::Program* prog)
{
prog->Uniform4(m_GL_ambientFactor, m_ambientFactor);
prog->Uniform4(m_GL_diffuseFactor, m_diffuseFactor);
prog->Uniform4(m_GL_specularFactor, m_specularFactor);
prog->Uniform1f(m_GL_shininess, m_shininess);
if (NULL != tmpCopy) {
// really release previous texture. In case of same texture loading, then we did not have reload it .. just increase and decrease index...
ewol::resource::Release(tmpCopy);
}
}

View File

@ -13,41 +13,50 @@
#include <etk/math/Vector3D.h>
#include <etk/math/Vector4D.h>
#include <ewol/renderer/resources/Program.h>
#include <ewol/renderer/resources/Image.h>
namespace ewol
{
class Material
class MaterialGlId
{
private:
// values
vec4 m_ambientFactor;
vec4 m_diffuseFactor;
vec4 m_specularFactor;
float m_shininess;
private:
public:
// GL index
int32_t m_GL_ambientFactor;
int32_t m_GL_diffuseFactor;
int32_t m_GL_specularFactor;
int32_t m_GL_shininess;
int32_t m_GL_texture0;
MaterialGlId(void);
void Link(ewol::Program* _prog, const etk::UString& _baseName);
};
class Material
{
private:
// values
vec4 m_ambientFactor;
vec4 m_diffuseFactor;
vec4 m_specularFactor;
float m_shininess;
ewol::TextureFile* m_texture0;
public:
Material(void);
~Material(void);
void Link(ewol::Program* prog, const etk::UString& baseName);
void Draw(ewol::Program* prog);
void SetAmbientFactor(const vec4& val) {
m_ambientFactor = val;
void Draw(ewol::Program* _prog, const MaterialGlId& _glID);
void SetAmbientFactor(const vec4& _val) {
m_ambientFactor = _val;
}
void SetDiffuseFactor(const vec4& val) {
m_diffuseFactor = val;
void SetDiffuseFactor(const vec4& _val) {
m_diffuseFactor = _val;
}
void SetSpecularFactor(const vec4& val) {
m_specularFactor = val;
void SetSpecularFactor(const vec4& _val) {
m_specularFactor = _val;
}
void SetShininess(float val) {
m_shininess = val;
void SetShininess(float _val) {
m_shininess = _val;
}
void SetTexture0(const etk::UString& _filename);
};
};

View File

@ -348,47 +348,32 @@ bool ewol::resource::Keep(const etk::UString& _filename, ewol::TextureFile*& _ob
return true;
}
bool ewol::resource::Keep(const etk::UString& filename, ewol::MeshObj*& object)
bool ewol::resource::Keep(const etk::UString& _meshName, ewol::Mesh*& _object)
{
object = static_cast<ewol::MeshObj*>(LocalKeep(filename));
if (NULL != object) {
_object = static_cast<ewol::Mesh*>(LocalKeep(_meshName));
if (NULL != _object) {
return true;
}
object = new ewol::MeshObj(filename);
if (NULL == object) {
EWOL_ERROR("allocation error of a resource : ??Mesh.obj??" << filename);
_object = new ewol::Mesh(_meshName);
if (NULL == _object) {
EWOL_ERROR("allocation error of a resource : ??Mesh??" << _meshName);
return false;
}
LocalAdd(object);
LocalAdd(_object);
return true;
}
bool ewol::resource::Keep(const etk::UString& meshName, ewol::Mesh*& object)
{
object = static_cast<ewol::Mesh*>(LocalKeep(meshName));
if (NULL != object) {
return true;
}
object = new ewol::Mesh(meshName);
if (NULL == object) {
EWOL_ERROR("allocation error of a resource : ??Mesh??" << meshName);
return false;
}
LocalAdd(object);
return true;
}
bool ewol::resource::Keep(const etk::UString& accesMode, ewol::VirtualBufferObject*& object)
bool ewol::resource::Keep(const etk::UString& _accesMode, ewol::VirtualBufferObject*& _object)
{
// this element create a new one every time ....
object = new ewol::VirtualBufferObject(accesMode);
if (NULL == object) {
_object = new ewol::VirtualBufferObject(_accesMode);
if (NULL == _object) {
EWOL_ERROR("allocation error of a resource : ??VBO??");
return false;
}
LocalAdd(object);
LocalAdd(_object);
return true;
}
@ -483,13 +468,6 @@ void ewol::resource::Release(ewol::TextureFile*& object)
object = NULL;
}
void ewol::resource::Release(ewol::MeshObj*& object)
{
ewol::Resource* object2 = static_cast<ewol::Resource*>(object);
Release(object2);
object = NULL;
}
void ewol::resource::Release(ewol::Mesh*& object)
{
ewol::Resource* object2 = static_cast<ewol::Resource*>(object);

View File

@ -19,7 +19,7 @@
#include <ewol/renderer/resources/TexturedFont.h>
#include <ewol/renderer/resources/Texture.h>
#include <ewol/renderer/resources/Image.h>
#include <ewol/renderer/resources/MeshObj.h>
#include <ewol/renderer/resources/Mesh.h>
#include <ewol/renderer/resources/Colored3DObject.h>
namespace ewol
@ -77,7 +77,6 @@ namespace ewol
bool Keep(ewol::Texture*& object); // no name needed here ...
bool Keep(const etk::UString& filename, ewol::TextureFile*& object, ivec2 size=ivec2(-1,-1));
bool Keep(const etk::UString& accesMode, ewol::VirtualBufferObject*& object);
bool Keep(const etk::UString& filename, ewol::MeshObj*& object);
bool Keep(const etk::UString& meshName, ewol::Mesh*& object);
bool Keep(const etk::UString& filename, ewol::ConfigFile*& object);
bool Keep(ewol::Colored3DObject*& object);
@ -94,7 +93,6 @@ namespace ewol
void Release(ewol::Texture*& object);
void Release(ewol::TextureFile*& object);
void Release(ewol::VirtualBufferObject*& object);
void Release(ewol::MeshObj*& object);
void Release(ewol::Mesh*& object);
void Release(ewol::ConfigFile*& object);
void Release(ewol::Colored3DObject*& object);

View File

@ -9,6 +9,7 @@
#include <ewol/debug.h>
#include <ewol/renderer/resources/Mesh.h>
#include <ewol/renderer/ResourceManager.h>
#include <etk/os/FSNode.h>
#undef __class__
#define __class__ "Mesh"
@ -61,21 +62,21 @@ class VertexNode {
ewol::Mesh::Mesh(etk::UString genName, etk::UString shaderName) :
ewol::Resource(genName),
ewol::Mesh::Mesh(const etk::UString& _fileName, const etk::UString& _shaderName) :
ewol::Resource(_fileName),
m_enableFaceNormal(true),
m_enableVertexNormal(true),
m_numberOfElments(0),
m_texture0(NULL)
m_numberOfElments(0)
{
EWOL_DEBUG("Load a new mesh : '" << _fileName << "'");
// get the shader resource :
m_GLPosition = 0;
// set the element material properties :
m_material.SetAmbientFactor(vec4(0.100000,0.100000,0.100000, 1.0));
m_material.SetDiffuseFactor(vec4(0.640000, 0.640000, 0.640000, 1.0));
m_material.SetSpecularFactor(vec4(0.500000, 0.500000, 0.500000, 1.0));
m_material.SetShininess(0.96078431);
//m_material.SetAmbientFactor(vec4(0.100000,0.100000,0.100000, 1.0));
//m_material.SetDiffuseFactor(vec4(0.640000, 0.640000, 0.640000, 1.0));
//m_material.SetSpecularFactor(vec4(0.500000, 0.500000, 0.500000, 1.0));
//m_material.SetShininess(0.96078431);
m_light.SetDirection(vec3(0,cos(M_PI/4),sin(M_PI/4)));
m_light.SetHalfPlane(vec3(1,0,0));
@ -83,28 +84,42 @@ ewol::Mesh::Mesh(etk::UString genName, etk::UString shaderName) :
m_light.SetDiffuseColor(vec4(1.0,1.0,1.0,1));
m_light.SetSpecularColor(vec4(0.0,0.0,0.0,1));
if (true == ewol::resource::Keep(shaderName, m_GLprogram) ) {
if (true == ewol::resource::Keep(_shaderName, m_GLprogram) ) {
m_GLPosition = m_GLprogram->GetAttribute("EW_coord3d");
m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d");
m_GLNormal = m_GLprogram->GetAttribute("EW_normal");
m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d");
m_GLNormal = m_GLprogram->GetAttribute("EW_normal");
m_GLNormalFace = m_GLprogram->GetAttribute("EW_faceNormal");
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
m_GLMatrixPosition = m_GLprogram->GetUniform("EW_MatrixPosition");
m_GLtexID0 = m_GLprogram->GetUniform("EW_texID");
// Link material and Lights
m_material.Link(m_GLprogram, "EW_material");
m_GLMaterial.Link(m_GLprogram, "EW_material");
m_light.Link(m_GLprogram, "EW_directionalLight");
}
// this is the properties of the buffer requested : "r"/"w" + "-" + buffer type "f"=flaot "i"=integer
ewol::resource::Keep("w-fff", m_verticesVBO);
// load the curent file :
etk::UString tmpName = _fileName.ToLower();
// select the corect Loader :
if (true == tmpName.EndWith(".obj") ) {
if (false == LoadOBJ(_fileName)) {
EWOL_ERROR("Error To load OBJ file " << tmpName );
return;
}
} else if (true == tmpName.EndWith(".emf") ) {
if (false == LoadEMF(_fileName)) {
EWOL_ERROR("Error To load EMF file " << tmpName );
return;
}
//EWOL_CRITICAL("Load a new mesh : '" << _fileName << "' (end)");
} else {
// nothing to do ==> reqiest an enmpty mesh ==> user manage it ...
}
}
ewol::Mesh::~Mesh(void)
{
// remove dynamics dependencies :
if(NULL!=m_texture0) {
ewol::resource::Release(m_texture0);
}
ewol::resource::Release(m_GLprogram);
ewol::resource::Release(m_verticesVBO);
m_numberOfElments=0;
@ -113,6 +128,7 @@ ewol::Mesh::~Mesh(void)
void ewol::Mesh::Draw(mat4& positionMatrix)
{
EWOL_DEBUG("Request Draw : " << m_listIndexFaces.Size() << " elements");
#ifndef USE_INDEXED_MESH
if (m_numberOfElments<=0) {
return;
@ -122,10 +138,6 @@ void ewol::Mesh::Draw(mat4& positionMatrix)
return;
}
#endif
if (NULL == m_texture0) {
EWOL_WARNING("Texture does not exist ...");
return;
}
if (m_GLprogram==NULL) {
EWOL_ERROR("No shader ...");
return;
@ -139,8 +151,6 @@ void ewol::Mesh::Draw(mat4& positionMatrix)
mat4 tmpMatrix = projMatrix * camMatrix;
m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
m_GLprogram->UniformMatrix4fv(m_GLMatrixPosition, 1, positionMatrix.m_mat);
// TextureID
m_GLprogram->SetTexture0(m_GLtexID0, m_texture0->GetId());
// position :
m_GLprogram->SendAttributePointer(m_GLPosition, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_VERTICES);
// Texture :
@ -152,7 +162,7 @@ void ewol::Mesh::Draw(mat4& positionMatrix)
m_GLprogram->SendAttributePointer(m_GLNormalFace, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_FACE_NORMAL);
#endif
// draw materials :
m_material.Draw(m_GLprogram);
m_materials.GetValue(0)->Draw(m_GLprogram, m_GLMaterial);
m_light.Draw(m_GLprogram);
#ifndef USE_INDEXED_MESH
@ -160,6 +170,7 @@ void ewol::Mesh::Draw(mat4& positionMatrix)
ewol::openGL::DrawArrays(GL_TRIANGLES, 0, m_numberOfElments);
#else
ewol::openGL::DrawElements(GL_TRIANGLES, m_listIndexFaces);
EWOL_DEBUG("Draw : " << m_listIndexFaces.Size() << " elements");
#endif
m_GLprogram->UnUse();
ewol::openGL::Disable(ewol::openGL::FLAG_DEPTH_TEST);
@ -168,6 +179,7 @@ void ewol::Mesh::Draw(mat4& positionMatrix)
}
void ewol::Mesh::Draw2(mat4& positionMatrix)
{
EWOL_DEBUG("Request Draw2 : " << m_listIndexFaces.Size() << " elements");
#ifndef USE_INDEXED_MESH
if (m_numberOfElments<=0) {
return;
@ -177,10 +189,6 @@ void ewol::Mesh::Draw2(mat4& positionMatrix)
return;
}
#endif
if (NULL == m_texture0) {
EWOL_WARNING("Texture does not exist ...");
return;
}
if (m_GLprogram==NULL) {
EWOL_ERROR("No shader ...");
return;
@ -193,8 +201,6 @@ void ewol::Mesh::Draw2(mat4& positionMatrix)
mat4 tmpMatrix = projMatrix;
m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
m_GLprogram->UniformMatrix4fv(m_GLMatrixPosition, 1, positionMatrix.m_mat);
// TextureID
m_GLprogram->SetTexture0(m_GLtexID0, m_texture0->GetId());
// position :
m_GLprogram->SendAttributePointer(m_GLPosition, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_VERTICES);
// Texture :
@ -205,10 +211,10 @@ void ewol::Mesh::Draw2(mat4& positionMatrix)
#ifndef USE_INDEXED_MESH
m_GLprogram->SendAttributePointer(m_GLNormalFace, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_FACE_NORMAL);
#endif
// draw materials :
m_material.Draw(m_GLprogram);
m_light.Draw(m_GLprogram);
// draw materials :
m_materials.GetValue(0)->Draw(m_GLprogram, m_GLMaterial);
#ifndef USE_INDEXED_MESH
// Request the draw od the elements :
ewol::openGL::DrawArrays(GL_TRIANGLES, 0, m_numberOfElments);
@ -221,6 +227,7 @@ void ewol::Mesh::Draw2(mat4& positionMatrix)
glBindBuffer(GL_ARRAY_BUFFER,0);
}
// normal calculation of the normal face is really easy :
void ewol::Mesh::CalculateNormaleFace(void)
{
@ -229,10 +236,11 @@ void ewol::Mesh::CalculateNormaleFace(void)
if( true==m_enableFaceNormal
|| true==m_enableVertexNormal) {
for(int32_t iii=0 ; iii<m_listFaces.Size() ; iii++) {
etk::Vector<Face>& tmpFaceList = m_listFaces.GetValue(0);
for(int32_t iii=0 ; iii<tmpFaceList.Size() ; iii++) {
// for all case, We use only the 3 vertex for quad element, in theory 3D modeler export element in triangle if it is not a real plane.
vec3 normal = btCross(m_listVertex[m_listFaces[iii].m_vertex[0]]-m_listVertex[m_listFaces[iii].m_vertex[1]],
m_listVertex[m_listFaces[iii].m_vertex[1]]-m_listVertex[m_listFaces[iii].m_vertex[2]]);
vec3 normal = btCross(m_listVertex[tmpFaceList[iii].m_vertex[0]]-m_listVertex[tmpFaceList[iii].m_vertex[1]],
m_listVertex[tmpFaceList[iii].m_vertex[1]]-m_listVertex[tmpFaceList[iii].m_vertex[2]]);
m_listFacesNormal.PushBack(normal.normalized());
}
}
@ -245,14 +253,15 @@ void ewol::Mesh::CalculateNormaleEdge(void)
if(true==m_enableVertexNormal) {
for(int32_t iii=0 ; iii<m_listVertex.Size() ; iii++) {
etk::Vector<Face>& tmpFaceList = m_listFaces.GetValue(0);
vec3 normal(0,0,0);
// add the vertex from all the element in the list for face when the element in the face ...
for(int32_t jjj=0 ; jjj<m_listFaces.Size() ; jjj++) {
if( m_listFaces[jjj].m_vertex[0] == iii
|| m_listFaces[jjj].m_vertex[1] == iii
|| m_listFaces[jjj].m_vertex[2] == iii
|| ( m_listFaces[jjj].m_nbElement == 4
&& m_listFaces[jjj].m_vertex[3] == iii) ) {
for(int32_t jjj=0 ; jjj<tmpFaceList.Size() ; jjj++) {
if( tmpFaceList[jjj].m_vertex[0] == iii
|| tmpFaceList[jjj].m_vertex[1] == iii
|| tmpFaceList[jjj].m_vertex[2] == iii
|| ( tmpFaceList[jjj].m_nbElement == 4
&& tmpFaceList[jjj].m_vertex[3] == iii) ) {
normal += m_listFacesNormal[jjj];
}
}
@ -280,18 +289,19 @@ void ewol::Mesh::GenerateVBO(void)
// Generate element in 2 pass :
// - create new index dependeng a vertex is a unique componenet of position, texture, normal
// - the index list generation (can be dynamic ... (TODO later)
for (int32_t iii=0; iii<m_listFaces.Size() ; iii++) {
for(int32_t indice=0 ; indice<m_listFaces[iii].m_nbElement; indice++) {
vec3 position = m_listVertex[m_listFaces[iii].m_vertex[indice]];
vec3 normal = m_listVertexNormal[m_listFaces[iii].m_vertex[indice]];
vec2 texturepos(m_listUV[m_listFaces[iii].m_uv[indice]].x(),1.0f-m_listUV[m_listFaces[iii].m_uv[indice]].y());
etk::Vector<Face>& tmpFaceList = m_listFaces.GetValue(0);
for (int32_t iii=0; iii<tmpFaceList.Size() ; iii++) {
for(int32_t indice=0 ; indice<tmpFaceList[iii].m_nbElement; indice++) {
vec3 position = m_listVertex[tmpFaceList[iii].m_vertex[indice]];
vec3 normal = m_listVertexNormal[tmpFaceList[iii].m_vertex[indice]];
vec2 texturepos(m_listUV[tmpFaceList[iii].m_uv[indice]].x(),1.0f-m_listUV[tmpFaceList[iii].m_uv[indice]].y());
// try to find it in the list :
bool elementFind = false;
for (int32_t jjj=0; jjj<m_verticesVBO->SizeOnBufferVec3(MESH_VBO_VERTICES); jjj++) {
if( m_verticesVBO->GetOnBufferVec3(MESH_VBO_VERTICES,jjj) == position
&& m_verticesVBO->GetOnBufferVec3(MESH_VBO_VERTICES_NORMAL,jjj) == normal
&& m_verticesVBO->GetOnBufferVec2(MESH_VBO_TEXTURE,jjj) == texturepos) {
m_listFaces[iii].m_vertexVBOId[indice] = jjj;
tmpFaceList[iii].m_vertexVBOId[indice] = jjj;
elementFind = true;
// stop searching ...
break;
@ -301,25 +311,25 @@ void ewol::Mesh::GenerateVBO(void)
m_verticesVBO->PushOnBuffer(MESH_VBO_VERTICES, position);
m_verticesVBO->PushOnBuffer(MESH_VBO_VERTICES_NORMAL, normal);
m_verticesVBO->PushOnBuffer(MESH_VBO_TEXTURE, texturepos);
m_listFaces[iii].m_vertexVBOId[indice] = m_verticesVBO->SizeOnBufferVec3(MESH_VBO_VERTICES)-1;
tmpFaceList[iii].m_vertexVBOId[indice] = m_verticesVBO->SizeOnBufferVec3(MESH_VBO_VERTICES)-1;
}
}
}
for (int32_t iii=0; iii<m_listFaces.Size() ; iii++) {
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[0]);
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[1]);
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[2]);
for (int32_t iii=0; iii<tmpFaceList.Size() ; iii++) {
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[0]);
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[1]);
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[2]);
#ifndef PRINT_HALF
if (m_listFaces[iii].m_nbElement==4) {
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[0]);
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[2]);
m_listIndexFaces.PushBack(m_listFaces[iii].m_vertexVBOId[3]);
if (tmpFaceList[iii].m_nbElement==4) {
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[0]);
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[2]);
m_listIndexFaces.PushBack(tmpFaceList[iii].m_vertexVBOId[3]);
}
#endif
}
#else
// TODO : Set a better display system, this one is the worst I known ...
for (int32_t iii=0; iii<m_listFaces.Size() ; iii++) {
for (int32_t iii=0; iii<tmpFaceList.Size() ; iii++) {
#ifdef PRINT_HALF
m_numberOfElments += 3*3;
#else
@ -403,6 +413,7 @@ void ewol::Mesh::GenerateVBO(void)
void ewol::Mesh::CreateCube(float size)
{
#if 0
m_listVertex.Clear();
m_listUV.Clear();
m_listFaces.Clear();
@ -446,17 +457,19 @@ void ewol::Mesh::CreateCube(float size)
m_listUV.PushBack(vec2(1.0, 1.0));
m_listUV.PushBack(vec2(0.0, 1.0));
m_listFaces.PushBack(Face(0,0, 1,1, 2,2, 3,3));
m_listFaces.PushBack(Face(4,0, 0,1, 3,2, 7,3));
m_listFaces.PushBack(Face(2,0, 6,1, 7,2, 3,3));
m_listFaces.PushBack(Face(4,0, 7,1, 6,2, 5,3));
m_listFaces.PushBack(Face(1,0, 5,1, 6,2, 2,3));
m_listFaces.PushBack(Face(0,0, 4,1, 5,2, 1,3));
#endif
}
void ewol::Mesh::CreateViewBox(float size)
{
#if 0
m_listVertex.Clear();
m_listUV.Clear();
m_listFaces.Clear();
@ -535,36 +548,21 @@ void ewol::Mesh::CreateViewBox(float size)
m_listFaces.PushBack(Face(4,2, 7,3, 6,7, 5,6)); // 5
m_listFaces.PushBack(Face(1,5, 5,9, 6,10, 2,6)); // 1
m_listFaces.PushBack(Face(0,4, 4,8, 5,9, 1,5)); // 0
}
void ewol::Mesh::SetTexture(const etk::UString& myTexture)
{
ivec2 tmpSize(256, 256);
// prevent overloard error :
ewol::TextureFile* tmpCopy = m_texture0;
m_texture0 = NULL;
if (false == ewol::resource::Keep(myTexture, m_texture0, tmpSize)) {
EWOL_ERROR("Can not load specific texture : " << myTexture);
// retreave previous texture:
m_texture0 = tmpCopy;
return;
}
if (NULL != tmpCopy) {
// really release previous texture. In case of same texture loading, then we did not have reload it .. just increase and decrease index...
ewol::resource::Release(tmpCopy);
}
#endif
}
void ewol::Mesh::Subdivide(int32_t numberOfTime, bool smooth)
{
#if 0
for(int32_t iii=0; iii<numberOfTime ; iii++) {
InternalSubdivide(smooth);
}
#endif
}
int32_t CreateOrGetNewPointId(vertex_te type, const vec3& point, etk::Vector<VertexNode*>& list)
{
#if 0
for (int32_t iii=0; iii<list.Size(); iii++) {
if (list[iii]->GetPos() == point) {
return iii;
@ -576,10 +574,14 @@ int32_t CreateOrGetNewPointId(vertex_te type, const vec3& point, etk::Vector<Ver
}
list.PushBack(tmpElement);
return list.Size()-1;
#else
return 0;
#endif
}
int32_t CreateOrGetNewTexId(const vec2& point, etk::Vector<vec2>& list)
{
#if 0
for (int32_t iii=0; iii<list.Size(); iii++) {
if (list[iii] == point) {
return iii;
@ -587,10 +589,14 @@ int32_t CreateOrGetNewTexId(const vec2& point, etk::Vector<vec2>& list)
}
list.PushBack(point);
return list.Size()-1;
#else
return 0;
#endif
}
void ewol::Mesh::InternalSubdivide(bool smooth)
{
#if 0
//Copy the mesh for modify this one and not his parrent (that one is needed for smoothing)
etk::Vector<VertexNode*> listVertex;
for(int32_t iii=0; iii<m_listVertex.Size(); iii++) {
@ -806,6 +812,7 @@ void ewol::Mesh::InternalSubdivide(bool smooth)
}
}
listVertex.Clear();
#endif
}
@ -817,6 +824,7 @@ void ewol::Mesh::LoadMaterial(const etk::UString& name)
void ewol::Mesh::DisplaceElement(const ewol::DisplacementTable& displacement)
{
#if 0
CalculateNormaleFace();
CalculateNormaleEdge();
// displacement is done from the center of the element:
@ -850,6 +858,470 @@ void ewol::Mesh::DisplaceElement(const ewol::DisplacementTable& displacement)
vec3 translate = m_listVertexNormal[iii] * (move*4.0);
m_listVertex[iii] += translate;
}
#endif
}
bool ewol::Mesh::LoadOBJ(const etk::UString& _fileName)
{
#if 0
etk::FSNode fileName(_fileName);
// Get the fileSize ...
int32_t size = fileName.FileSize();
if (size == 0 ) {
EWOL_ERROR("No data in the file named=\"" << fileName << "\"");
return false;
}
if(false == fileName.FileOpenRead() ) {
EWOL_ERROR("Can not find the file name=\"" << fileName << "\"");
return false;
}
char inputDataLine[2048];
int32_t lineID = 0;
while (NULL != fileName.FileGets(inputDataLine, 2048) )
{
lineID++;
if (inputDataLine[0]=='v') {
if (inputDataLine[1]=='n') {
// Vertice normal : vn 0.000000 0.000000 -1.000000
// we did not use normal ==> we recalculated it if needed (some .obj does not export normal, then it is simple like this ...
// TODO : Use the normal provided ... => can be smooth or not ... (cf check "s 1")
} else if (inputDataLine[1]=='t') {
// Texture position : vt 0.748573 0.750412
vec2 vertex(0,0);
sscanf(&inputDataLine[3], "%f %f", &vertex.m_floats[0], &vertex.m_floats[1]);
m_listUV.PushBack(vertex);
} else {
// Vertice position : v 1.000000 -1.000000 -1.000000
vec3 vertex(0,0,0);
sscanf(&inputDataLine[2], "%f %f %f", &vertex.m_floats[0], &vertex.m_floats[1], &vertex.m_floats[2] );
m_listVertex.PushBack(vertex);
}
} else if (inputDataLine[0]=='f') {
// face : f 5/1/1 1/2/1 4/3/1*
uint32_t vertexIndex[4], uvIndex[4], normalIndex[4];
bool quadMode = true;
int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2],
&vertexIndex[3], &uvIndex[3], &normalIndex[3] );
if (12 != matches){
// no normal mode :
matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d %d/%d\n",
&vertexIndex[0], &uvIndex[0],
&vertexIndex[1], &uvIndex[1],
&vertexIndex[2], &uvIndex[2],
&vertexIndex[3], &uvIndex[3] );
if (8 != matches){
quadMode = false;
matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2] );
if (9 != matches){
// no normal mode :
matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d\n",
&vertexIndex[0], &uvIndex[0],
&vertexIndex[1], &uvIndex[1],
&vertexIndex[2], &uvIndex[2] );
if (6 != matches){
EWOL_ERROR("Parsing error in the .obj files : " << fileName << " (l=" << lineID << ") in 'f' section : \"" << &inputDataLine[2] << "\" expected : %d/%d(/%d) %d/%d(/%d) %d/%d(/%d) (%d/%d(/%d)) () for option");
continue;
}
}
}
}
if (true==quadMode) {
m_listFaces.PushBack(Face(vertexIndex[0]-1, uvIndex[0]-1,
vertexIndex[1]-1, uvIndex[1]-1,
vertexIndex[2]-1, uvIndex[2]-1,
vertexIndex[3]-1, uvIndex[3]-1));
} else {
m_listFaces.PushBack(Face(vertexIndex[0]-1, uvIndex[0]-1,
vertexIndex[1]-1, uvIndex[1]-1,
vertexIndex[2]-1, uvIndex[2]-1));
}
/*
EWOL_DEBUG(" plop : " << tmpFace.m_nbElement << " ? " << m_listFaces[m_listFaces.Size()-1].m_nbElement);
EWOL_DEBUG(" : " << tmpFace.m_vertex[0] << " ? " << m_listFaces[m_listFaces.Size()-1].m_vertex[0]);
EWOL_DEBUG(" : " << tmpFace.m_uv[0] << " ? " << m_listFaces[m_listFaces.Size()-1].m_uv[0]);
*/
} else if (inputDataLine[0]=='s') {
// ??? : s off
} else if (inputDataLine[0]=='#') {
// comment
// nothing to do ... just go to the new line ...
} else if( inputDataLine[0]=='u'
&& inputDataLine[1]=='s'
&& inputDataLine[2]=='e'
&& inputDataLine[3]=='m'
&& inputDataLine[4]=='t'
&& inputDataLine[5]=='l' ) {
// Use Material : usemtl imageName.xxx
while( inputDataLine[strlen(inputDataLine)-1] == '\n'
|| inputDataLine[strlen(inputDataLine)-1] == '\r'
|| inputDataLine[strlen(inputDataLine)-1] == ' ') {
if (1 == strlen(inputDataLine) ){
break;
}
inputDataLine[strlen(inputDataLine)-1] = '\0';
}
etk::UString tmpVal(&inputDataLine[7]);
SetTexture(fileName.GetRelativeFolder() + tmpVal);
} else if( inputDataLine[0]=='m'
&& inputDataLine[1]=='t'
&& inputDataLine[2]=='l'
&& inputDataLine[3]=='l'
&& inputDataLine[4]=='i'
&& inputDataLine[5]=='b' ) {
// ???? : mtllib cube.mtl
}
}
fileName.FileClose();
GenerateVBO();
#endif
return true;
}
char* LoadNextData(char* _elementLine, int64_t _maxData, etk::FSNode& _file, bool _removeTabs=false, bool _stopColomn=false)
{
memset(_elementLine, 0, _maxData);
char * element = _elementLine;
int64_t outSize = 0;
/*
if (m_zipReadingOffset>=m_zipContent->Size()) {
element[0] = '\0';
return NULL;
}
*/
char current = _file.FileGet();
while (current != '\0') {
if( _removeTabs==false
|| element != _elementLine) {
*element = current;
element++;
}
if( current == '\n'
|| current == '\r'
|| current == '|'
|| ( current == ':'
&& _stopColomn==true) )
{
*element = '\0';
//EWOL_DEBUG(" plop : '" << _elementLine << "'" );
return _elementLine;
} else if( element == _elementLine
&& current != '\t') {
*element = current;
element++;
}
// check maxData Size ...
if (outSize>=_maxData-1) {
*element = '\0';
return _elementLine;
}
current = _file.FileGet();
}
if (outSize==0) {
return NULL;
} else {
// send last line
return _elementLine;
}
return NULL;
}
bool ewol::Mesh::LoadEMF(const etk::UString& _fileName)
{
etk::FSNode fileName(_fileName);
// Get the fileSize ...
int32_t size = fileName.FileSize();
if (size == 0 ) {
EWOL_ERROR("No data in the file named=\"" << fileName << "\"");
return false;
}
if(false == fileName.FileOpenRead() ) {
EWOL_ERROR("Can not find the file name=\"" << fileName << "\"");
return false;
}
char inputDataLine[2048];
// load the first line :
fileName.FileGets(inputDataLine, 2048);
if(0==strncmp(inputDataLine, "EMF(STRING)", 11)) {
// parse in string mode ...
} else if (0==strncmp(inputDataLine, "EMF(BINARY)", 11)) {
EWOL_ERROR(" file binary mode is not supported now : 'EMF(BINARY)'");
return false;
} else {
EWOL_ERROR(" file mode is not supported now : 'EMF(? ? ?)' = '" << inputDataLine << "'");
return false;
}
while (NULL != LoadNextData(inputDataLine, 2048, fileName) ) {
//EWOL_DEBUG("min line : '" << inputDataLine << "'");
if( inputDataLine[0]=='#'
|| inputDataLine[0]=='\0' ) {
// comment line ... or empty line
continue;
}
if( inputDataLine[0]=='\t'
|| 0 == strncmp(inputDataLine, " ", 4) ) {
// Sub section that is not parsed ...
continue;
}
if( 0 == strncmp(inputDataLine, "Mesh :", 6) ) {
//Find a mesh ==> parse it ...
while (NULL != LoadNextData(inputDataLine, 2048, fileName) ) {
if( inputDataLine[0]=='#'
|| inputDataLine[0]=='\0' ) {
// comment line ... or empty line
continue;
}
if( 0 == strncmp(inputDataLine, "\tName : ", 8) ) {
// find the mesh name.
etk::UString m_meshName = &inputDataLine[8];
EWOL_DEBUG("Load sub mesh named : '" << m_meshName << "'");
continue;
}
if( 0 == strncmp(inputDataLine, "\tVertex : ", 10) ) {
// find the vertex list of elements.
while (NULL != LoadNextData(inputDataLine, 2048, fileName, true) ) {
if (inputDataLine[0] == '\0') {
break;
}
vec3 vertex(0,0,0);
sscanf(inputDataLine, "%f %f %f", &vertex.m_floats[0], &vertex.m_floats[1], &vertex.m_floats[2] );
m_listVertex.PushBack(vertex);
}
EWOL_DEBUG("Load " << m_listVertex.Size() << " vertex");
continue;
}
if( 0 == strncmp(inputDataLine, "\tUV-mapping :", 13) ) {
// find the UV mapping.
while (NULL != LoadNextData(inputDataLine, 2048, fileName, true) ) {
if (inputDataLine[0] == '\0') {
break;
}
vec2 uvMap(0,0);
sscanf(inputDataLine, "%f %f", &uvMap.m_floats[0], &uvMap.m_floats[1]);
m_listUV.PushBack(uvMap);
}
EWOL_DEBUG("Load " << m_listUV.Size() << " uv mapping point");
continue;
}
if( 0 == strncmp(inputDataLine, "\tNormal(vertex) : ", 18) ) {
// find the vertex Normal list.
while (NULL != LoadNextData(inputDataLine, 2048, fileName, true) ) {
if (inputDataLine[0] == '\0') {
break;
}
vec3 normal(0,0,0);
sscanf(inputDataLine, "%f %f %f", &normal.m_floats[0], &normal.m_floats[1], &normal.m_floats[2] );
m_listVertexNormal.PushBack(normal);
}
EWOL_DEBUG("Load " << m_listVertexNormal.Size() << " vertex normal");
continue;
}
if( 0 == strncmp(inputDataLine, "\tNormal(face) : ", 16) ) {
// find the face Normal list.
while (NULL != LoadNextData(inputDataLine, 2048, fileName, true) ) {
if (inputDataLine[0] == '\0') {
break;
}
vec3 normal(0,0,0);
sscanf(inputDataLine, "%f %f %f", &normal.m_floats[0], &normal.m_floats[1], &normal.m_floats[2] );
m_listFacesNormal.PushBack(normal);
}
EWOL_DEBUG("Load " << m_listFacesNormal.Size() << " face normal");
continue;
}
if( 0 == strncmp(inputDataLine, "\tFace : ", 8) ) {
// find the face list.
int32_t elementID = -1;
while (NULL != LoadNextData(inputDataLine, 2048, fileName, true, true) ) {
if (inputDataLine[0] == '\0') {
break;
}
//EWOL_DEBUG("parse :'" << inputDataLine << "'");
int32_t len = strlen(inputDataLine);
if (inputDataLine[len-1] == ':') {
// find the material :
inputDataLine[len-1] = '\0';
etk::UString materialName = inputDataLine;
etk::Vector<Face> empty;
m_listFaces.Add(materialName, empty);
elementID = m_listFaces.GetId(materialName);
} else {
if (elementID < 0) {
continue;
}
int32_t matches;
uint32_t vertexIndex[3], uvIndex[3], normalIndex[3];
vertexIndex[0] = 0;
vertexIndex[1] = 0;
vertexIndex[2] = 0;
uvIndex[0] = 0;
uvIndex[1] = 0;
uvIndex[2] = 0;
normalIndex[0] = 0;
normalIndex[1] = 0;
normalIndex[2] = 0;
matches = sscanf(inputDataLine, "%d/%d/%d %d/%d/%d %d/%d/%d",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2] );
m_listFaces.GetValue(elementID).PushBack(Face(vertexIndex[0], uvIndex[0],
vertexIndex[1], uvIndex[1],
vertexIndex[2], uvIndex[2]));
/*
EWOL_DEBUG("face :" << vertexIndex[0] << "/" << uvIndex[0] << "/" << normalIndex[0] <<
" " << vertexIndex[1] << "/" << uvIndex[1] << "/" << normalIndex[1] <<
" " << vertexIndex[2] << "/" << uvIndex[2] << "/" << normalIndex[2]);
*/
}
}
EWOL_DEBUG("Load " << m_listFaces.Size() << " faces (mode) :");
for (esize_t iii=0; iii< m_listFaces.Size(); iii++) {
EWOL_DEBUG(" mat='" << m_listFaces.GetKey(iii) << "' nb faces=" << m_listFaces.GetValue(iii).Size());
}
break;
}
}
continue;
}
if( 0 == strncmp(inputDataLine, "Materials : ", 11) ) {
//Find Material section ==> parse it ...
//EWOL_DEBUG("find a Maretials section :");
// all object might have minimaly one material :
ewol::Material* material = NULL;
etk::UString name = "";
//Find a mesh ==> parse it ...
while (NULL != LoadNextData(inputDataLine, 2048, fileName) ) {
//EWOL_DEBUG("mat parse : '" << inputDataLine << "'");
if( inputDataLine[0] == '\t'
&& inputDataLine[1] != '\t') {
if( name != ""
&& material!=NULL) {
m_materials.Add(name, material);
name = "";
material = NULL;
}
material = new ewol::Material();
inputDataLine[strlen(inputDataLine)-1] = '\0';
name = &inputDataLine[1];
EWOL_DEBUG("Create materials : '" << name << "'");
} else {
if (NULL != material) {
if( inputDataLine[2] == 'N'
&& inputDataLine[3] == 's'
&& inputDataLine[4] == ' ' ) {
float tmpVal=0;
sscanf(&inputDataLine[5], "%f", &tmpVal);
material->SetShininess(tmpVal);
} else if( inputDataLine[2] == 'K'
&& inputDataLine[3] == 'a'
&& inputDataLine[4] == ' ' ) {
float tmpVal1=0;
float tmpVal2=0;
float tmpVal3=0;
sscanf(&inputDataLine[5], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3);
vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1);
material->SetAmbientFactor(tmp);
} else if( inputDataLine[2] == 'K'
&& inputDataLine[3] == 'd'
&& inputDataLine[4] == ' ' ) {
float tmpVal1=0;
float tmpVal2=0;
float tmpVal3=0;
sscanf(&inputDataLine[5], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3);
vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1);
material->SetDiffuseFactor(tmp);
} else if( inputDataLine[2] == 'K'
&& inputDataLine[3] == 's'
&& inputDataLine[4] == ' ' ) {
float tmpVal1=0;
float tmpVal2=0;
float tmpVal3=0;
sscanf(&inputDataLine[5], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3);
vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1);
material->SetSpecularFactor(tmp);
} else if( inputDataLine[2] == 'N'
&& inputDataLine[3] == 'i'
&& inputDataLine[4] == ' ' ) {
float tmpVal=0;
sscanf(&inputDataLine[5], "%f", &tmpVal);
// TODO : ...
} else if( inputDataLine[2] == 'd'
&& inputDataLine[3] == ' ' ) {
float tmpVal=0;
sscanf(&inputDataLine[4], "%f", &tmpVal);
// TODO : ...
} else if( inputDataLine[2] == 'i'
&& inputDataLine[3] == 'l'
&& inputDataLine[4] == 'l'
&& inputDataLine[5] == 'u'
&& inputDataLine[6] == 'm'
&& inputDataLine[7] == ' ' ) {
// TODO : ...
} else if( inputDataLine[2] == 'm'
&& inputDataLine[3] == 'a'
&& inputDataLine[4] == 'p'
&& inputDataLine[5] == '_'
&& inputDataLine[6] == 'K'
&& inputDataLine[7] == 'd'
&& inputDataLine[8] == ' ' ) {
inputDataLine[strlen(inputDataLine)-1] = '\0';
material->SetTexture0(fileName.GetRelativeFolder() + &inputDataLine[9]);
} else {
EWOL_ERROR("unknow material property ... : '" << inputDataLine << "'");
}
}
}
}
if( name != ""
&& material!=NULL) {
m_materials.Add(name, material);
name = "";
material = NULL;
}
continue;
}
/* exemple of file
EMF(STRING)
# Blender v2.66 (sub 1) EMF File: 'station.blend'
Mesh : 1
Name : MainControl_mesh
Vertex : 174
0.500000 0.015097 -1.170499|-1.003113 0.010738 -1.000184|1.003173 0.013001 -0.998027|
UV-mapping :
0.964431 0.766844|0.939031 0.811940|1.050593 0.813877|0.815493 0.602993|0.783793 0.520610|
Normal(face) : 344
0.310313 -0.276298 0.909596|-0.426055 -0.318865 0.846642|-0.915346 -0.402637 -0.004953|
Face : 344
Material: 23/1/1 9/2/1 2/3/1| 18/4/2 20/5/2 1/6/2| 18/4/3 1/6/3 5/7/3|
Materials : 1
Material
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd station.png
- Ka - material ambient is multiplied by the texture value
- Kd - material diffuse is multiplied by the texture value
- Ks - material specular is multiplied by the texture value
- Ns - material specular exponent is multiplied by the texture value
- d - material dissolve is multiplied by the texture value
*/
}
fileName.FileClose();
GenerateVBO();
return true;
}

View File

@ -10,6 +10,7 @@
#define __MESH_H__
#include <etk/types.h>
#include <etk/Hach.h>
#include <ewol/renderer/resources/Resource.h>
#include <ewol/renderer/resources/Image.h>
#include <ewol/renderer/resources/Shader.h>
@ -152,25 +153,24 @@ namespace ewol
int32_t m_GLNormal;
int32_t m_GLNormalFace;
int32_t m_GLtexture;
int32_t m_GLtexID0;
int32_t m_bufferOfset;
int32_t m_numberOfElments;
ewol::Material m_material;
MaterialGlId m_GLMaterial;
ewol::Light m_light;
protected:
etk::Vector<vec3> m_listVertex; //!< List of all vertex in the element
etk::Vector<vec2> m_listUV; //!< List of all UV point in the mesh (for the specify texture)
etk::Vector<Face> m_listFaces; //!< List of all Face for the mesh
etk::Vector<vec3> m_listFacesNormal; //!< List of all Face normal, when calculated
etk::Vector<vec3> m_listVertexNormal; //!< List of all Face normal, when calculated
etk::Hash<etk::Vector<Face> > m_listFaces; //!< List of all Face for the mesh
etk::Hash<ewol::Material*> m_materials;
#ifdef USE_INDEXED_MESH
etk::Vector<uint32_t> m_listIndexFaces;
#endif
protected:
ewol::VirtualBufferObject* m_verticesVBO;
ewol::TextureFile* m_texture0;
ewol::VirtualBufferObject* m_verticesVBO;
public:
Mesh(etk::UString genName, etk::UString shaderName="DATA:textured3D2.prog");
Mesh(const etk::UString& _fileName, const etk::UString& _shaderName="DATA:textured3D2.prog");
virtual ~Mesh(void);
virtual const char* GetType(void) { return "ewol::Mesh"; };
virtual void Draw(mat4& positionMatrix);
@ -201,6 +201,9 @@ namespace ewol
void CreateViewBox(float size=1.0);
void Subdivide(int32_t numberOfTime, bool smooth);
void DisplaceElement(const ewol::DisplacementTable& displacement);
private:
bool LoadOBJ(const etk::UString& _fileName);
bool LoadEMF(const etk::UString& _fileName);
};
};

View File

@ -1,140 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <etk/Vector.h>
#include <etk/os/FSNode.h>
#include <ewol/debug.h>
#include <ewol/renderer/ResourceManager.h>
#include <ewol/renderer/resources/MeshObj.h>
#undef __class__
#define __class__ "MeshObj"
ewol::MeshObj::MeshObj(etk::UString _fileName) :
ewol::Mesh(_fileName)
{
etk::FSNode fileName(_fileName);
// Get the fileSize ...
int32_t size = fileName.FileSize();
if (size == 0 ) {
EWOL_ERROR("No data in the file named=\"" << fileName << "\"");
return;
}
if(false == fileName.FileOpenRead() ) {
EWOL_ERROR("Can not find the file name=\"" << fileName << "\"");
return;
}
char inputDataLine[2048];
int32_t lineID = 0;
while (NULL != fileName.FileGets(inputDataLine, 2048) )
{
lineID++;
if (inputDataLine[0]=='v') {
if (inputDataLine[1]=='n') {
// Vertice normal : vn 0.000000 0.000000 -1.000000
// we did not use normal ==> we recalculated it if needed (some .obj does not export normal, then it is simple like this ...
} else if (inputDataLine[1]=='t') {
// Texture position : vt 0.748573 0.750412
vec2 vertex(0,0);
sscanf(&inputDataLine[3], "%f %f", &vertex.m_floats[0], &vertex.m_floats[1]);
m_listUV.PushBack(vertex);
} else {
// Vertice position : v 1.000000 -1.000000 -1.000000
vec3 vertex(0,0,0);
sscanf(&inputDataLine[2], "%f %f %f", &vertex.m_floats[0], &vertex.m_floats[1], &vertex.m_floats[2] );
m_listVertex.PushBack(vertex);
}
} else if (inputDataLine[0]=='f') {
// face : f 5/1/1 1/2/1 4/3/1*
uint32_t vertexIndex[4], uvIndex[4], normalIndex[4];
bool quadMode = true;
int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2],
&vertexIndex[3], &uvIndex[3], &normalIndex[3] );
if (12 != matches){
// no normal mode :
matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d %d/%d\n",
&vertexIndex[0], &uvIndex[0],
&vertexIndex[1], &uvIndex[1],
&vertexIndex[2], &uvIndex[2],
&vertexIndex[3], &uvIndex[3] );
if (8 != matches){
quadMode = false;
matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2] );
if (9 != matches){
// no normal mode :
matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d\n",
&vertexIndex[0], &uvIndex[0],
&vertexIndex[1], &uvIndex[1],
&vertexIndex[2], &uvIndex[2] );
if (6 != matches){
EWOL_ERROR("Parsing error in the .obj files : " << fileName << " (l=" << lineID << ") in 'f' section : \"" << &inputDataLine[2] << "\" expected : %d/%d(/%d) %d/%d(/%d) %d/%d(/%d) (%d/%d(/%d)) () for option");
continue;
}
}
}
}
if (true==quadMode) {
m_listFaces.PushBack(Face(vertexIndex[0]-1, uvIndex[0]-1,
vertexIndex[1]-1, uvIndex[1]-1,
vertexIndex[2]-1, uvIndex[2]-1,
vertexIndex[3]-1, uvIndex[3]-1));
} else {
m_listFaces.PushBack(Face(vertexIndex[0]-1, uvIndex[0]-1,
vertexIndex[1]-1, uvIndex[1]-1,
vertexIndex[2]-1, uvIndex[2]-1));
}
/*
EWOL_DEBUG(" plop : " << tmpFace.m_nbElement << " ? " << m_listFaces[m_listFaces.Size()-1].m_nbElement);
EWOL_DEBUG(" : " << tmpFace.m_vertex[0] << " ? " << m_listFaces[m_listFaces.Size()-1].m_vertex[0]);
EWOL_DEBUG(" : " << tmpFace.m_uv[0] << " ? " << m_listFaces[m_listFaces.Size()-1].m_uv[0]);
*/
} else if (inputDataLine[0]=='s') {
// ??? : s off
} else if (inputDataLine[0]=='#') {
// comment
// nothing to do ... just go to the new line ...
} else if( inputDataLine[0]=='u'
&& inputDataLine[1]=='s'
&& inputDataLine[2]=='e'
&& inputDataLine[3]=='m'
&& inputDataLine[4]=='t'
&& inputDataLine[5]=='l' ) {
// Use Material : usemtl imageName.xxx
while( inputDataLine[strlen(inputDataLine)-1] == '\n'
|| inputDataLine[strlen(inputDataLine)-1] == '\r'
|| inputDataLine[strlen(inputDataLine)-1] == ' ') {
if (1 == strlen(inputDataLine) ){
break;
}
inputDataLine[strlen(inputDataLine)-1] = '\0';
}
etk::UString tmpVal(&inputDataLine[7]);
SetTexture(fileName.GetRelativeFolder() + tmpVal);
} else if( inputDataLine[0]=='m'
&& inputDataLine[1]=='t'
&& inputDataLine[2]=='l'
&& inputDataLine[3]=='l'
&& inputDataLine[4]=='i'
&& inputDataLine[5]=='b' ) {
// ???? : mtllib cube.mtl
}
}
fileName.FileClose();
GenerateVBO();
}

View File

@ -1,32 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __MESH_OBJ_H__
#define __MESH_OBJ_H__
#include <etk/types.h>
#include <etk/UString.h>
#include <ewol/renderer/resources/Mesh.h>
namespace ewol
{
class MeshObj : public ewol::Mesh
{
public:
MeshObj(etk::UString fileName);
~MeshObj(void) { };
virtual const char* GetType(void) { return "ewol::MeshObj"; };
};
};
#endif

View File

@ -11,7 +11,7 @@
#include <etk/types.h>
#include <ewol/widget/Widget.h>
#include <ewol/renderer/resources/MeshObj.h>
#include <ewol/renderer/resources/Mesh.h>
extern const char * const ewolEventMeshPressed;
@ -22,7 +22,7 @@ namespace widget {
private:
// mesh name :
etk::UString m_meshName;
ewol::MeshObj* m_object;
ewol::Mesh* m_object;
// mesh display properties:
vec3 m_position;
vec3 m_angle;

View File

@ -52,7 +52,6 @@ def Create(target):
'ewol/renderer/resources/FontFreeType.cpp',
'ewol/renderer/resources/TexturedFont.cpp',
'ewol/renderer/resources/Mesh.cpp',
'ewol/renderer/resources/MeshObj.cpp',
'ewol/renderer/resources/Texture.cpp',
'ewol/renderer/resources/Colored3DObject.cpp',
'ewol/renderer/resources/Image.cpp',