From a87d61c9962d8e22e23eacd4e49049adc3e214a0 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 2 Jun 2017 23:26:56 +0200 Subject: [PATCH] [DEV] continue to correct link between blender, ege and ephysics --- blender/io_scene_emf/__init__.py | 69 +------------- blender/io_scene_emf/export_emf.py | 63 +++---------- ege/physics/Component.cpp | 143 ++++++++++++++++++++++++++++- ege/physics/Component.hpp | 80 +++++++++++++++- ege/physics/Engine.cpp | 9 ++ ege/resource/MeshGird.cpp | 12 +-- 6 files changed, 249 insertions(+), 127 deletions(-) diff --git a/blender/io_scene_emf/__init__.py b/blender/io_scene_emf/__init__.py index 038f22d..775deef 100644 --- a/blender/io_scene_emf/__init__.py +++ b/blender/io_scene_emf/__init__.py @@ -46,45 +46,14 @@ class ImportEMF(bpy.types.Operator, ImportHelper): options={'HIDDEN'}, ) - 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='-X', - ) - - 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='Z', - ) - def execute(self, context): # print("Selected: " + context.active_object.name) from . import import_obj - keywords = self.as_keywords(ignore=("axis_forward", - "axis_up", - "filter_glob", + keywords = self.as_keywords(ignore=("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): @@ -94,8 +63,6 @@ class ImportEMF(bpy.types.Operator, ImportHelper): 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") @@ -141,30 +108,6 @@ class ExportEMF(bpy.types.Operator, ExportHelper): default="phys" ) - 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='-Y', - ) - - 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='Z', - ) - path_mode = path_reference_mode check_extension = True @@ -173,9 +116,7 @@ class ExportEMF(bpy.types.Operator, ExportHelper): from . import export_emf from mathutils import Matrix - keywords = self.as_keywords(ignore=("axis_forward", - "axis_up", - "global_scale", + keywords = self.as_keywords(ignore=("global_scale", "check_existing", "filter_glob", )) @@ -186,12 +127,6 @@ class ExportEMF(bpy.types.Operator, ExportHelper): 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) diff --git a/blender/io_scene_emf/export_emf.py b/blender/io_scene_emf/export_emf.py index 811429a..dfb62e7 100644 --- a/blender/io_scene_emf/export_emf.py +++ b/blender/io_scene_emf/export_emf.py @@ -49,38 +49,20 @@ To create a compound physics collision shape for a mesh in blender: default=True) """ -# Methods for writing point, scale, and quaternion types to a YAML file. -# This particular implementation converts values to a Y-up coordinate system. -def out_point3_y_up( v ): - return "%g %g %g" % ( v.x, v.z, -v.y ) -def out_scale3_y_up( s ): - return "%g %g %g" % ( s.x, s.z, s.y ) -def out_quaternion_y_up( q ): - return "%g %g %g %g" % ( q.x, q.z, -q.y, q.w ) -# This implementation maintains blender's Z-up coordinate system. -def out_point3_z_up( v ): +def out_point3( v ): return "%g %g %g" % ( v.x, v.y, v.z ) -def out_scale3_z_up( s ): +def out_scale3( s ): return "%g %g %g" % ( s.x, s.y, s.z ) -def out_quaternion_z_up( q ): +def out_quaternion( q ): return "%g %g %g %g" % ( q.x, q.y, q.z, q.w ) -def get_physics_shape(obj, mainObjScale, use_y_up=False): +def get_physics_shape(obj, mainObjScale): shape = "" props = { } name = obj.name.lower() scale = Vector(( abs(obj.scale.x), abs(obj.scale.y), abs(obj.scale.z) )) - if use_y_up: - out_point3 = out_point3_y_up - out_scale3 = out_scale3_y_up - out_quaternion = out_quaternion_y_up - else: - out_point3 = out_point3_z_up - out_scale3 = out_scale3_z_up - out_quaternion = out_quaternion_z_up - # BOX if name.startswith('box') \ or name.startswith('cube'): @@ -99,12 +81,12 @@ def get_physics_shape(obj, mainObjScale, use_y_up=False): elif name.startswith('cyl'): shape = "Cylinder" props["radius"] = (obj.scale.x + obj.scale.y)*0.5 - props["size"] = obj.scale.z + props["size"] = obj.scale.z * 2.0 # CAPSULE elif name.startswith('cap'): shape = "Capsule" props["radius"] = (obj.scale.x + obj.scale.y)*0.5 - props["size"] = obj.scale.z + props["size"] = obj.scale.z * 2.0 # CONVEX-HULL elif name.startswith('convex'): shape = "ConvexHull" @@ -122,18 +104,12 @@ def get_physics_shape(obj, mainObjScale, use_y_up=False): if obj.matrix_world.to_translation() != Vector((0,0,0)): props["origin"] = out_point3(obj.matrix_world.to_translation()) - if obj.rotation_mode == 'QUATERNION': - qrot = obj.rotation_quaternion - else: - qrot = obj.matrix_local.to_quaternion() - - print(" Origin (local ): " + str(obj.location)) - print(" Origin (global): " + str(obj.matrix_world.to_translation())) - print(" Quaternion (local ): " + str(qrot)) - print(" Quaternion (global): " + str(obj.matrix_world.to_quaternion())) - + qrot = obj.matrix_world.to_quaternion() if qrot != Quaternion((1,0,0,0)): - props["rotate"] = out_quaternion(obj.matrix_world.to_quaternion()) + props["rotate"] = out_quaternion(qrot) + props["mass"] = obj.scale.x * obj.scale.y * obj.scale.z * 100.0 + if props["mass"] < 0.01: + props["mass"] = 0.01 return (shape, props) @@ -293,7 +269,7 @@ def veckey3d(v): def veckey2d(v): return round(v[0], 6), round(v[1], 6) -def write_mesh(scene, file, object, EXPORT_GLOBAL_MATRIX, mtl_dict): +def write_mesh(scene, file, object, mtl_dict): print("**************** '" + str(object.name) + "' *******************") # Initialize totals, these are updated each object @@ -338,8 +314,7 @@ def write_mesh(scene, file, object, EXPORT_GLOBAL_MATRIX, mtl_dict): me = None if me is None: continue - me.transform(EXPORT_GLOBAL_MATRIX * ob_mat) - #print("ploppp:" + str(EXPORT_GLOBAL_MATRIX) ) + me.transform(ob_mat) #print("ploppp:" + str(ob_mat) ) # _must_ do this first since it re-allocs arrays # triangulate all the mesh: @@ -564,14 +539,10 @@ def write_mesh(scene, file, object, EXPORT_GLOBAL_MATRIX, mtl_dict): def write_file(filepath, objects, scene, - EXPORT_GLOBAL_MATRIX=None, EXPORT_PATH_MODE='AUTO', EXPORT_BINARY_MODE=False, EXPORT_COLLISION_NAME="" ): - if EXPORT_GLOBAL_MATRIX is None: - EXPORT_GLOBAL_MATRIX = mathutils.Matrix() - print('EMF Export path: %r' % filepath) time1 = time.time() @@ -615,12 +586,12 @@ def write_file(filepath, # Get all meshes for ob_main in objects: if ob_main.type == 'MESH': - write_mesh(scene, file, ob_main, EXPORT_GLOBAL_MATRIX, mtl_dict) + write_mesh(scene, file, ob_main, mtl_dict) elif ob_main.type == 'EMPTY': for sub_obj in getChildren(ob_main): print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type) if sub_obj.type == 'MESH': - write_mesh(scene, file, sub_obj, EXPORT_GLOBAL_MATRIX, mtl_dict) + write_mesh(scene, file, sub_obj, mtl_dict) elif sub_obj.type == 'EMPTY' \ and sub_obj.name.lower().startswith("physic"): print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type) @@ -654,7 +625,6 @@ def write_file(filepath, def _write(context, filepath, EXPORT_SEL_ONLY, - EXPORT_GLOBAL_MATRIX, EXPORT_PATH_MODE, EXPORT_BINARY_MODE, EXPORT_COLLISION_NAME, @@ -683,7 +653,6 @@ def _write(context, write_file(full_path, objects, scene, - EXPORT_GLOBAL_MATRIX, EXPORT_PATH_MODE, EXPORT_BINARY_MODE, EXPORT_COLLISION_NAME, @@ -701,13 +670,11 @@ def save(operator, use_selection=True, use_binary=False, collision_object_name="", - global_matrix=None, path_mode='AUTO' ): _write(context, filepath, EXPORT_SEL_ONLY=use_selection, - EXPORT_GLOBAL_MATRIX=global_matrix, EXPORT_PATH_MODE=path_mode, EXPORT_BINARY_MODE=use_binary, EXPORT_COLLISION_NAME=collision_object_name, diff --git a/ege/physics/Component.cpp b/ege/physics/Component.cpp index 1bf4ef2..f36cdf9 100644 --- a/ege/physics/Component.cpp +++ b/ege/physics/Component.cpp @@ -27,7 +27,9 @@ void ege::physics::Component::newContact(ege::physics::Component* _other, const EGE_WARNING(" collision [ NEW ] " << _pos << " depth=" << _penetrationDepth); } -ege::physics::Component::Component(ememory::SharedPtr _env) { +ege::physics::Component::Component(ememory::SharedPtr _env): + m_staticForceApplyCenterOfMass(0,0,0), + m_staticTorqueApply(0,0,0) { m_engine = ememory::dynamicPointerCast(_env->getEngine(getType())); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(0.0f, 0.0f, 0.0f); @@ -40,7 +42,9 @@ ege::physics::Component::Component(ememory::SharedPtr _env) { //m_engine->getDynamicWorld()->testCollision(m_rigidBody, this); } -ege::physics::Component::Component(ememory::SharedPtr _env, const etk::Transform3D& _transform) { +ege::physics::Component::Component(ememory::SharedPtr _env, const etk::Transform3D& _transform): + m_staticForceApplyCenterOfMass(0,0,0), + m_staticTorqueApply(0,0,0) { m_engine = ememory::dynamicPointerCast(_env->getEngine(getType())); rp3d::Vector3 initPosition(_transform.getPosition().x(), _transform.getPosition().y(), @@ -56,6 +60,10 @@ ege::physics::Component::Component(ememory::SharedPtr _env, c m_lastTransformEmit = _transform; // set collision callback: //m_engine->getDynamicWorld()->testCollision(m_rigidBody, this); + EGE_ERROR("Bounciness=" << m_rigidBody->getMaterial().getBounciness()); + EGE_ERROR("FrictionCoefficient=" << m_rigidBody->getMaterial().getFrictionCoefficient()); + EGE_ERROR("RollingResistance=" << m_rigidBody->getMaterial().getRollingResistance()); + m_rigidBody->getMaterial().setFrictionCoefficient(0.5); } void ege::physics::Component::setType(enum ege::physics::Component::type _type) { @@ -261,6 +269,22 @@ void ege::physics::Component::emitAll() { } } +void ege::physics::Component::update(float _delta) { + if (m_rigidBody == nullptr) { + return; + } + if (m_staticForceApplyCenterOfMass != rp3d::Vector3(0,0,0)) { + rp3d::Vector3 tmp = m_staticForceApplyCenterOfMass*_delta; + EGE_ERROR("FORCE : " << vec3(tmp.x, tmp.y, tmp.z) ); + m_rigidBody->applyForceToCenterOfMass(tmp); + } + if (m_staticTorqueApply != rp3d::Vector3(0,0,0)) { + rp3d::Vector3 tmp = m_staticTorqueApply*_delta; + EGE_ERROR("TORQUE : " << vec3(tmp.x, tmp.y, tmp.z)); + m_rigidBody->applyTorque(tmp); + } +} + void ege::physics::Component::setTransform(const etk::Transform3D& _transform) { if (m_rigidBody == nullptr) { @@ -312,6 +336,28 @@ void ege::physics::Component::setLinearVelocity(const vec3& _linearVelocity) { m_rigidBody->setLinearVelocity(value); } +vec3 ege::physics::Component::getRelativeLinearVelocity() const { + if (m_rigidBody == nullptr) { + return vec3(0,0,0); + } + rp3d::Vector3 value = m_rigidBody->getLinearVelocity(); + value = m_rigidBody->getTransform().getOrientation().getInverse()*value; + return vec3(value.x, + value.y, + value.z); +} + +void ege::physics::Component::setRelativeLinearVelocity(const vec3& _linearVelocity) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 value(_linearVelocity.x(), + _linearVelocity.y(), + _linearVelocity.z()); + value = m_rigidBody->getTransform().getOrientation()*value; + m_rigidBody->setLinearVelocity(value); +} + vec3 ege::physics::Component::getAngularVelocity() const { if (m_rigidBody == nullptr) { return vec3(0,0,0); @@ -331,6 +377,99 @@ void ege::physics::Component::setAngularVelocity(const vec3& _angularVelocity) { m_rigidBody->setAngularVelocity(value); } +vec3 ege::physics::Component::getRelativeAngularVelocity() const { + if (m_rigidBody == nullptr) { + return vec3(0,0,0); + } + rp3d::Vector3 value = m_rigidBody->getAngularVelocity(); + value = m_rigidBody->getTransform().getOrientation().getInverse()*value; + return vec3(value.x, + value.y, + value.z); +} +void ege::physics::Component::setRelativeAngularVelocity(const vec3& _angularVelocity) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 value(_angularVelocity.x(), + _angularVelocity.y(), + _angularVelocity.z()); + value = m_rigidBody->getTransform().getOrientation()*value; + m_rigidBody->setAngularVelocity(value); +} + + +void ege::physics::Component::applyForce(const vec3& _force,const vec3& _point) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 force(_force.x(), + _force.y(), + _force.z()); + rp3d::Vector3 point(_point.x(), + _point.y(), + _point.z()); + m_rigidBody->applyForce(force, point); +} + +void ege::physics::Component::applyForceToCenterOfMass(const vec3& _force, bool _static) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 force(_force.x(), + _force.y(), + _force.z()); + if(_static == true) { + m_staticForceApplyCenterOfMass = force; + } else { + m_rigidBody->applyForceToCenterOfMass(force); + } +} + +void ege::physics::Component::applyRelativeForceToCenterOfMass(const vec3& _force, bool _static) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 force(_force.x(), + _force.y(), + _force.z()); + force = m_rigidBody->getTransform().getOrientation()*force; + if(_static == true) { + m_staticForceApplyCenterOfMass = force; + } else { + m_rigidBody->applyForceToCenterOfMass(force); + } +} + +void ege::physics::Component::applyTorque(const vec3& _torque, bool _static) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 torque(_torque.x(), + _torque.y(), + _torque.z()); + if(_static == true) { + m_staticTorqueApply = torque; + } else { + m_rigidBody->applyTorque(torque); + } +} + +void ege::physics::Component::applyRelativeTorque(const vec3& _torque, bool _static) { + if (m_rigidBody == nullptr) { + return; + } + rp3d::Vector3 torque(_torque.x(), + _torque.y(), + _torque.z()); + torque = m_rigidBody->getTransform().getOrientation()*torque; + if(_static == true) { + m_staticTorqueApply = torque; + } else { + m_rigidBody->applyTorque(torque); + } +} + const std::vector>& ege::physics::Component::getShape() const { return m_shape; } diff --git a/ege/physics/Component.hpp b/ege/physics/Component.hpp index c5d9dbd..89dbb61 100644 --- a/ege/physics/Component.hpp +++ b/ege/physics/Component.hpp @@ -61,25 +61,94 @@ namespace ege { */ etk::Transform3D getTransform() const; /** - * @brief Get the linear velocity. + * @brief Get the linear velocity (whole world). * @return The linear velocity vector of the body */ vec3 getLinearVelocity() const; /** - * @brief Set the linear velocity. + * @brief Set the linear velocity (whole world). * @param[in] _linearVelocity The linear velocity vector of the body */ void setLinearVelocity(const vec3& _linearVelocity); /** - * @brief Get the angular velocity. + * @brief Get the linear velocity (local Body). + * @return The linear velocity vector of the body + */ + vec3 getRelativeLinearVelocity() const; + /** + * @brief Set the linear velocity (local Body). + * @param[in] _linearVelocity The linear velocity vector of the body + */ + void setRelativeLinearVelocity(const vec3& _linearVelocity); + /** + * @brief Get the angular velocity (whole world). * @return The angular velocity vector of the body */ vec3 getAngularVelocity() const; /** - * @brief Set the angular velocity. + * @brief Set the angular velocity (whole world). * @param[in] _linearVelocity The angular velocity vector of the body */ void setAngularVelocity(const vec3& _angularVelocity); + /** + * @brief Get the angular velocity (local Body). + * @return The angular velocity vector of the body + */ + vec3 getRelativeAngularVelocity() const; + /** + * @brief Set the angular velocity (local Body). + * @param[in] _linearVelocity The angular velocity vector of the body + */ + void setRelativeAngularVelocity(const vec3& _angularVelocity); + /** + * @brief Apply an external force to the body at a given point (in world-space coordinates). + * If the point is not at the center of mass of the body, it will also generate some torque and therefore, change the angular velocity of the body. + * If the body is sleeping, calling this method will wake it up. Note that the force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing. + * @param[in] _force The force to apply on the body + * @param[in] _point The point where the force is applied (in world-space coordinates) + */ + void applyForce(const vec3& _force,const vec3& _point); + protected: + rp3d::Vector3 m_staticForceApplyCenterOfMass; + public: + /** + * @brief Apply an external force to the body at its center of mass. + * If the body is sleeping, calling this method will wake it up. + * @note The force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing. + * @param[in] _force The external force to apply on the center of mass of the body + * @param[in] _static The torque will be apply while the user des not call the same function with 0 value ... + */ + void applyForceToCenterOfMass(const vec3& _force, bool _static=false); + /** + * @brief Apply an external force to the body at its center of mass. + * If the body is sleeping, calling this method will wake it up. + * @note The force is apply with a relative axis of the object + * @note The force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing. + * @param[in] _force The external force to apply on the center of mass of the body + * @param[in] _static The torque will be apply while the user des not call the same function with 0 value ... + */ + void applyRelativeForceToCenterOfMass(const vec3& _force, bool _static=false); + protected: + rp3d::Vector3 m_staticTorqueApply; + public: + /** + * @brief Apply an external torque to the body. + * If the body is sleeping, calling this method will wake it up. + * @note The force will we added to the sum of the applied torques and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing. + * @param[in] _torque The external torque to apply on the body + * @param[in] _static The torque will be apply while the user des not call the same function with 0 value ... + */ + void applyTorque(const vec3& _torque, bool _static=false); + /** + * @brief Apply an external torque to the body. + * If the body is sleeping, calling this method will wake it up. + * @note The torque is apply with a relative axis of the object + * @note The force will we added to the sum of the applied torques and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing. + * @param[in] _torque The external torque to apply on the body + * @param[in] _static The torque will be apply while the user des not call the same function with 0 value ... + */ + void applyRelativeTorque(const vec3& _torque, bool _static=false); + protected: std::vector> m_shape; //!< collision shape module ... (independent of bullet lib) public: @@ -90,7 +159,10 @@ namespace ege { void drawShape(ememory::SharedPtr _draw, ememory::SharedPtr _camera); void drawAABB(ememory::SharedPtr _draw, ememory::SharedPtr _camera); private: + // call done after all cycle update of the physical engine void emitAll(); + // call of this function every time the call will be done + void update(float _delta); friend class ege::physics::Engine; private: /** diff --git a/ege/physics/Engine.cpp b/ege/physics/Engine.cpp index da2c765..0213154 100644 --- a/ege/physics/Engine.cpp +++ b/ege/physics/Engine.cpp @@ -136,6 +136,15 @@ void ege::physics::Engine::update(const echrono::Duration& _delta) { // While there is enough accumulated time to take one or several physics steps while (m_accumulator >= timeStep) { if (m_dynamicsWorld != nullptr) { + // call every object to usdate their constant forces applyed + for (auto &it: m_component) { + // check nullptr pointer + if (it == nullptr) { + // no pointer null are set in the output list ... + continue; + } + it->update(timeStep); + } // Update the Dynamics world with a constant time step EGE_DEBUG("Update the Physic engine ... " << timeStep); m_dynamicsWorld->update(timeStep); diff --git a/ege/resource/MeshGird.cpp b/ege/resource/MeshGird.cpp index 97893ee..9776af2 100644 --- a/ege/resource/MeshGird.cpp +++ b/ege/resource/MeshGird.cpp @@ -49,9 +49,9 @@ ememory::SharedPtr ege::resource::Mesh::createGrid(int32_t out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(0,_lineCount+0.5f,0.5f)*_size, etk::color::green); out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(0,_lineCount+0.5f,-0.5f)*_size, etk::color::green); // Y letter - out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(0.7f,_lineCount+2.0f,1.0f)*_size, etk::color::blue); - out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(-0.7f,_lineCount+2.0f,1.0f)*_size, etk::color::blue); - out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(0,_lineCount+2.0f,-1.0f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(0.7f,_lineCount+2.0f,1.0f)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(-0.7f,_lineCount+2.0f,1.0f)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+2.0f,0)*_size, _position+vec3(0,_lineCount+2.0f,-1.0f)*_size, etk::color::green); } else { out->addLine(_materialName, _position+vec3(iii,-_lineCount,0)*_size, _position+vec3(iii,_lineCount,0)*_size, etk::color::gray); } @@ -68,9 +68,9 @@ ememory::SharedPtr ege::resource::Mesh::createGrid(int32_t out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(0,0.5f,_lineCount+0.5f)*_size, etk::color::blue); out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(0,-0.5f,_lineCount+0.5f)*_size, etk::color::blue); // Z letter - out->addLine(_materialName, _position+vec3( 1,-1,_lineCount+2.0f)*_size, _position+vec3( 1, 1,_lineCount+2.0f)*_size, etk::color::green); - out->addLine(_materialName, _position+vec3( 1, 1,_lineCount+2.0f)*_size, _position+vec3(-1,-1,_lineCount+2.0f)*_size, etk::color::green); - out->addLine(_materialName, _position+vec3(-1,-1,_lineCount+2.0f)*_size, _position+vec3(-1, 1,_lineCount+2.0f)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3( 1,-1,_lineCount+2.0f)*_size, _position+vec3( 1, 1,_lineCount+2.0f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3( 1, 1,_lineCount+2.0f)*_size, _position+vec3(-1,-1,_lineCount+2.0f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(-1,-1,_lineCount+2.0f)*_size, _position+vec3(-1, 1,_lineCount+2.0f)*_size, etk::color::blue); } else { std::vector list;