Compare commits
61 Commits
73558e63ec
...
d13c401e1e
Author | SHA1 | Date | |
---|---|---|---|
d13c401e1e | |||
fdcd62b4a1 | |||
a47f635cb2 | |||
b2f79b3011 | |||
1748e90606 | |||
486998fb35 | |||
02c8b0ec81 | |||
436ae2c58d | |||
1fe5bececb | |||
e515e411fd | |||
fc598bd164 | |||
4a80003857 | |||
b41fbb70ac | |||
4a87d37e78 | |||
50fd99522c | |||
f30ec409bb | |||
7154278417 | |||
4016367de0 | |||
6c7f6a4414 | |||
fbc979aab5 | |||
54529a3efd | |||
ff4e7ac001 | |||
e8d16c380e | |||
51d3dd80bf | |||
18daa6836d | |||
307e8bc944 | |||
a87d61c996 | |||
c6d911ce70 | |||
1df51c29bd | |||
811f2fc2b1 | |||
afdcd183dc | |||
28014b421a | |||
8cbe9d1a80 | |||
7d51944355 | |||
71a5e41f5a | |||
e7351e8a0f | |||
30e73c9723 | |||
3c6c79b8bd | |||
d154b0c901 | |||
3f22081ced | |||
c25f125dee | |||
80793fb4da | |||
d72cefd665 | |||
4ed894376d | |||
36d869e636 | |||
2b9be54e37 | |||
fe17517d7c | |||
4a64ced041 | |||
c770439228 | |||
39ecb28335 | |||
d67a328fa4 | |||
b1c211a585 | |||
3ad1725f54 | |||
1c4e81bdba | |||
6fa74968b6 | |||
7cb5880af2 | |||
0a474afb7e | |||
a0132c0090 | |||
183a0020d7 | |||
21c6ab2f80 | |||
2305cdbbcc |
373
LICENSE
Normal file
373
LICENSE
Normal file
@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
11
README.md
11
README.md
@ -22,16 +22,21 @@ create user addon directory: (replace 2.xx with the blender version)
|
||||
- Select "Addons" tab
|
||||
- Enable "Import-export: Ewol Mesh file format emf"
|
||||
|
||||
Some error classile with awesome and blender
|
||||
============================================
|
||||
|
||||
License (APACHE v2.0)
|
||||
- file -> user preferences -> system -> Windows draw methode: triple bufferings
|
||||
|
||||
|
||||
License (MPL v2.0)
|
||||
=====================
|
||||
Copyright ege Edouard DUPIN
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
Licensed under the Mozilla Public License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
https://www.mozilla.org/MPL/2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -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")
|
||||
|
||||
@ -122,7 +89,7 @@ class ExportEMF(bpy.types.Operator, ExportHelper):
|
||||
# generate binary file
|
||||
use_binary = BoolProperty(
|
||||
name="Binary",
|
||||
description="Export the filein binary mode",
|
||||
description="Export the file in binary mode",
|
||||
default=False,
|
||||
)
|
||||
|
||||
@ -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='-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
|
||||
@ -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)
|
||||
|
||||
|
||||
|
@ -6,6 +6,10 @@ import bpy
|
||||
import mathutils
|
||||
import bpy_extras.io_utils
|
||||
|
||||
EXPORT_COLLISION_NAME = ""
|
||||
|
||||
#blender myscene.blend --background --python myscript.py
|
||||
|
||||
def getChildren(obj):
|
||||
children = []
|
||||
for ob in bpy.data.objects:
|
||||
@ -47,38 +51,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.w, q.x, q.z, -q.y )
|
||||
# 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 ):
|
||||
return "%g %g %g %g" % ( q.w, q.x, q.y, q.z )
|
||||
def out_quaternion( q ):
|
||||
return "%g %g %g %g" % ( q.x, q.y, q.z, q.w )
|
||||
|
||||
|
||||
def getPhysicsShape(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'):
|
||||
@ -91,17 +77,18 @@ def getPhysicsShape(obj, mainObjScale, use_y_up=False):
|
||||
# CONE
|
||||
elif name.startswith('cone'):
|
||||
shape = "Cone"
|
||||
props["radius"] = obj.scale.x
|
||||
props["height"] = obj.scale.z * 2.0
|
||||
props["radius"] = (obj.scale.x + obj.scale.y)*0.5
|
||||
props["size"] = obj.scale.z * 2.0
|
||||
# CYLINDER
|
||||
elif name.startswith('cyl'):
|
||||
shape = "Cylinder"
|
||||
props["half-extents"] = out_scale3( scale )
|
||||
props["radius"] = (obj.scale.x + obj.scale.y)*0.5
|
||||
props["size"] = obj.scale.z * 2.0
|
||||
# CAPSULE
|
||||
elif name.startswith('cap'):
|
||||
shape = "Capsule"
|
||||
props["radius"] = obj.scale.x
|
||||
props["height"] = obj.scale.z
|
||||
props["radius"] = (obj.scale.x + obj.scale.y)*0.5
|
||||
props["size"] = obj.scale.z * 2.0
|
||||
# CONVEX-HULL
|
||||
elif name.startswith('convex'):
|
||||
shape = "ConvexHull"
|
||||
@ -114,39 +101,41 @@ def getPhysicsShape(obj, mainObjScale, use_y_up=False):
|
||||
props["scale"] = out_scale3( scale )
|
||||
# remove mesh
|
||||
|
||||
print(" shape type : '%s' from element name : '%s'" % (shape, obj.name))
|
||||
print(" shape type: '" + str(shape) + "' from element name:'" + str(obj.name) + "'")
|
||||
|
||||
if obj.location != Vector((0,0,0)):
|
||||
props["origin"] = out_point3( obj.location )
|
||||
|
||||
if obj.rotation_mode == 'QUATERNION':
|
||||
qrot = obj.rotation_quaternion
|
||||
else:
|
||||
qrot = obj.matrix_local.to_quaternion()
|
||||
if obj.matrix_world.to_translation() != Vector((0,0,0)):
|
||||
props["origin"] = out_point3(obj.matrix_world.to_translation())
|
||||
|
||||
qrot = obj.matrix_world.to_quaternion()
|
||||
if qrot != Quaternion((1,0,0,0)):
|
||||
props["rotate"] = out_quaternion( qrot )
|
||||
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)
|
||||
|
||||
|
||||
def writeCollisionShape(object, file, mainObjScale):
|
||||
def write_collision_shape(object, file, mainObjScale, offset):
|
||||
if len(getChildren(object))==0:
|
||||
# no phisical shape ...
|
||||
return
|
||||
fw = file.write
|
||||
fw('\t\tPhysics : \n')
|
||||
string_offset = ""
|
||||
for iii in range(offset):
|
||||
string_offset += "\t"
|
||||
file.write(string_offset + 'Physics:\n')
|
||||
for subObj in getChildren(object):
|
||||
print(" element='%s' type '%s'" % (subObj.name,str(subObj.type)))
|
||||
if subObj.type != 'MESH':
|
||||
print(" element='" + subObj.name + "' type '" + str(subObj.type) + "'")
|
||||
if subObj.type != 'MESH' \
|
||||
and subObj.type != 'EMPTY':
|
||||
continue
|
||||
(shape, props) = getPhysicsShape(subObj, mainObjScale)
|
||||
(shape, props) = get_physics_shape(subObj, mainObjScale)
|
||||
if shape=="":
|
||||
print("error of shape detection type ...");
|
||||
continue
|
||||
fw("\t\t\t" + shape + "\n" )
|
||||
file.write(string_offset + "\t" + shape + "\n" )
|
||||
for (k,v) in props.items():
|
||||
fw("\t\t\t\t%s : %s\n" % (k, v) )
|
||||
file.write(string_offset + "\t\t%s:%s\n" % (k, v) )
|
||||
|
||||
|
||||
|
||||
@ -175,47 +164,47 @@ def write_mtl(scene, file, filepath, path_mode, copy_set, mtl_dict):
|
||||
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))
|
||||
file.write('\n')
|
||||
#file.write('\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
|
||||
# Having an image named None will make a bug, dont do it:)
|
||||
file.write('Materials:%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)
|
||||
file.write('\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
|
||||
file.write('\tKa %.6f %.6f %.6f\n' % (mat.ambient * world_amb)[:]) # Ambient, uses mirror color,
|
||||
file.write('\tKd %.6f %.6f %.6f\n' % (mat.diffuse_intensity * mat.diffuse_color)[:]) # Diffuse
|
||||
file.write('\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
|
||||
file.write('\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)
|
||||
file.write('\tNi %.6f\n' % 1.0)
|
||||
file.write('\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
|
||||
file.write('\tillum 0\n') # ignore lighting
|
||||
elif mat.specular_intensity == 0:
|
||||
fw('\t\tillum 1\n') # no specular.
|
||||
file.write('\tillum 1\n') # no specular.
|
||||
else:
|
||||
fw('\t\tillum 2\n') # light normaly
|
||||
file.write('\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
|
||||
file.write('\tNs 0\n')
|
||||
file.write('\tKa %.6f %.6f %.6f\n' % world_amb[:]) # Ambient, uses mirror color,
|
||||
file.write('\tKd 0.8 0.8 0.8\n')
|
||||
file.write('\tKs 0.8 0.8 0.8\n')
|
||||
file.write('\td 1\n') # No alpha
|
||||
file.write('\tillum 2\n') # light normaly
|
||||
# Write images!
|
||||
if face_img: # We have an image on the face!
|
||||
filepath = face_img.filepath
|
||||
@ -228,7 +217,7 @@ def write_mtl(scene, file, filepath, path_mode, copy_set, mtl_dict):
|
||||
"",
|
||||
copy_set,
|
||||
face_img.library)
|
||||
fw('\t\tmap_Kd %s\n' % filepath) # Diffuse mapping image
|
||||
file.write('\tmap_Kd %s\n' % filepath) # Diffuse mapping image
|
||||
del filepath
|
||||
else:
|
||||
# so we write the materials image.
|
||||
@ -274,7 +263,276 @@ def write_mtl(scene, file, filepath, path_mode, copy_set, mtl_dict):
|
||||
"",
|
||||
copy_set,
|
||||
image.library)
|
||||
fw('\t\t%s %s\n' % (key, repr(filepath)[1:-1]))
|
||||
file.write('\t%s %s\n' % (key, repr(filepath)[1:-1]))
|
||||
|
||||
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)
|
||||
|
||||
def write_mesh(scene, file, object, mtl_dict):
|
||||
print("**************** '" + str(object.name) + "' *******************")
|
||||
|
||||
# Initialize totals, these are updated each object
|
||||
totverts = 1
|
||||
totuvco = 1
|
||||
totno = 1
|
||||
globalNormals = {}
|
||||
face_vert_index = 1
|
||||
# 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 = {}
|
||||
|
||||
|
||||
if object.type != 'MESH':
|
||||
print(object.name + 'is not a mesh type - ignoring type=' + object.type)
|
||||
file.write('# can not export:"%s":type="%s"\n' % (object.name, str(object.type)))
|
||||
return
|
||||
#print("name:'%s'" % object.name)
|
||||
#for plop in object.child:
|
||||
# print(" child:'%s'" % plop.name)
|
||||
# ignore dupli children
|
||||
if object.parent and object.parent.dupli_type in {'VERTS', 'FACES'}:
|
||||
# XXX
|
||||
print(object.name, 'is a dupli child - ignoring')
|
||||
return
|
||||
obs = []
|
||||
if object.dupli_type != 'NONE':
|
||||
# XXX
|
||||
print('creating dupli_list on', object.name)
|
||||
object.dupli_list_create(scene)
|
||||
obs = [(dob.object, dob.matrix) for dob in object.dupli_list]
|
||||
# XXX debug print
|
||||
print(object.name, 'has', len(obs), 'dupli children')
|
||||
else:
|
||||
obs = [(object, object.matrix_world)]
|
||||
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
|
||||
me.transform(ob_mat)
|
||||
#print("ploppp:" + str(ob_mat) )
|
||||
# _must_ do this first since it re-allocs arrays
|
||||
# triangulate all the mesh:
|
||||
mesh_triangulate(me)
|
||||
# calculated normals:
|
||||
me.calc_normals()
|
||||
# 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.
|
||||
|
||||
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 ....
|
||||
name1 = ob.name
|
||||
name2 = ob.data.name
|
||||
if name1 == name2:
|
||||
obnamestring = name_compat(name1)
|
||||
else:
|
||||
obnamestring = '%s_%s' % (name_compat(name1), name_compat(name2))
|
||||
file.write('Mesh:%s\n' % obnamestring) # Write Object name
|
||||
###########################################################
|
||||
## Vert
|
||||
###########################################################
|
||||
file.write('\tVertex:%d\n\t\t' % len(me_verts))
|
||||
for v in me_verts:
|
||||
file.write('%.6f %.6f %.6f|' % v.co[:])
|
||||
file.write('\n')
|
||||
###########################################################
|
||||
## UV
|
||||
###########################################################
|
||||
if faceuv:
|
||||
file.write('\tUV-mapping:\n\t\t')
|
||||
# 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)
|
||||
file.write('%.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
|
||||
file.write('\n')
|
||||
else:
|
||||
print("does not use UV-MAPPING")
|
||||
###########################################################
|
||||
## NORMAL
|
||||
###########################################################
|
||||
if len(face_index_pairs) > 0:
|
||||
if face_index_pairs[0][0].use_smooth:
|
||||
localIsSmooth = 'vertex'
|
||||
else:
|
||||
localIsSmooth = 'face'
|
||||
else:
|
||||
localIsSmooth = 'face'
|
||||
file.write('\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
|
||||
file.write('%.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
|
||||
file.write('%.6f %.6f %.6f|' % noKey)
|
||||
|
||||
file.write('\n')
|
||||
if not faceuv:
|
||||
f_image = None
|
||||
###########################################################
|
||||
## faces
|
||||
###########################################################
|
||||
file.write('\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:
|
||||
file.write("\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:
|
||||
file.write("\n\t\t%s\n\t\t\t" % 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:
|
||||
file.write(" %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:
|
||||
file.write(" %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:
|
||||
file.write(" %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:
|
||||
file.write(" %d/%d" % (v.index + totverts-1, no-1))
|
||||
file.write('|')
|
||||
file.write('\n')
|
||||
# Write edges. ==> did not know what it is ...
|
||||
#file.write('Faces:%d' % len(edges))
|
||||
#for ed in edges:
|
||||
# if ed.is_loose:
|
||||
# file.write('%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 object.dupli_type != 'NONE':
|
||||
object.dupli_list_clear()
|
||||
#####################################################################
|
||||
## Save collision shapes (for one object):
|
||||
#####################################################################
|
||||
for subObj in getChildren(object):
|
||||
print(" child:'%s' check if start with : '%s'" % (subObj.name, EXPORT_COLLISION_NAME))
|
||||
if subObj.name.lower().startswith(EXPORT_COLLISION_NAME):
|
||||
print(" find physics:'%s'" % (subObj.name))
|
||||
write_collision_shape(subObj, file, object.scale, 1)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
@ -283,20 +541,10 @@ def write_mtl(scene, file, filepath, path_mode, copy_set, 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()
|
||||
|
||||
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()
|
||||
@ -304,278 +552,58 @@ def write_file(filepath,
|
||||
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 = {}
|
||||
file.write('EMF(STRING)\n') # if binary:file.write('EMF(BINARY)\n')
|
||||
file.write('# Blender v%s EMF File: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
||||
|
||||
# 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()
|
||||
"""
|
||||
nb_total_mesh = 0
|
||||
nb_total_physic = 0
|
||||
for ob_main in objects:
|
||||
print("**************** '" + str(ob_main.name) + "' *******************")
|
||||
if 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':
|
||||
nb_total_mesh += 1
|
||||
elif sub_obj.type == 'EMPTY' \
|
||||
and sub_obj.name.lower().startswith("physic"):
|
||||
nb_total_physic += 1
|
||||
for sub_obj_2 in getChildren(sub_obj):
|
||||
print(" child:'" + str(sub_obj_2.name) + "' type=" + sub_obj_2.type)
|
||||
for sub_obj_3 in getChildren(sub_obj_2):
|
||||
print(" child:'" + str(sub_obj_3.name) + "' type=" + sub_obj_3.type)
|
||||
if ob_main.type == 'MESH':
|
||||
nb_total_mesh += 1
|
||||
print("nb_total_mesh: " + str(nb_total_mesh))
|
||||
print("nb_total_physic: " + str(nb_total_physic))
|
||||
"""
|
||||
|
||||
# Get all meshes
|
||||
for ob_main in objects:
|
||||
print("**************** '%s' *******************" % str(ob_main.name))
|
||||
if ob_main.type != 'MESH':
|
||||
print(ob_main.name, 'is not a mesh type - ignoring')
|
||||
fw('# can not export : "%s" : type="%s"\n' % (ob_main.name, str(ob_main.type)))
|
||||
continue
|
||||
#print("name : '%s'" % ob_main.name)
|
||||
#for plop in ob_main.child:
|
||||
# print(" child : '%s'" % plop.name)
|
||||
# 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)
|
||||
#print("ploppp : " + str(EXPORT_GLOBAL_MATRIX) )
|
||||
#print("ploppp : " + str(ob_mat) )
|
||||
# _must_ do this first since it re-allocs arrays
|
||||
# triangulate all the mesh :
|
||||
mesh_triangulate(me)
|
||||
# calculated normals:
|
||||
me.calc_normals()
|
||||
# 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.
|
||||
|
||||
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)
|
||||
if ob_main.type == 'MESH':
|
||||
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, mtl_dict)
|
||||
elif sub_obj.type == 'EMPTY' \
|
||||
and sub_obj.name.lower().startswith("physic"):
|
||||
print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type)
|
||||
#####################################################################
|
||||
## Save collision shapes (for one all):
|
||||
#####################################################################
|
||||
write_collision_shape(sub_obj, file, sub_obj.scale, 0)
|
||||
else:
|
||||
obnamestring = '%s_%s' % (name_compat(name1), name_compat(name2))
|
||||
fw('\t%s\n' % obnamestring) # Write Object name
|
||||
###########################################################
|
||||
## Vert
|
||||
###########################################################
|
||||
fw('\t\tVertex : %d\n\t\t\t' % len(me_verts))
|
||||
for v in me_verts:
|
||||
fw('%.6f %.6f %.6f|' % v.co[:])
|
||||
fw('\n')
|
||||
###########################################################
|
||||
## UV
|
||||
###########################################################
|
||||
fw('\t\tUV-mapping :\n\t\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('\t\tNormal(%s) : %d\n\t\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('\t\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\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\t%s\n\t\t\t\t" % 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()
|
||||
#####################################################################
|
||||
## Save collision shapes (for one object :
|
||||
#####################################################################
|
||||
for subObj in getChildren(ob_main):
|
||||
print(" child : '%s'" % (subObj.name))
|
||||
if subObj.name.lower().startswith(EXPORT_COLLISION_NAME):
|
||||
print(" find physics : '%s'" % (subObj.name))
|
||||
writeCollisionShape(subObj, file, ob_main.scale)
|
||||
|
||||
print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type + " not parsed ...")
|
||||
|
||||
#####################################################################
|
||||
## Now we have all our materials, save them in the material section
|
||||
#####################################################################
|
||||
@ -599,25 +627,24 @@ def write_file(filepath,
|
||||
def _write(context,
|
||||
filepath,
|
||||
EXPORT_SEL_ONLY,
|
||||
EXPORT_GLOBAL_MATRIX,
|
||||
EXPORT_PATH_MODE,
|
||||
EXPORT_BINARY_MODE,
|
||||
EXPORT_COLLISION_NAME,
|
||||
):
|
||||
#
|
||||
base_name, ext = os.path.splitext(filepath)
|
||||
# create the output name :
|
||||
# create the output name:
|
||||
context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
|
||||
# get the curent scene :
|
||||
# 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 :
|
||||
# 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 ...
|
||||
# get only the object that are selected or all...
|
||||
if EXPORT_SEL_ONLY:
|
||||
objects = context.selected_objects
|
||||
else:
|
||||
@ -628,7 +655,6 @@ def _write(context,
|
||||
write_file(full_path,
|
||||
objects,
|
||||
scene,
|
||||
EXPORT_GLOBAL_MATRIX,
|
||||
EXPORT_PATH_MODE,
|
||||
EXPORT_BINARY_MODE,
|
||||
EXPORT_COLLISION_NAME,
|
||||
@ -646,13 +672,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,
|
||||
|
73
data/material3D.frag
Normal file
73
data/material3D.frag
Normal file
@ -0,0 +1,73 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
struct DirectionalLight {
|
||||
vec3 direction;
|
||||
vec3 halfplane;
|
||||
vec4 ambientColor;
|
||||
vec4 diffuseColor;
|
||||
vec4 specularColor;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 ambientFactor; // color of the material with a reflection factor (0.2 for example) ==> light the back of the object
|
||||
vec4 diffuseFactor; // Direct exposition of the object by the light (object color)
|
||||
vec4 specularFactor; // Shining the Object with the light
|
||||
float shininess;
|
||||
};
|
||||
|
||||
// Light
|
||||
uniform DirectionalLight EW_directionalLight;
|
||||
// Material
|
||||
uniform Material EW_material;
|
||||
|
||||
varying vec3 v_ecNormal;
|
||||
|
||||
#if 1
|
||||
// real basic version
|
||||
void main(void) {
|
||||
// Normalize v_ecNormal
|
||||
vec3 ecNormal = normalize(v_ecNormal);
|
||||
|
||||
float ecNormalDotLightDirection = (dot(ecNormal, EW_directionalLight.direction)+1.0) * 0.5;
|
||||
|
||||
// Calculate diffuse light
|
||||
vec4 diffuseLight = ecNormalDotLightDirection * EW_directionalLight.diffuseColor * EW_material.diffuseFactor;
|
||||
|
||||
vec4 light = diffuseLight;
|
||||
gl_FragColor = light;
|
||||
}
|
||||
#else
|
||||
// must work but it is full white
|
||||
void main(void) {
|
||||
// Normalize v_ecNormal
|
||||
vec3 ecNormal = normalize(v_ecNormal);
|
||||
|
||||
// Calculate ambient light
|
||||
vec4 ambientLight = EW_directionalLight.ambientColor * EW_material.ambientFactor;
|
||||
|
||||
float ecNormalDotLightDirection = max(0.0, dot(ecNormal, EW_directionalLight.direction));
|
||||
//float ecNormalDotLightDirection = (dot(ecNormal, EW_directionalLight.direction)+1.0) * 0.5;
|
||||
|
||||
// Calculate diffuse light
|
||||
vec4 diffuseLight = ecNormalDotLightDirection * EW_directionalLight.diffuseColor * EW_material.diffuseFactor;
|
||||
//vec4 diffuseLight = EW_material.diffuseFactor;
|
||||
//vec4 diffuseLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
// Calculate specular light
|
||||
vec4 specularLight = EW_directionalLight.specularColor * EW_material.specularFactor;
|
||||
|
||||
float ecNormalDotLightHalfplane = dot(ecNormal, EW_directionalLight.halfplane);
|
||||
if (ecNormalDotLightHalfplane > 0.0) {
|
||||
specularLight = pow(ecNormalDotLightHalfplane, EW_material.shininess) * EW_directionalLight.specularColor * EW_material.specularFactor;
|
||||
specularLight = EW_directionalLight.specularColor * EW_material.specularFactor;
|
||||
}
|
||||
|
||||
// here, we have a white color
|
||||
vec4 light = ambientLight + diffuseLight + specularLight;
|
||||
// here we have color
|
||||
//vec4 light = diffuseLight;
|
||||
gl_FragColor = light;
|
||||
}
|
||||
#endif
|
23
data/material3D.vert
Normal file
23
data/material3D.vert
Normal file
@ -0,0 +1,23 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
// Input:
|
||||
attribute vec3 EW_coord3d;
|
||||
attribute vec3 EW_normal;
|
||||
uniform mat4 EW_MatrixTransformation;
|
||||
uniform mat4 EW_MatrixPosition;
|
||||
|
||||
// output:
|
||||
varying vec3 v_ecNormal;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = EW_MatrixTransformation * EW_MatrixPosition * vec4(EW_coord3d, 1.0);
|
||||
mat4 MatrixPosition = EW_MatrixPosition;
|
||||
/*
|
||||
MatrixPosition[3][0] = 0.0;
|
||||
MatrixPosition[3][1] = 0.0;
|
||||
MatrixPosition[3][2] = 0.0;
|
||||
*/
|
||||
v_ecNormal = vec3(MatrixPosition * vec4(EW_normal, 1.0) );
|
||||
}
|
55
data/material3DTextured.frag
Normal file
55
data/material3DTextured.frag
Normal file
@ -0,0 +1,55 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
struct DirectionalLight {
|
||||
vec3 direction;
|
||||
vec3 halfplane;
|
||||
vec4 ambientColor;
|
||||
vec4 diffuseColor;
|
||||
vec4 specularColor;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 ambientFactor;
|
||||
vec4 diffuseFactor;
|
||||
vec4 specularFactor;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
// Light
|
||||
uniform DirectionalLight EW_directionalLight;
|
||||
// Material
|
||||
uniform Material EW_material;
|
||||
|
||||
// Input :
|
||||
uniform sampler2D EW_texID;
|
||||
|
||||
varying vec2 f_texcoord;
|
||||
varying vec3 v_ecNormal;
|
||||
|
||||
void main(void) {
|
||||
vec4 tmpElementColor = texture2D(EW_texID, f_texcoord);
|
||||
|
||||
// Normalize v_ecNormal
|
||||
vec3 ecNormal = v_ecNormal / length(v_ecNormal);
|
||||
|
||||
float ecNormalDotLightDirection = max(0.0, dot(ecNormal, EW_directionalLight.direction));
|
||||
float ecNormalDotLightHalfplane = max(0.0, dot(ecNormal, EW_directionalLight.halfplane));
|
||||
|
||||
// Calculate ambient light
|
||||
vec4 ambientLight = EW_directionalLight.ambientColor * EW_material.ambientFactor;
|
||||
|
||||
// Calculate diffuse light
|
||||
vec4 diffuseLight = ecNormalDotLightDirection * EW_directionalLight.diffuseColor * EW_material.diffuseFactor;
|
||||
|
||||
// Calculate specular light
|
||||
vec4 specularLight = vec4(0.0);
|
||||
|
||||
if (ecNormalDotLightHalfplane > 0.0) {
|
||||
specularLight = pow(ecNormalDotLightHalfplane, EW_material.shininess) * EW_directionalLight.specularColor * EW_material.specularFactor;
|
||||
specularLight = EW_directionalLight.specularColor * EW_material.specularFactor;
|
||||
}
|
||||
vec4 light = ambientLight + diffuseLight + specularLight;
|
||||
gl_FragColor = tmpElementColor;// * light;
|
||||
}
|
25
data/material3DTextured.vert
Normal file
25
data/material3DTextured.vert
Normal file
@ -0,0 +1,25 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
// Input :
|
||||
attribute vec3 EW_coord3d;
|
||||
attribute vec2 EW_texture2d;
|
||||
attribute vec3 EW_normal;
|
||||
uniform mat4 EW_MatrixTransformation;
|
||||
uniform mat4 EW_MatrixPosition;
|
||||
|
||||
// output :
|
||||
varying vec2 f_texcoord;
|
||||
varying vec3 v_ecNormal;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = EW_MatrixTransformation * EW_MatrixPosition * vec4(EW_coord3d, 1.0);
|
||||
// set texture output coord
|
||||
f_texcoord = EW_texture2d;
|
||||
mat4 MatrixPosition = EW_MatrixPosition;
|
||||
MatrixPosition[3][0] = 0.0;
|
||||
MatrixPosition[3][1] = 0.0;
|
||||
MatrixPosition[3][2] = 0.0;
|
||||
v_ecNormal = vec3(MatrixPosition * vec4(EW_normal, 1.0) );
|
||||
}
|
@ -32,16 +32,16 @@ Are there any licensing restrictions? {#ege_mainpage_license_restrict
|
||||
EGE is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
|
||||
|
||||
|
||||
License (APACHE-2.0) {#ege_mainpage_license}
|
||||
====================
|
||||
License (MPL v2.0) {#ege_mainpage_license}
|
||||
==================
|
||||
|
||||
Copyright EGE Edouard DUPIN
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
Licensed under the Mozilla Public License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
<http://www.apache.org/licenses/LICENSE-2.0>
|
||||
<https://www.mozilla.org/MPL/2.0>
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -7,7 +7,7 @@ import doxy.tools as tools
|
||||
def create(target, module_name):
|
||||
my_module = module.Module(__file__, module_name)
|
||||
my_module.set_version("version.txt")
|
||||
my_module.set_title("Ewol Game engine (based on bullet lib)")
|
||||
my_module.set_title("Ewol Game engine")
|
||||
my_module.set_website("http://atria-soft.github.io/" + module_name)
|
||||
my_module.set_website_sources("http://github.com/atria-soft/" + module_name)
|
||||
my_module.add_path([
|
||||
|
@ -1,9 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/AudioElement.hpp>
|
||||
|
@ -1,13 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/AudioEngine.hpp>
|
||||
|
@ -1,12 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,181 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/CollisionShapeCreator.hpp>
|
||||
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
#include <ege/physicsShape/PhysicsBox.hpp>
|
||||
#include <ege/physicsShape/PhysicsCapsule.hpp>
|
||||
#include <ege/physicsShape/PhysicsCone.hpp>
|
||||
#include <ege/physicsShape/PhysicsConvexHull.hpp>
|
||||
#include <ege/physicsShape/PhysicsCylinder.hpp>
|
||||
#include <ege/physicsShape/PhysicsSphere.hpp>
|
||||
|
||||
// Documentetion of bullet library :
|
||||
// http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Shapes
|
||||
|
||||
btCollisionShape* ege::collision::createShape(const ememory::SharedPtr<ege::resource::Mesh>& _mesh) {
|
||||
if (_mesh == nullptr) {
|
||||
EGE_DEBUG("Create empty shape (no mesh)");
|
||||
return new btEmptyShape();;
|
||||
}
|
||||
const std::vector<ememory::SharedPtr<ege::PhysicsShape>>& physiqueProperty = _mesh->getPhysicalProperties();
|
||||
if (physiqueProperty.size() == 0) {
|
||||
EGE_DEBUG("Create empty shape (no default shape)");
|
||||
return new btEmptyShape();;
|
||||
}
|
||||
int32_t count = 0;
|
||||
for (size_t iii=0; iii<physiqueProperty.size(); iii++) {
|
||||
if (physiqueProperty[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
btCompoundShape* outputShape = nullptr;
|
||||
if (count>1) {
|
||||
EGE_DEBUG("Create complexe shape");
|
||||
outputShape = new btCompoundShape();
|
||||
} else {
|
||||
EGE_DEBUG("Create simple shape");
|
||||
}
|
||||
for (size_t iii=0; iii<physiqueProperty.size(); iii++) {
|
||||
if (physiqueProperty[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
switch (physiqueProperty[iii]->getType()) {
|
||||
case ege::PhysicsShape::box : {
|
||||
EGE_DEBUG(" Box");
|
||||
const ege::PhysicsBox* tmpElement = physiqueProperty[iii]->toBox();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btBoxShape(tmpElement->getSize());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ege::PhysicsShape::cylinder : {
|
||||
EGE_DEBUG(" Cylinder");
|
||||
const ege::PhysicsCylinder* tmpElement = physiqueProperty[iii]->toCylinder();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btCylinderShape(tmpElement->getSize());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ege::PhysicsShape::capsule : {
|
||||
EGE_DEBUG(" Capsule");
|
||||
const ege::PhysicsCapsule* tmpElement = physiqueProperty[iii]->toCapsule();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btCapsuleShape(tmpElement->getRadius(), tmpElement->getHeight());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ege::PhysicsShape::cone : {
|
||||
EGE_DEBUG(" Cone");
|
||||
const ege::PhysicsCone* tmpElement = physiqueProperty[iii]->toCone();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btConeShape(tmpElement->getRadius(), tmpElement->getHeight());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ege::PhysicsShape::sphere : {
|
||||
EGE_DEBUG(" Sphere");
|
||||
const ege::PhysicsSphere* tmpElement = physiqueProperty[iii]->toSphere();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btSphereShape(tmpElement->getRadius());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ege::PhysicsShape::convexHull : {
|
||||
EGE_DEBUG(" convexHull");
|
||||
const ege::PhysicsConvexHull* tmpElement = physiqueProperty[iii]->toConvexHull();
|
||||
if (tmpElement == nullptr) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btConvexHullShape* tmpShape = new btConvexHullShape(&(tmpElement->getPointList()[0].x()), tmpElement->getPointList().size());
|
||||
if (tmpShape != nullptr) {
|
||||
if (outputShape == nullptr) {
|
||||
return tmpShape;
|
||||
} else {
|
||||
vec4 qqq = tmpElement->getQuaternion();
|
||||
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
|
||||
outputShape->addChildShape(localTransform, tmpShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
EGE_DEBUG(" ???");
|
||||
// TODO : UNKNOW type ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outputShape == nullptr) {
|
||||
EGE_DEBUG("create empty shape ...");
|
||||
return new btEmptyShape();
|
||||
}
|
||||
return outputShape;
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/resource/Mesh.hpp>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
|
||||
namespace ege {
|
||||
namespace collision {
|
||||
btCollisionShape* createShape(const ememory::SharedPtr<ege::resource::Mesh>& _mesh);
|
||||
}
|
||||
}
|
||||
|
12
ege/Component.cpp
Normal file
12
ege/Component.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/Component.hpp>
|
||||
|
||||
const etk::String& ege::Component::getType() const {
|
||||
static etk::String tmp("component");
|
||||
return tmp;
|
||||
}
|
||||
|
35
ege/Component.hpp
Normal file
35
ege/Component.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ememory/memory.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class Component : public ememory::EnableSharedFromThis<Component> {
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual const etk::String& getType() const;
|
||||
|
||||
/**
|
||||
* @brief Evironement notify that a new component is added on the same Element
|
||||
* @param[in] _component New component added
|
||||
*/
|
||||
virtual void addFriendComponent(const ememory::SharedPtr<ege::Component>& _component) {
|
||||
// nothing to do.
|
||||
}
|
||||
/**
|
||||
* @brief Evironement notify that a component is removed on the same Element
|
||||
* @param[in] _component Old component removed
|
||||
*/
|
||||
virtual void removeFriendComponent(const ememory::SharedPtr<ege::Component>& _component) {
|
||||
// nothing to do.
|
||||
}
|
||||
};
|
||||
}
|
37
ege/Engine.cpp
Normal file
37
ege/Engine.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/Engine.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
|
||||
ege::Engine::Engine(ege::Environement* _env) :
|
||||
m_env(_env) {
|
||||
|
||||
}
|
||||
|
||||
const etk::String& ege::Engine::getType() const {
|
||||
static etk::String tmp("engine");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ege::Engine::componentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
|
||||
}
|
||||
|
||||
void ege::Engine::componentAdd(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
|
||||
}
|
||||
|
||||
void ege::Engine::update(const echrono::Duration& _delta) {
|
||||
|
||||
}
|
||||
|
||||
void ege::Engine::render(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
|
||||
}
|
||||
|
||||
void ege::Engine::renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
|
||||
}
|
62
ege/Engine.hpp
Normal file
62
ege/Engine.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ememory/memory.hpp>
|
||||
|
||||
#include <ege/Component.hpp>
|
||||
#include <echrono/Duration.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <eproperty/Interface.hpp>
|
||||
|
||||
namespace ege {
|
||||
class Environement;
|
||||
class Camera;
|
||||
class Engine :
|
||||
public ememory::EnableSharedFromThis<Engine>,
|
||||
public eproperty::Interface {
|
||||
protected:
|
||||
ege::Environement* m_env;
|
||||
public:
|
||||
Engine(ege::Environement* _env);
|
||||
virtual ~Engine() = default;
|
||||
public:
|
||||
/**
|
||||
* @brief get the type of the engine
|
||||
* @return the type in string
|
||||
*/
|
||||
virtual const etk::String& getType() const;
|
||||
/**
|
||||
* @brief An ege::Entity component has been removed ==> need remove it in local if needed
|
||||
* @param[in] _ref Referrence on the component
|
||||
*/
|
||||
virtual void componentRemove(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
/**
|
||||
* @brief An ege::Entity component has been added ==> need add it in local if needed
|
||||
* @param[in] _ref Referrence on the component
|
||||
*/
|
||||
virtual void componentAdd(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
/**
|
||||
* @brief Global game engine main cycle of update internal parameters
|
||||
* @param[in] _delta time from the last update
|
||||
*/
|
||||
virtual void update(const echrono::Duration& _delta);
|
||||
/**
|
||||
* @brief Globalgame engine main cycle of draw
|
||||
* @param[in] _delta time from the last render
|
||||
* @param[in] _camera Camera property to render the engine properties ...
|
||||
*/
|
||||
virtual void render(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera);
|
||||
/**
|
||||
* @brief Globalgame engine main cycle of draw
|
||||
* @param[in] _delta time from the last render
|
||||
* @param[in] _camera Camera property to render the engine properties ...
|
||||
*/
|
||||
virtual void renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera);
|
||||
};
|
||||
}
|
||||
|
288
ege/Entity.cpp
Normal file
288
ege/Entity.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/Entity.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
|
||||
|
||||
const etk::String& ege::Entity::getType() const {
|
||||
static const etk::String nameType("----");
|
||||
return nameType;
|
||||
}
|
||||
|
||||
|
||||
ege::Entity::Entity(const ememory::SharedPtr<ege::Environement>& _env) :
|
||||
m_env(_env),
|
||||
m_uID(0),
|
||||
m_life(100),
|
||||
m_lifeMax(100),
|
||||
m_group(0),
|
||||
m_radius(0) {
|
||||
static uint32_t unique=0;
|
||||
m_uID = unique;
|
||||
EGE_DEBUG("Create Entity: uId=" << m_uID);
|
||||
//m_debugText.setFontSize(12);
|
||||
unique++;
|
||||
}
|
||||
|
||||
ege::Entity::~Entity() {
|
||||
EGE_DEBUG("Destroy Entity: uId=" << m_uID);
|
||||
}
|
||||
|
||||
void ege::Entity::addComponent(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
if (_ref == null) {
|
||||
EGE_ERROR("try to add an empty component");
|
||||
return;
|
||||
}
|
||||
EGE_PRINT("Entity: Add New component ... [START]");
|
||||
// Componenet to remove if it have the same type of the previous Component:
|
||||
ememory::SharedPtr<ege::Component> componentRemoved;
|
||||
int32_t findId = -1;
|
||||
// check if not exist
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_component[iii]->getType() == _ref->getType()) {
|
||||
componentRemoved = m_component[iii];
|
||||
m_component[iii] = _ref;
|
||||
findId = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// try to add in an empty slot
|
||||
if (findId == -1) {
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] != null) {
|
||||
continue;
|
||||
}
|
||||
findId = iii;
|
||||
m_component[iii] = _ref;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add it at the end ...
|
||||
if (findId == -1) {
|
||||
findId = m_component.size();
|
||||
m_component.pushBack(_ref);
|
||||
}
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (componentRemoved != null) {
|
||||
EGE_PRINT("Entity: ==> remove previous component");
|
||||
m_env->engineComponentRemove(componentRemoved);
|
||||
m_component[iii]->removeFriendComponent(componentRemoved);
|
||||
}
|
||||
EGE_PRINT("Entity: ==> add New component");
|
||||
m_env->engineComponentAdd(_ref);
|
||||
m_component[iii]->addFriendComponent(_ref);
|
||||
break;
|
||||
}
|
||||
// notify new component of all previously added component:
|
||||
componentRemoved = _ref;
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_component[iii] == _ref) {
|
||||
continue;
|
||||
}
|
||||
componentRemoved->addFriendComponent(m_component[iii]);
|
||||
}
|
||||
EGE_PRINT("Entity: Add New component ... [END]");
|
||||
}
|
||||
|
||||
void ege::Entity::rmComponent(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
if (_ref == null) {
|
||||
EGE_ERROR("try to remove an empty component");
|
||||
return;
|
||||
}
|
||||
int32_t findId = -1;
|
||||
// check if not exist
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_component[iii] == _ref) {
|
||||
m_component[iii] = null;
|
||||
findId = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (findId == -1) {
|
||||
EGE_ERROR("try to remove an unexisting component");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_env->engineComponentRemove(_ref);
|
||||
m_component[iii]->removeFriendComponent(_ref);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::Entity::rmComponent(const etk::String& _type) {
|
||||
int32_t findId = -1;
|
||||
ememory::SharedPtr<ege::Component> componentRemoved;
|
||||
// check if not exist
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_component[iii]->getType() == _type) {
|
||||
componentRemoved = m_component[iii];
|
||||
m_component[iii] = null;
|
||||
findId = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (findId == -1) {
|
||||
EGE_ERROR("try to remove an unexisting component type : '" << _type << "'");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_env->engineComponentRemove(componentRemoved);
|
||||
m_component[iii]->removeFriendComponent(componentRemoved);
|
||||
}
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Component> ege::Entity::getComponent(const etk::String& _type) {
|
||||
// check if not exist
|
||||
for (size_t iii=0; iii<m_component.size(); ++iii) {
|
||||
if (m_component[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_component[iii]->getType() == _type) {
|
||||
return m_component[iii];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ege::Entity::init() {
|
||||
EGE_WARNING("init() not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Entity::initString(const etk::String& _description) {
|
||||
EGE_WARNING("String Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Entity::initXML(const exml::Node& _node) {
|
||||
EGE_WARNING("xml Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Entity::initJSON(const ejson::Value& _value) {
|
||||
EGE_WARNING("JSON Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Entity::initVoid(void* _value) {
|
||||
EGE_WARNING("joid* Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Entity::unInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float ege::Entity::getLifeRatio() {
|
||||
if (0 >= m_life) {
|
||||
return 0;
|
||||
}
|
||||
return m_life/m_lifeMax;
|
||||
}
|
||||
|
||||
void ege::Entity::setFireOn(int32_t _groupIdSource, int32_t _type, float _power, const vec3& _center) {
|
||||
float previousLife = m_life;
|
||||
m_life += _power;
|
||||
m_life = etk::avg(0.0f, m_life, m_lifeMax);
|
||||
if (m_life <= 0) {
|
||||
EGE_DEBUG("[" << getUID() << "] Entity is killed ..." << getType());
|
||||
}
|
||||
if (m_life != previousLife) {
|
||||
onLifeChange();
|
||||
}
|
||||
}
|
||||
|
||||
const float lifeBorder = 0.1f;
|
||||
const float lifeHeight = 0.3f;
|
||||
const float lifeWidth = 2.0f;
|
||||
const float lifeYPos = 1.7f;
|
||||
|
||||
#if 0
|
||||
void ege::Entity::drawLife(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
if (_draw == null) {
|
||||
return;
|
||||
}
|
||||
float ratio = getLifeRatio();
|
||||
if (ratio == 1.0f) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
mat4 transformationMatrix = etk::matTranslate(getPosition())
|
||||
* etk::matRotate(vec3(0,0,1),_camera.getAngleZ())
|
||||
* etk::matRotate(vec3(1,0,0),(M_PI/2.0f-_camera.getAngleTeta()));
|
||||
etk::Vector<vec3> localVertices;
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.pushBack(vec3( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
|
||||
localVertices.pushBack(vec3( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.pushBack(vec3( lifeWidth/2.0+lifeBorder,lifeYPos -lifeBorder,0));
|
||||
etk::Color<float> myColor(0x0000FF99);
|
||||
_draw->draw(localVertices, myColor, transformationMatrix, false, false);
|
||||
localVertices.clear();
|
||||
/** Bounding box == > model shape **/
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0 ,lifeYPos,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0 ,lifeYPos + lifeHeight,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0 ,lifeYPos,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
|
||||
localVertices.pushBack(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos,0));
|
||||
myColor =0x00FF00FF;
|
||||
if (ratio < 0.2f) {
|
||||
myColor = 0xFF0000FF;
|
||||
} else if (ratio < 0.4f) {
|
||||
myColor = 0xDA7B00FF;
|
||||
}
|
||||
_draw->draw(localVertices, myColor, transformationMatrix, false, false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void ege::Entity::drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
/*
|
||||
m_debugText.clear();
|
||||
m_debugText.setColor(etk::Color<>(0x00, 0xFF, 0x00, 0xFF));
|
||||
m_debugText.setPos(vec3(-20,32,0));
|
||||
m_debugText.print(getType());
|
||||
m_debugText.setPos(vec3(-20,20,0));
|
||||
m_debugText.print("life=("+etk::toString(getLifeRatio()));
|
||||
*/
|
||||
//m_debugText.print(etk::String("Axe=(")+etk::String(m_tmpAxe.x())+etk::String(",")+etk::UString(m_tmpAxe.y())+etk::UString(",")+etk::UString(m_tmpAxe.z())+etk::UString(")"));
|
||||
/*
|
||||
// TODO : Keep this it can be usefull to print something in direction of the camera ...
|
||||
m_debugText.draw( etk::matTranslate(getPosition())
|
||||
* etk::matRotate(vec3(0,0,1),_camera.getAngleZ())
|
||||
* etk::matRotate(vec3(1,0,0),(M_PI/2.0f-_camera.getAngleTeta()))
|
||||
* etk::matScale(vec3(0.05,0.05,0.05)));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
171
ege/Entity.hpp
Normal file
171
ege/Entity.hpp
Normal file
@ -0,0 +1,171 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <ewol/debug.hpp>
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <ewol/resource/Colored3DObject.hpp>
|
||||
#include <ege/resource/Mesh.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <ewol/compositing/Text.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/Component.hpp>
|
||||
|
||||
#define INDEX_RIGHT_AXIS (0)
|
||||
#define INDEX_FORWARD_AXIS (1)
|
||||
#define INDEX_UP_AXIS (2)
|
||||
|
||||
#define Entity_SCALE (1.0f/8.0f)
|
||||
|
||||
namespace ege {
|
||||
class Entity : public ememory::EnableSharedFromThis<Entity> {
|
||||
protected:
|
||||
ememory::SharedPtr<ege::Environement> m_env;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor (when constructer is called just add Entity that did not change.
|
||||
* The objest will be stored in a pool of Entity and keep a second time if needed == > redure memory allocation,
|
||||
* when needed, the system will call the init and un-init function...
|
||||
*/
|
||||
Entity(const ememory::SharedPtr<ege::Environement>& _env);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Entity();
|
||||
protected:
|
||||
etk::Vector<ememory::SharedPtr<ege::Component>> m_component;
|
||||
public:
|
||||
void addComponent(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
void rmComponent(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
void rmComponent(const etk::String& _type);
|
||||
ememory::SharedPtr<ege::Component> getComponent(const etk::String& _type);
|
||||
|
||||
/**
|
||||
* @brief get the Entity Type description string.
|
||||
* @return A reference on the descriptive string.
|
||||
*/
|
||||
virtual const etk::String& getType() const;
|
||||
/**
|
||||
* @brief init the Entity with the defined properties
|
||||
* @param[in] _property Type of the next Entity
|
||||
* @param[in] _value pointer on the value type
|
||||
* @return true, the Entity is corectly initialized.
|
||||
*/
|
||||
virtual bool init();
|
||||
virtual bool initString(const etk::String& _description);
|
||||
virtual bool initXML(const exml::Node& _node);
|
||||
virtual bool initJSON(const ejson::Value& _value);
|
||||
virtual bool initVoid(void* _value);
|
||||
virtual bool unInit();
|
||||
private:
|
||||
uint32_t m_uID; //!< This is a reference on a basic Entity ID
|
||||
public:
|
||||
/**
|
||||
* @brief get the curent Entity Unique ID in the all Game.
|
||||
* @return The requested Unique ID.
|
||||
*/
|
||||
inline uint32_t getUID() const {
|
||||
return m_uID;
|
||||
};
|
||||
protected:
|
||||
float m_life; //!< Current life of the object
|
||||
float m_lifeMax; //!< Maximum possible life of the Entity
|
||||
public:
|
||||
/**
|
||||
* @brief get the curent life ratio [0..1]
|
||||
* @return The proportionnal life
|
||||
*/
|
||||
float getLifeRatio();
|
||||
/**
|
||||
* @brief Check if the Entity is dead.
|
||||
* @return true if the Entity does not exist anymore, false otherwise.
|
||||
*/
|
||||
bool isDead() {
|
||||
return (0 >= m_life)?true:false;
|
||||
};
|
||||
/**
|
||||
* @brief Request if the Entity might be removed from the system
|
||||
* @return true == > the object is removed
|
||||
*/
|
||||
virtual bool needToRemove() {
|
||||
return isDead();
|
||||
}
|
||||
/**
|
||||
* @brief apply a fire on the Entity at a current power and a specific power.
|
||||
* @param[in] _groupIdSource Source Id of the group, by default all event arrive at all group, buf some event can not be obviously apply at the ennemy like reparing ....
|
||||
* @param[in] _type Type of event on the life propertied
|
||||
* @param[in] _power Power of the event (can be >0 for adding life).
|
||||
* @param[in] _center Some fire decrease in function of space distance...
|
||||
*/
|
||||
virtual void setFireOn(int32_t _groupIdSource, int32_t _type, float _power, const vec3& _center=vec3(0,0,0));
|
||||
/**
|
||||
* @brief Call when the Entity life change.
|
||||
*/
|
||||
virtual void onLifeChange() { };
|
||||
protected:
|
||||
int32_t m_group; //!< Every Entity has a generic group
|
||||
public:
|
||||
/**
|
||||
* @brief get the Group of the Entity.
|
||||
* @return The group ID
|
||||
*/
|
||||
inline int32_t getGroup() const {
|
||||
return m_group;
|
||||
};
|
||||
/**
|
||||
* @brief set the group of the curent Entity
|
||||
* @param[in] newGroup The new Group ID of the Entity.
|
||||
*/
|
||||
inline void setGroup(int32_t _newGroup) {
|
||||
m_group=_newGroup;
|
||||
};
|
||||
protected:
|
||||
// For debug only ...
|
||||
//ewol::compositing::Text m_debugText; // ==> this is reall y a bad idea==> it is inneficient ...
|
||||
public:
|
||||
/**
|
||||
* @brief Debug display of the current Entity
|
||||
* @param[in,out] _draw Basic system to draw the debug shape and informations
|
||||
* @param[in] _camera Current camera for display
|
||||
*/
|
||||
virtual void drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
/**
|
||||
* @brief Event arrive when an Entity has been remove from the system == > this permit to keep pointer of ennemy, and not search them every cycle ...
|
||||
* @param[in] _removedEntity Pointer on the Entity removed.
|
||||
*/
|
||||
virtual void entityIsRemoved(ememory::SharedPtr<ege::Entity> _removedEntity) { };
|
||||
protected:
|
||||
float m_radius; //!< Radius of the Entity (all Entity have a radius, if == 0 ==> then ghost ...
|
||||
public:
|
||||
/**
|
||||
* @brief get the current space needed by the Entity in the workspace
|
||||
* @return The dimention needed.
|
||||
*/
|
||||
inline float getRadius() {
|
||||
return m_radius;
|
||||
};
|
||||
/**
|
||||
* @brief, call when the Entity is removed (call only one time)
|
||||
*/
|
||||
virtual void onDestroy() {};
|
||||
/**
|
||||
* @brief set the elment in the physique engine
|
||||
*/
|
||||
virtual void dynamicEnable() {};
|
||||
/**
|
||||
* @brief remove this Entity from the physique engine
|
||||
*/
|
||||
virtual void dynamicDisable() {};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,110 +1,204 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/elements/Element.hpp>
|
||||
#include <ege/Entity.hpp>
|
||||
#include <ewol/object/Manager.hpp>
|
||||
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <LinearMath/btTransformUtil.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
#include <ege/particule/Engine.hpp>
|
||||
#include <ege/render/Engine.hpp>
|
||||
#include <ege/ia/Engine.hpp>
|
||||
#include <ege/physics/Engine.hpp>
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::getElementNearest(ememory::SharedPtr<ege::Element> _sourceRequest, float& _distance) {
|
||||
if (_sourceRequest == nullptr) {
|
||||
return nullptr;
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
#include <etk/typeInfo.hpp>
|
||||
|
||||
ETK_DECLARE_TYPE(ege::gameStatus);
|
||||
|
||||
void ege::Environement::addEngine(const ememory::SharedPtr<ege::Engine>& _ref) {
|
||||
if (_ref == null) {
|
||||
EGE_ERROR("try to add an empty Engine");
|
||||
return;
|
||||
}
|
||||
vec3 sourcePosition = _sourceRequest->getPosition();
|
||||
ememory::SharedPtr<ege::Element> result = nullptr;
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
// chack nullptr pointer
|
||||
if (m_listElement[iii] == nullptr) {
|
||||
// check if not exist
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_listElement[iii]->getGroup() <= 0) {
|
||||
if (it->getType() == _ref->getType()) {
|
||||
it = _ref;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// try to add in an empty slot
|
||||
for (auto &it: m_engine) {
|
||||
if (it != null) {
|
||||
continue;
|
||||
}
|
||||
it = _ref;
|
||||
return;
|
||||
}
|
||||
// add it at the end ...
|
||||
m_engine.pushBack(_ref);
|
||||
}
|
||||
|
||||
void ege::Environement::rmEngine(const ememory::SharedPtr<ege::Engine>& _ref) {
|
||||
if (_ref == null) {
|
||||
EGE_ERROR("try to remove an empty engine");
|
||||
return;
|
||||
}
|
||||
// check if not exist
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (it == _ref) {
|
||||
it = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
EGE_ERROR("try to remove an unexisting engine");
|
||||
}
|
||||
|
||||
void ege::Environement::rmEngine(const etk::String& _type) {
|
||||
// check if not exist
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (it->getType() == _type) {
|
||||
it = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
EGE_ERROR("try to remove an unexisting engine type : '" << _type << "'");
|
||||
return;
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Engine> ege::Environement::getEngine(const etk::String& _type) {
|
||||
// check if not exist
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (it->getType() == _type) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
EGE_ERROR("try to get an unexisting engine type : '" << _type << "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
void ege::Environement::engineComponentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (it->getType() == _ref->getType()) {
|
||||
it->componentRemove(_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ege::Environement::engineComponentAdd(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
for (auto &it: m_engine) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
if (it->getType() == _ref->getType()) {
|
||||
it->componentAdd(_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ememory::SharedPtr<ege::Entity> ege::Environement::getEntityNearest(ememory::SharedPtr<ege::Entity> _sourceRequest, float& _distance) {
|
||||
if (_sourceRequest == null) {
|
||||
return null;
|
||||
}
|
||||
vec3 sourcePosition = _sourceRequest->getPosition();
|
||||
ememory::SharedPtr<ege::Entity> result = null;
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
// chack null pointer
|
||||
if (m_listEntity[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_listEntity[iii]->getGroup() <= 0) {
|
||||
continue;
|
||||
}
|
||||
// check if they are in the same group:
|
||||
if (m_listElement[iii]->getGroup() == _sourceRequest->getGroup()) {
|
||||
if (m_listEntity[iii]->getGroup() == _sourceRequest->getGroup()) {
|
||||
continue;
|
||||
}
|
||||
// check distance ...
|
||||
vec3 destPosition = m_listElement[iii]->getPosition();
|
||||
float distance = btDistance(sourcePosition, destPosition);
|
||||
vec3 destPosition = m_listEntity[iii]->getPosition();
|
||||
float distance = (sourcePosition - destPosition).length();
|
||||
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
||||
if (_distance>distance) {
|
||||
_distance = distance;
|
||||
result = m_listElement[iii];
|
||||
result = m_listEntity[iii];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ege::Environement::getElementNearest(const vec3& _sourcePosition,
|
||||
void ege::Environement::getEntityNearest(const vec3& _sourcePosition,
|
||||
float _distanceMax,
|
||||
std::vector<ege::Environement::ResultNearestElement>& _resultList) {
|
||||
etk::Vector<ege::Environement::ResultNearestEntity>& _resultList) {
|
||||
_resultList.clear();
|
||||
ege::Environement::ResultNearestElement result;
|
||||
ege::Environement::ResultNearestEntity result;
|
||||
result.dist = 99999999999.0f;
|
||||
result.element = nullptr;
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
// chack nullptr pointer
|
||||
result.element = m_listElement[iii];
|
||||
if (result.element == nullptr) {
|
||||
result.entity = null;
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
// chack null pointer
|
||||
result.entity = m_listEntity[iii];
|
||||
if (result.entity == null) {
|
||||
continue;
|
||||
}
|
||||
// check distance ...
|
||||
vec3 destPosition = result.element->getPosition();
|
||||
vec3 destPosition = result.entity->getPosition();
|
||||
if (_sourcePosition == destPosition) {
|
||||
continue;
|
||||
}
|
||||
result.dist = btDistance(_sourcePosition, destPosition);
|
||||
result.dist = (_sourcePosition - destPosition).length();
|
||||
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
||||
if (_distanceMax>result.dist) {
|
||||
_resultList.push_back(result);
|
||||
_resultList.pushBack(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ege::Environement::getElementNearestFixed(const vec3& _sourcePosition,
|
||||
void ege::Environement::getEntityNearestFixed(const vec3& _sourcePosition,
|
||||
float _distanceMax,
|
||||
std::vector<ege::Environement::ResultNearestElement>& _resultList) {
|
||||
etk::Vector<ege::Environement::ResultNearestEntity>& _resultList) {
|
||||
_resultList.clear();
|
||||
ege::Environement::ResultNearestElement result;
|
||||
ege::Environement::ResultNearestEntity result;
|
||||
result.dist = 99999999999.0f;
|
||||
result.element = nullptr;
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
// chack nullptr pointer
|
||||
result.element = m_listElement[iii];
|
||||
if (result.element == nullptr) {
|
||||
result.entity = null;
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
// chack null pointer
|
||||
result.entity = m_listEntity[iii];
|
||||
if (result.entity == null) {
|
||||
continue;
|
||||
}
|
||||
if (result.element->isFixed() == false) {
|
||||
if (result.entity->isFixed() == false) {
|
||||
continue;
|
||||
}
|
||||
// check distance ...
|
||||
vec3 destPosition = result.element->getPositionTheoric();
|
||||
result.dist = btDistance(_sourcePosition, destPosition);
|
||||
vec3 destPosition = result.entity->getPositionTheoric();
|
||||
result.dist = (_sourcePosition - destPosition).length();
|
||||
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
||||
if (_distanceMax <= result.dist) {
|
||||
continue;
|
||||
}
|
||||
// try to add the element at the best positions:
|
||||
// try to add the entity at the best positions:
|
||||
size_t jjj;
|
||||
for (jjj=0; jjj<_resultList.size(); jjj++) {
|
||||
if (_resultList[jjj].dist>result.dist) {
|
||||
@ -112,20 +206,21 @@ void ege::Environement::getElementNearestFixed(const vec3& _sourcePosition,
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add element at the end :
|
||||
// add entity at the end :
|
||||
if (jjj >= _resultList.size()) {
|
||||
_resultList.push_back(result);
|
||||
_resultList.pushBack(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static etk::Hash<ege::createElement_tf>& getHachTableCreating() {
|
||||
static etk::Hash<ege::createElement_tf> s_table;
|
||||
static etk::Map<etk::String,ege::createEntity_tf>& getHachTableCreating() {
|
||||
static etk::Map<etk::String,ege::createEntity_tf> s_table(0,false);
|
||||
return s_table;
|
||||
}
|
||||
|
||||
void ege::Environement::addCreator(const std::string& _type, ege::createElement_tf _creator) {
|
||||
if (_creator == nullptr) {
|
||||
void ege::Environement::addCreator(const etk::String& _type, ege::createEntity_tf _creator) {
|
||||
if (_creator == null) {
|
||||
EGE_ERROR("Try to add an empty CREATOR ...");
|
||||
return;
|
||||
}
|
||||
@ -135,237 +230,84 @@ void ege::Environement::addCreator(const std::string& _type, ege::createElement_
|
||||
}
|
||||
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::createElement(const std::string& _type, const std::string& _description, bool _autoAddElement) {
|
||||
ememory::SharedPtr<ege::Entity> ege::Environement::createEntity(const etk::String& _type, const ejson::Value& _value, bool _autoAddEntity) {
|
||||
if (getHachTableCreating().exist(_type) == false) {
|
||||
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
||||
return nullptr;
|
||||
return null;
|
||||
}
|
||||
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == nullptr) {
|
||||
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
||||
return nullptr;
|
||||
ege::createEntity_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == null) {
|
||||
EGE_ERROR("null pointer creator == > internal error... '" << _type << "'");
|
||||
return null;
|
||||
}
|
||||
ememory::SharedPtr<ege::Element> tmpElement = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()));
|
||||
if (tmpElement == nullptr) {
|
||||
ememory::SharedPtr<ege::Entity> tmpEntity = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()), _value);
|
||||
if (tmpEntity == null) {
|
||||
EGE_ERROR("allocation error '" << _type << "'");
|
||||
return nullptr;
|
||||
return null;
|
||||
}
|
||||
if (tmpElement->initString(_description) == false) {
|
||||
EGE_ERROR("Init error ... '" << _type << "'");
|
||||
return nullptr;
|
||||
if (_autoAddEntity == true) {
|
||||
addEntity(tmpEntity);
|
||||
}
|
||||
if (_autoAddElement == true) {
|
||||
addElement(tmpElement);
|
||||
}
|
||||
return tmpElement;
|
||||
return tmpEntity;
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::createElement(const std::string& _type, const ejson::Value& _value, bool _autoAddElement) {
|
||||
if (getHachTableCreating().exist(_type) == false) {
|
||||
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == nullptr) {
|
||||
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ememory::SharedPtr<ege::Element> tmpElement = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()));
|
||||
if (tmpElement == nullptr) {
|
||||
EGE_ERROR("allocation error '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (tmpElement->initJSON(_value) == false) {
|
||||
EGE_ERROR("Init error ... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (_autoAddElement == true) {
|
||||
addElement(tmpElement);
|
||||
}
|
||||
return tmpElement;
|
||||
ememory::SharedPtr<ege::Entity> ege::Environement::createEntity(const etk::String& _type, bool _autoAddEntity) {
|
||||
ejson::Value empty;
|
||||
return createEntity(_type, empty, _autoAddEntity);
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::createElement(const std::string& _type, const exml::Node& _node, bool _autoAddElement) {
|
||||
if (getHachTableCreating().exist(_type) == false) {
|
||||
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == nullptr) {
|
||||
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ememory::SharedPtr<ege::Element> tmpElement = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()));
|
||||
if (tmpElement == nullptr) {
|
||||
EGE_ERROR("allocation error '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (tmpElement->initXML(_node) == false) {
|
||||
EGE_ERROR("Init error ... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (_autoAddElement == true) {
|
||||
addElement(tmpElement);
|
||||
}
|
||||
return tmpElement;
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::createElement(const std::string& _type, void* _data, bool _autoAddElement) {
|
||||
if (getHachTableCreating().exist(_type) == false) {
|
||||
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == nullptr) {
|
||||
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ememory::SharedPtr<ege::Element> tmpElement = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()));
|
||||
if (tmpElement == nullptr) {
|
||||
EGE_ERROR("allocation error '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (tmpElement->initVoid(_data) == false) {
|
||||
EGE_ERROR("Init error ... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (_autoAddElement == true) {
|
||||
addElement(tmpElement);
|
||||
}
|
||||
return tmpElement;
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Element> ege::Environement::createElement(const std::string& _type, bool _autoAddElement) {
|
||||
if (getHachTableCreating().exist(_type) == false) {
|
||||
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
||||
if (creatorPointer == nullptr) {
|
||||
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ememory::SharedPtr<ege::Element> tmpElement = creatorPointer(ememory::dynamicPointerCast<ege::Environement>(sharedFromThis()));
|
||||
if (tmpElement == nullptr) {
|
||||
EGE_ERROR("allocation error '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (tmpElement->init() == false) {
|
||||
EGE_ERROR("Init error ... '" << _type << "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (_autoAddElement == true) {
|
||||
addElement(tmpElement);
|
||||
}
|
||||
return tmpElement;
|
||||
}
|
||||
|
||||
void ege::Environement::addElement(ememory::SharedPtr<ege::Element> _newElement) {
|
||||
void ege::Environement::addEntity(ememory::SharedPtr<ege::Entity> _newEntity) {
|
||||
// prevent memory allocation and un allocation ...
|
||||
if (_newElement == nullptr) {
|
||||
if (_newEntity == null) {
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
if (m_listElement[iii] == nullptr) {
|
||||
m_listElement[iii] = _newElement;
|
||||
m_listElement[iii]->dynamicEnable();
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
if (m_listEntity[iii] == null) {
|
||||
m_listEntity[iii] = _newEntity;
|
||||
m_listEntity[iii]->dynamicEnable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_listElement.push_back(_newElement);
|
||||
_newElement->dynamicEnable();
|
||||
m_listEntity.pushBack(_newEntity);
|
||||
_newEntity->dynamicEnable();
|
||||
}
|
||||
|
||||
void ege::Environement::rmElement(ememory::SharedPtr<ege::Element> _removeElement) {
|
||||
if (_removeElement == nullptr) {
|
||||
void ege::Environement::rmEntity(ememory::SharedPtr<ege::Entity> _removeEntity) {
|
||||
if (_removeEntity == null) {
|
||||
return;
|
||||
}
|
||||
// inform the element that an element has been removed == > this permit to keep pointer on elements ...
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
if (m_listElement[iii] != nullptr) {
|
||||
m_listElement[iii]->elementIsRemoved(_removeElement);
|
||||
// inform the entity that an entity has been removed == > this permit to keep pointer on entitys ...
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
if (m_listEntity[iii] != null) {
|
||||
m_listEntity[iii]->entityIsRemoved(_removeEntity);
|
||||
}
|
||||
}
|
||||
// ream remove on the element :
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
if (_removeElement == m_listElement[iii]) {
|
||||
m_listElement[iii]->onDestroy();
|
||||
m_listElement[iii]->dynamicDisable();
|
||||
m_listElement[iii]->unInit();
|
||||
m_listElement[iii].reset();
|
||||
// ream remove on the entity :
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
if (_removeEntity == m_listEntity[iii]) {
|
||||
m_listEntity[iii]->onDestroy();
|
||||
m_listEntity[iii]->dynamicDisable();
|
||||
m_listEntity[iii]->unInit();
|
||||
m_listEntity[iii].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ege::Environement::getOrderedElementForDisplay(std::vector<ege::Environement::ResultNearestElement>& _resultList,
|
||||
const vec3& _position,
|
||||
const vec3& _direction) {
|
||||
// TODO : Set it back ... corrected...
|
||||
// remove all unneeded elements (old display...)
|
||||
_resultList.clear();
|
||||
// basic element result
|
||||
ege::Environement::ResultNearestElement result;
|
||||
result.dist = 99999999999.0f;
|
||||
result.element = nullptr;
|
||||
// for all element in the game we chek if it is needed to display it ...
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
// chack nullptr pointer
|
||||
if (m_listElement[iii] == nullptr) {
|
||||
// no pointer null are set in the output list ...
|
||||
void ege::Environement::generateInteraction(ege::EntityInteraction& _event) {
|
||||
// inform the entity that an entity has been removed == > this permit to keep pointer on entitys ...
|
||||
for (size_t iii=0; iii<m_listEntity.size() ; iii++) {
|
||||
if (m_listEntity[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
result.element = m_listElement[iii];
|
||||
// check distance ...
|
||||
vec3 destPosition = result.element->getPosition();
|
||||
vec3 angleView = (destPosition - _position);
|
||||
angleView.safeNormalize();
|
||||
float dotResult=angleView.dot(_direction);
|
||||
//EGE_DEBUG("Dot position : " << destPosition << " == > dot=" << dotResult);
|
||||
_event.applyEvent(*m_listEntity[iii]);
|
||||
/*
|
||||
if (dotResult <= 0.85f) {
|
||||
// they are not in the camera angle view ... == > no need to process display
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
result.dist = btDistance(_position, destPosition);
|
||||
/*
|
||||
if (result.dist>500.0f) {
|
||||
// The element is realy too far ... == > no need to display
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
// try to add the element at the best positions:
|
||||
size_t jjj;
|
||||
for (jjj=0; jjj<_resultList.size(); jjj++) {
|
||||
if (_resultList[jjj].dist>result.dist) {
|
||||
_resultList.insert(_resultList.begin()+jjj, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add element at the end :
|
||||
if (jjj >= _resultList.size()) {
|
||||
_resultList.push_back(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ege::Environement::generateInteraction(ege::ElementInteraction& _event) {
|
||||
// inform the element that an element has been removed == > this permit to keep pointer on elements ...
|
||||
for (size_t iii=0; iii<m_listElement.size() ; iii++) {
|
||||
if (m_listElement[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
_event.applyEvent(*m_listElement[iii]);
|
||||
/*
|
||||
vec3 destPosition = m_listElement[iii]->getPosition();
|
||||
float dist = btDistance(sourcePosition, destPosition);
|
||||
vec3 destPosition = m_listEntity[iii]->getPosition();
|
||||
float dist = (sourcePosition - destPosition).length;
|
||||
if (dist == 0 || dist>decreasePower) {
|
||||
continue;
|
||||
}
|
||||
float inpact = (decreasePower-dist)/decreasePower * power;
|
||||
g_listElement[iii]->setFireOn(groupIdSource, type, -inpact, sourcePosition);
|
||||
g_listEntity[iii]->setFireOn(groupIdSource, type, -inpact, sourcePosition);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -379,19 +321,46 @@ ege::Environement::Environement() :
|
||||
propertyRatio(this, "ratio",
|
||||
1.0f,
|
||||
"game speed ratio"),
|
||||
m_listElement(),
|
||||
m_particuleEngine(this) {
|
||||
m_listEntity() {
|
||||
// nothing to do ...
|
||||
propertyStatus.add(gameStart, "start", "Scene is started");
|
||||
propertyStatus.add(gamePause, "pause", "Scene is paused");
|
||||
propertyStatus.add(gameStop, "stop", "Scene is stopped");
|
||||
// we add the 4 classical engines (the order is used to the global rendering cycle ...
|
||||
addEngine(ememory::makeShared<ege::physics::Engine>(this));
|
||||
addEngine(ememory::makeShared<ege::ia::Engine>(this));
|
||||
addEngine(ememory::makeShared<ege::render::Engine>(this));
|
||||
addEngine(ememory::makeShared<ege::particule::Engine>(this));
|
||||
}
|
||||
|
||||
void ege::Environement::clear() {
|
||||
m_listElement.clear();
|
||||
m_listEntity.clear();
|
||||
}
|
||||
|
||||
|
||||
void ege::Environement::render(const echrono::Duration& _delta, const etk::String& _camera) {
|
||||
// get the correct camera:
|
||||
ememory::SharedPtr<ege::Camera> camera = getCamera(_camera);
|
||||
if (camera == null) {
|
||||
EGE_ERROR("Render: Can not get camera named: '" << _camera << "'");
|
||||
return;
|
||||
}
|
||||
for (auto &it: m_engine) {
|
||||
if(it == null) {
|
||||
continue;
|
||||
}
|
||||
EGE_VERBOSE(" render: " << it->getType());
|
||||
it->render(_delta, camera);
|
||||
}
|
||||
for (auto &it: m_engine) {
|
||||
if(it == null) {
|
||||
continue;
|
||||
}
|
||||
EGE_VERBOSE(" render: " << it->getType());
|
||||
it->renderDebug(_delta, camera);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::Environement::onCallbackPeriodicCall(const ewol::event::Time& _event) {
|
||||
float curentDelta = _event.getDeltaCall();
|
||||
EGE_VERBOSE("periodic call : " << _event);
|
||||
@ -413,36 +382,43 @@ void ege::Environement::onCallbackPeriodicCall(const ewol::event::Time& _event)
|
||||
|
||||
// update camera positions:
|
||||
for (auto &it : m_listCamera) {
|
||||
if (it.second != nullptr) {
|
||||
if (it.second != null) {
|
||||
EGE_VERBOSE(" update camera : '" << it.first << "'");
|
||||
it.second->periodicCall(curentDelta);
|
||||
}
|
||||
}
|
||||
EGE_VERBOSE(" step simulation : " << curentDelta);
|
||||
for (auto &it: m_engine) {
|
||||
if(it == null) {
|
||||
continue;
|
||||
}
|
||||
EGE_VERBOSE(" update: " << it->getType());
|
||||
it->update(echrono::Duration(double(curentDelta)));
|
||||
}
|
||||
|
||||
//EGE_DEBUG("stepSimulation (start)");
|
||||
///step the simulation
|
||||
if (m_physicEngine.getDynamicWorld() != nullptr) {
|
||||
EGE_VERBOSE(" step simulation : " << curentDelta);
|
||||
m_physicEngine.getDynamicWorld()->stepSimulation(curentDelta);
|
||||
//optional but useful: debug drawing
|
||||
m_physicEngine.getDynamicWorld()->debugDrawWorld();
|
||||
}
|
||||
EGE_VERBOSE(" Update particule engine");
|
||||
m_particuleEngine.update(curentDelta);
|
||||
// remove all element that requested it ...
|
||||
// TODO : m_physicEngine.update(curentDelta);
|
||||
// TODO : //optional but useful: debug drawing
|
||||
// TODO : m_physicEngine.debugDrawWorld();
|
||||
// TODO : EGE_INFO(" Update particule engine");
|
||||
// TODO : m_particuleEngine.update(curentDelta);
|
||||
// remove all entity that requested it ...
|
||||
/**
|
||||
{
|
||||
int32_t numberEnnemyKilled=0;
|
||||
int32_t victoryPoint=0;
|
||||
auto it(m_listElement.begin());
|
||||
while (it != m_listElement.end()) {
|
||||
if(*it != nullptr) {
|
||||
auto it(m_listEntity.begin());
|
||||
while (it != m_listEntity.end()) {
|
||||
if(*it != null) {
|
||||
if ((*it)->needToRemove() == true) {
|
||||
if ((*it)->getGroup() > 1) {
|
||||
numberEnnemyKilled++;
|
||||
victoryPoint++;
|
||||
}
|
||||
EGE_VERBOSE("[" << (*it)->getUID() << "] element Removing ... " << (*it)->getType());
|
||||
rmElement((*it));
|
||||
it = m_listElement.begin();
|
||||
EGE_INFO("[" << (*it)->getUID() << "] entity Removing ... " << (*it)->getType());
|
||||
rmEntity((*it));
|
||||
it = m_listEntity.begin();
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@ -454,19 +430,20 @@ void ege::Environement::onCallbackPeriodicCall(const ewol::event::Time& _event)
|
||||
//signalKillEnemy.emit(numberEnnemyKilled);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void ege::Environement::addCamera(const std::string& _name, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
m_listCamera.insert(std::make_pair(_name, _camera));
|
||||
void ege::Environement::addCamera(const etk::String& _name, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
m_listCamera.set(_name, _camera);
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::Camera> ege::Environement::getCamera(const std::string& _name) {
|
||||
ememory::SharedPtr<ege::Camera> ege::Environement::getCamera(const etk::String& _name) {
|
||||
auto cameraIt = m_listCamera.find(_name);
|
||||
if (cameraIt != m_listCamera.end()) {
|
||||
return cameraIt->second;
|
||||
}
|
||||
return nullptr;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,36 +1,33 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
class Environement;
|
||||
class ElementInteraction;
|
||||
class EntityInteraction;
|
||||
};
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <ege/ParticuleEngine.hpp>
|
||||
|
||||
#include <ege/Engine.hpp>
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <BulletDynamics/Dynamics/btActionInterface.h>
|
||||
class btDynamicsWorld;
|
||||
|
||||
#include <vector>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <ejson/ejson.hpp>
|
||||
#include <exml/exml.hpp>
|
||||
#include <ewol/object/Object.hpp>
|
||||
#include <esignal/Signal.hpp>
|
||||
#include <ewol/event/Time.hpp>
|
||||
#include <eproperty/Value.hpp>
|
||||
#include <ege/resource/Mesh.hpp>
|
||||
#include <ege/physics/Engine.hpp>
|
||||
|
||||
namespace ege {
|
||||
class Element;
|
||||
class Entity;
|
||||
class Environement;
|
||||
typedef ememory::SharedPtr<ege::Element> (*createElement_tf)(const ememory::SharedPtr<ege::Environement>& _env);
|
||||
typedef ememory::SharedPtr<ege::Entity> (*createEntity_tf)(const ememory::SharedPtr<ege::Environement>& _env, const ejson::Value& _property);
|
||||
|
||||
enum gameStatus {
|
||||
gameStart,
|
||||
@ -38,7 +35,7 @@ namespace ege {
|
||||
gameStop
|
||||
};
|
||||
|
||||
class ElementInteraction {
|
||||
class EntityInteraction {
|
||||
protected:
|
||||
int32_t m_type;
|
||||
public:
|
||||
@ -52,13 +49,13 @@ namespace ege {
|
||||
return m_groupSource;
|
||||
};
|
||||
protected:
|
||||
std::vector<int32_t> m_groupDestination;
|
||||
etk::Vector<int32_t> m_groupDestination;
|
||||
public:
|
||||
const std::vector<int32_t>& getDestinationGroup() {
|
||||
const etk::Vector<int32_t>& getDestinationGroup() {
|
||||
return m_groupDestination;
|
||||
};
|
||||
void addGroupDestination(int32_t _id) {
|
||||
m_groupDestination.push_back(_id);
|
||||
m_groupDestination.pushBack(_id);
|
||||
};
|
||||
protected:
|
||||
vec3 m_positionSource;
|
||||
@ -67,15 +64,16 @@ namespace ege {
|
||||
return m_positionSource;
|
||||
};
|
||||
public:
|
||||
ElementInteraction(int32_t _type, int32_t _groupSource, const vec3& _pos) :
|
||||
EntityInteraction(int32_t _type, int32_t _groupSource, const vec3& _pos) :
|
||||
m_type(_type),
|
||||
m_groupSource(_groupSource),
|
||||
m_positionSource(_pos)
|
||||
{ };
|
||||
virtual ~EntityInteraction() = default;
|
||||
public:
|
||||
virtual void applyEvent(ege::Element& _element) { };
|
||||
virtual void applyEvent(ege::Entity& _entity) { };
|
||||
};
|
||||
|
||||
// TODO : An entity must be created by a local factory...
|
||||
class Environement : public ewol::Object {
|
||||
public:
|
||||
// Signals
|
||||
@ -83,36 +81,45 @@ namespace ege {
|
||||
// properties:
|
||||
eproperty::List<enum gameStatus> propertyStatus; //!< the display is running (not in pause)
|
||||
eproperty::Value<float> propertyRatio; //!< Speed ratio
|
||||
protected:
|
||||
etk::Vector<ememory::SharedPtr<ege::Engine>> m_engine; //!< EGE sub engine interface (like physique, rendering, audio, ...).
|
||||
public:
|
||||
void addEngine(const ememory::SharedPtr<ege::Engine>& _ref);
|
||||
void rmEngine(const ememory::SharedPtr<ege::Engine>& _ref);
|
||||
void rmEngine(const etk::String& _type);
|
||||
ememory::SharedPtr<ege::Engine> getEngine(const etk::String& _type);
|
||||
void engineComponentRemove(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
void engineComponentAdd(const ememory::SharedPtr<ege::Component>& _ref);
|
||||
|
||||
private:
|
||||
//ememory::SharedPtr<btDynamicsWorld> m_dynamicsWorld; //!< curent system world description
|
||||
ege::physics::Engine m_physicEngine; //!< EGE physic engine interface.
|
||||
std::vector<ememory::SharedPtr<ege::Element>> m_listElement; //!< List of all element added in the Game
|
||||
etk::Vector<ememory::SharedPtr<ege::Entity>> m_listEntity; //!< List of all entity added in the Game
|
||||
protected:
|
||||
Environement();
|
||||
public:
|
||||
DECLARE_FACTORY(Environement);
|
||||
virtual ~Environement() { };
|
||||
public:
|
||||
void render(const echrono::Duration& _delta, const etk::String& _camera);
|
||||
protected:
|
||||
protected:
|
||||
std::map<std::string, ememory::SharedPtr<ege::Camera>> m_listCamera; //!< list of all camera in the world
|
||||
etk::Map<etk::String, ememory::SharedPtr<ege::Camera>> m_listCamera; //!< list of all camera in the world
|
||||
public:
|
||||
/**
|
||||
* @brief Add a camera in the camera pool.
|
||||
* @param[in] _name Name of the camera.
|
||||
* @param[in] _camera Pointer on the camera to add.
|
||||
*/
|
||||
void addCamera(const std::string& _name, const ememory::SharedPtr<ege::Camera>& _camera);
|
||||
void addCamera(const etk::String& _name, const ememory::SharedPtr<ege::Camera>& _camera);
|
||||
/**
|
||||
* @brief Get a specific camera.
|
||||
* @param[in] _name Name of the camera.
|
||||
* @return A pointer on the camera requested.
|
||||
*/
|
||||
ememory::SharedPtr<ege::Camera> getCamera(const std::string& _name);
|
||||
ememory::SharedPtr<ege::Camera> getCamera(const etk::String& _name);
|
||||
/**
|
||||
* @brief Get List of all camera.
|
||||
* @return All the camera registerred.
|
||||
*/
|
||||
std::map<std::string, ememory::SharedPtr<ege::Camera>> getCameraList() const {
|
||||
etk::Map<etk::String, ememory::SharedPtr<ege::Camera>> getCameraList() const {
|
||||
return m_listCamera;
|
||||
}
|
||||
public:
|
||||
@ -121,28 +128,25 @@ namespace ege {
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief add a creator element system
|
||||
* @param[in] _type Type of the element.
|
||||
* @param[in] _creator Function pointer that reference the element creating.
|
||||
* @brief add a creator entity system
|
||||
* @param[in] _type Type of the entity.
|
||||
* @param[in] _creator Function pointer that reference the entity creating.
|
||||
*/
|
||||
static void addCreator(const std::string& _type, ege::createElement_tf _creator);
|
||||
static void addCreator(const etk::String& _type, ege::createEntity_tf _creator);
|
||||
/**
|
||||
* @brief Create an element on the curent scene.
|
||||
* @param[in] _type Type of the element that might be created.
|
||||
* @param[in] _description String that describe the content of the element properties.
|
||||
* @param[in] _autoAddElement this permit to add the element if it is created == > no more action ...
|
||||
* @return nullptr if an error occured OR the pointer on the element and it is already added on the system.
|
||||
* @brief Create an entity on the curent scene.
|
||||
* @param[in] _type Type of the entity that might be created.
|
||||
* @param[in] _description String that describe the content of the entity properties.
|
||||
* @param[in] _autoAddEntity this permit to add the entity if it is created == > no more action ...
|
||||
* @return null if an error occured OR the pointer on the entity and it is already added on the system.
|
||||
* @note Pointer is return in case of setting properties on it...
|
||||
*/
|
||||
ememory::SharedPtr<ege::Element> createElement(const std::string& _type, const std::string& _description, bool _autoAddElement=true);
|
||||
ememory::SharedPtr<ege::Element> createElement(const std::string& _type, const ejson::Value& _value, bool _autoAddElement=true);
|
||||
ememory::SharedPtr<ege::Element> createElement(const std::string& _type, const exml::Node& _node, bool _autoAddElement=true);
|
||||
ememory::SharedPtr<ege::Element> createElement(const std::string& _type, void* _data, bool _autoAddElement=true);
|
||||
ememory::SharedPtr<ege::Element> createElement(const std::string& _type, bool _autoAddElement=true);
|
||||
ememory::SharedPtr<ege::Entity> createEntity(const etk::String& _type, const ejson::Value& _value, bool _autoAddEntity=true);
|
||||
ememory::SharedPtr<ege::Entity> createEntity(const etk::String& _type, bool _autoAddEntity=true);
|
||||
public:
|
||||
class ResultNearestElement {
|
||||
class ResultNearestEntity {
|
||||
public:
|
||||
ememory::SharedPtr<ege::Element> element;
|
||||
ememory::SharedPtr<ege::Entity> entity;
|
||||
float dist;
|
||||
};
|
||||
#if 0
|
||||
@ -161,62 +165,44 @@ namespace ege {
|
||||
return m_dynamicsWorld;
|
||||
};
|
||||
#endif
|
||||
ege::physics::Engine& getPhysicEngine() {
|
||||
return m_physicEngine;
|
||||
}
|
||||
/**
|
||||
* @breif get a reference on the curent list of element games
|
||||
* @return all element list
|
||||
* @breif get a reference on the curent list of entity games
|
||||
* @return all entity list
|
||||
*/
|
||||
std::vector<ememory::SharedPtr<ege::Element>>& getElement() {
|
||||
return m_listElement;
|
||||
etk::Vector<ememory::SharedPtr<ege::Entity>>& getEntity() {
|
||||
return m_listEntity;
|
||||
};
|
||||
/**
|
||||
* @brief get the nearest Element
|
||||
* @param[in] _sourceRequest Pointer on the element that request this.
|
||||
* @param[in] _distance Maximum distance search == > return the element distance
|
||||
* @return Pointer on the neares element OR nullptr
|
||||
* @brief get the nearest Entity
|
||||
* @param[in] _sourceRequest Pointer on the entity that request this.
|
||||
* @param[in] _distance Maximum distance search == > return the entity distance
|
||||
* @return Pointer on the neares entity OR null
|
||||
*/
|
||||
ememory::SharedPtr<ege::Element> getElementNearest(ememory::SharedPtr<ege::Element> _sourceRequest, float& _distance);
|
||||
/*
|
||||
ememory::SharedPtr<ege::Entity> getEntityNearest(ememory::SharedPtr<ege::Entity> _sourceRequest, float& _distance);
|
||||
|
||||
void getElementNearest(const vec3& _sourcePosition,
|
||||
void getEntityNearest(const vec3& _sourcePosition,
|
||||
float _distanceMax,
|
||||
std::vector<ege::Environement::ResultNearestElement>& _resultList);
|
||||
void getElementNearestFixed(const vec3& _sourcePosition,
|
||||
etk::Vector<ege::Environement::ResultNearestEntity>& _resultList);
|
||||
void getEntityNearestFixed(const vec3& _sourcePosition,
|
||||
float _distanceMax,
|
||||
std::vector<ege::Environement::ResultNearestElement>& _resultList);
|
||||
etk::Vector<ege::Environement::ResultNearestEntity>& _resultList);
|
||||
*/
|
||||
/**
|
||||
* @brief add an element on the list availlable.
|
||||
* @param[in] _newElement Element to add.
|
||||
* @brief add an entity on the list availlable.
|
||||
* @param[in] _newEntity Entity to add.
|
||||
*/
|
||||
void addElement(ememory::SharedPtr<ege::Element> _newElement);
|
||||
void addEntity(ememory::SharedPtr<ege::Entity> _newEntity);
|
||||
/**
|
||||
* @brief remove an element on the list availlable.
|
||||
* @param[in] _removeElement Element to remove.
|
||||
* @brief remove an entity on the list availlable.
|
||||
* @param[in] _removeEntity Entity to remove.
|
||||
*/
|
||||
void rmElement(ememory::SharedPtr<ege::Element> _removeElement);
|
||||
void rmEntity(ememory::SharedPtr<ege::Entity> _removeEntity);
|
||||
/**
|
||||
* @brief get the element order from the nearest to the farest, and remove all element that are not in the camera angle and axes.
|
||||
* @param[in,out] _resultList List of the element ordered.
|
||||
* @param[in] _position Camera position in the space.
|
||||
* @param[in] _direction Camera direction of the view.
|
||||
*/
|
||||
void getOrderedElementForDisplay(std::vector<ege::Environement::ResultNearestElement>& _resultList, const vec3& _position, const vec3& _direction);
|
||||
/**
|
||||
* @brief generate an event on all the sub element of the game == > usefull for explosion, or lazer fire ...
|
||||
* @brief generate an event on all the sub entity of the game == > usefull for explosion, or lazer fire ...
|
||||
* @param[in] _event event that might be apply ...
|
||||
*/
|
||||
void generateInteraction(ege::ElementInteraction& _event);
|
||||
private:
|
||||
ege::ParticuleEngine m_particuleEngine; //!< Particule engine properties
|
||||
public:
|
||||
/**
|
||||
* @brief get the particule engine reference.
|
||||
* @return The requested reference on the engine
|
||||
*/
|
||||
ege::ParticuleEngine& getParticuleEngine() {
|
||||
return m_particuleEngine;
|
||||
};
|
||||
void generateInteraction(ege::EntityInteraction& _event);
|
||||
protected:
|
||||
int64_t m_gameTime; //!< time of the game running
|
||||
public:
|
||||
@ -224,12 +210,12 @@ namespace ege {
|
||||
private:
|
||||
void onCallbackPeriodicCall(const ewol::event::Time& _event);
|
||||
protected:
|
||||
std::vector<ememory::SharedPtr<ege::resource::Mesh>> m_listMeshToDrawFirst;
|
||||
etk::Vector<ememory::SharedPtr<ege::resource::Mesh>> m_listMeshToDrawFirst;
|
||||
public:
|
||||
void addStaticMeshToDraw(const ememory::SharedPtr<ege::resource::Mesh>& _mesh) {
|
||||
m_listMeshToDrawFirst.push_back(_mesh);
|
||||
m_listMeshToDrawFirst.pushBack(_mesh);
|
||||
}
|
||||
std::vector<ememory::SharedPtr<ege::resource::Mesh>>& getStaticMeshToDraw() {
|
||||
etk::Vector<ememory::SharedPtr<ege::resource::Mesh>>& getStaticMeshToDraw() {
|
||||
return m_listMeshToDrawFirst;
|
||||
}
|
||||
virtual void onChangePropertyStatus();
|
||||
|
49
ege/Game.hpp
49
ege/Game.hpp
@ -1,49 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <vector>
|
||||
#include <ewol/debug.hpp>
|
||||
#include <ege/Camera.hpp>
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <ewol/openGL/openGL.hpp>
|
||||
#include <ewol/resource/Manager.hpp>
|
||||
#include <ege/ElementGame.hpp>
|
||||
#include <ewol/Dimension.hpp>
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
class btOverlappingPairCache;
|
||||
class btCollisionDispatcher;
|
||||
class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
class btDynamicsWorld;
|
||||
#include <LinearMath/btScalar.h>
|
||||
class btVector3;
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
|
||||
namespace ege {
|
||||
enum gameStatus {
|
||||
gameStart,
|
||||
gamePause,
|
||||
gameStop
|
||||
};
|
||||
class Game : public ewol::Object {
|
||||
protected:
|
||||
Game();
|
||||
void init();
|
||||
public:
|
||||
~Game()
|
||||
protected:
|
||||
ege::PhysicEngine m_physicEngine; //!< physic engine interface
|
||||
ege::AudioEngine m_AudioEngine; //!< physic engine interface
|
||||
ege::IAEngine m_iAEngine; //!< physic engine interface
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/Light.hpp>
|
||||
@ -25,8 +25,8 @@ ege::Light::~Light() {
|
||||
|
||||
}
|
||||
|
||||
void ege::Light::link(ememory::SharedPtr<gale::resource::Program> _prog, const std::string& _baseName) {
|
||||
if (_prog == nullptr) {
|
||||
void ege::Light::link(ememory::SharedPtr<gale::resource::Program> _prog, const etk::String& _baseName) {
|
||||
if (_prog == null) {
|
||||
return;
|
||||
}
|
||||
m_GL_direction = _prog->getUniform(_baseName+".direction");
|
||||
@ -44,7 +44,7 @@ void ege::Light::draw(ememory::SharedPtr<gale::resource::Program> _prog) {
|
||||
_prog->uniform4(m_GL_specularColor, m_specularColor);
|
||||
}
|
||||
|
||||
std::ostream& ege::operator <<(std::ostream& _os, const ege::Light& _obj) {
|
||||
etk::Stream& ege::operator <<(etk::Stream& _os, const ege::Light& _obj) {
|
||||
_os << "light:{";
|
||||
_os << "dir=" << _obj.m_direction;
|
||||
_os << " halfplan=" << _obj.m_halfplane;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -29,7 +29,7 @@ namespace ege {
|
||||
public:
|
||||
Light();
|
||||
~Light();
|
||||
void link(ememory::SharedPtr<gale::resource::Program> _prog, const std::string& _baseName);
|
||||
void link(ememory::SharedPtr<gale::resource::Program> _prog, const etk::String& _baseName);
|
||||
void draw(ememory::SharedPtr<gale::resource::Program> _prog);
|
||||
void setDirection(const vec3& val) {
|
||||
m_direction = val;
|
||||
@ -47,8 +47,8 @@ namespace ege {
|
||||
m_specularColor = val;
|
||||
}
|
||||
|
||||
friend std::ostream& operator <<(std::ostream& _os, const ege::Light& _obj);
|
||||
friend etk::Stream& operator <<(etk::Stream& _os, const ege::Light& _obj);
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, const ege::Light& _obj);
|
||||
etk::Stream& operator <<(etk::Stream& _os, const ege::Light& _obj);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <gale/resource/Manager.hpp>
|
||||
@ -17,8 +17,8 @@ ege::MaterialGlId::MaterialGlId() :
|
||||
// nothing to do else ...
|
||||
}
|
||||
|
||||
void ege::MaterialGlId::link(ememory::SharedPtr<gale::resource::Program> _prog, const std::string& _baseName) {
|
||||
if (_prog == nullptr) {
|
||||
void ege::MaterialGlId::link(ememory::SharedPtr<gale::resource::Program> _prog, const etk::String& _baseName) {
|
||||
if (_prog == null) {
|
||||
return;
|
||||
}
|
||||
m_GL_ambientFactor = _prog->getUniform(_baseName+".ambientFactor");
|
||||
@ -34,7 +34,7 @@ ege::Material::Material() :
|
||||
m_specularFactor(0,0,0,1),
|
||||
m_shininess(1),
|
||||
m_renderMode(gale::openGL::renderMode::triangle),
|
||||
m_texture0(nullptr) {
|
||||
m_texture0(null) {
|
||||
// nothing to do else ...
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ void ege::Material::draw(ememory::SharedPtr<gale::resource::Program> _prog, cons
|
||||
_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 (m_texture0 != nullptr) {
|
||||
if (m_texture0 != null) {
|
||||
EGE_VERBOSE(" set texture: " << _glID.m_GL_texture0 << " " << m_texture0->getId());
|
||||
_prog->setTexture0(_glID.m_GL_texture0, m_texture0->getRendererId());
|
||||
#if DEBUG
|
||||
@ -66,17 +66,38 @@ void ege::Material::draw(ememory::SharedPtr<gale::resource::Program> _prog, cons
|
||||
EGE_VERBOSE("draw Material: ( end )");
|
||||
}
|
||||
|
||||
void ege::Material::setTexture0(const std::string& _filename) {
|
||||
bool ege::Material::haveTexture() const {
|
||||
return m_texture0 != null;
|
||||
}
|
||||
|
||||
void ege::Material::setAmbientFactor(const vec4& _val) {
|
||||
m_ambientFactor = _val;
|
||||
}
|
||||
|
||||
void ege::Material::setDiffuseFactor(const vec4& _val) {
|
||||
//EGE_ERROR("**************** set difuse factor:" << _val);
|
||||
m_diffuseFactor = _val;
|
||||
}
|
||||
|
||||
void ege::Material::setSpecularFactor(const vec4& _val) {
|
||||
m_specularFactor = _val;
|
||||
}
|
||||
|
||||
void ege::Material::setShininess(float _val) {
|
||||
m_shininess = _val;
|
||||
}
|
||||
|
||||
void ege::Material::setTexture0(const etk::Uri& _uri) {
|
||||
ivec2 tmpSize(256, 256);
|
||||
if (_filename != "") {
|
||||
if (_uri.isEmpty() == false) {
|
||||
// prevent overloard error :
|
||||
ememory::SharedPtr<ewol::resource::Texture> tmpCopy = m_texture0;
|
||||
m_texture0 = ewol::resource::TextureFile::create(_filename, tmpSize);
|
||||
if (m_texture0 == nullptr) {
|
||||
EGE_ERROR("Can not load specific texture : " << _filename);
|
||||
m_texture0 = ewol::resource::TextureFile::create(_uri, tmpSize);
|
||||
if (m_texture0 == null) {
|
||||
EGE_ERROR("Can not load specific texture : " << _uri);
|
||||
// retreave previous texture:
|
||||
m_texture0 = tmpCopy;
|
||||
if (m_texture0 != nullptr) {
|
||||
if (m_texture0 != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -88,7 +109,7 @@ void ege::Material::setTexture0(const std::string& _filename) {
|
||||
void ege::Material::setTexture0Magic(const ivec2& _size) {
|
||||
// create a simple custum texture :
|
||||
m_texture0 = ewol::resource::Texture::create();
|
||||
if (m_texture0 != nullptr) {
|
||||
if (m_texture0 != null) {
|
||||
setImageSize(_size);
|
||||
egami::Image& img = m_texture0->get();
|
||||
for (int32_t xxx=0; xxx<_size.x(); ++xxx) {
|
||||
@ -104,6 +125,9 @@ void ege::Material::setTexture0Magic(const ivec2& _size) {
|
||||
enum gale::openGL::renderMode ege::Material::getRenderModeOpenGl() {
|
||||
return m_renderMode;
|
||||
}
|
||||
enum gale::openGL::renderMode ege::Material::getRenderMode() {
|
||||
return m_renderMode;
|
||||
}
|
||||
|
||||
void ege::Material::setRenderMode(enum gale::openGL::renderMode _val) {
|
||||
switch (_val) {
|
||||
@ -145,3 +169,24 @@ void ege::Material::setRenderMode(enum gale::openGL::renderMode _val) {
|
||||
m_renderMode = _val;
|
||||
}
|
||||
|
||||
void ege::Material::setImageSize(const ivec2& _newSize) {
|
||||
if (m_texture0 == null){
|
||||
return;
|
||||
}
|
||||
m_texture0->setImageSize(_newSize);
|
||||
}
|
||||
|
||||
egami::Image* ege::Material::get() {
|
||||
if (m_texture0 == null){
|
||||
return null;
|
||||
}
|
||||
return &m_texture0->get();
|
||||
}
|
||||
|
||||
void ege::Material::flush() {
|
||||
if (m_texture0 == null){
|
||||
return;
|
||||
}
|
||||
m_texture0->flush();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Vector4D.hpp>
|
||||
#include <gale/resource/Program.hpp>
|
||||
#include <ewol/resource/Image.hpp>
|
||||
#include <ewol/resource/TextureFile.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
namespace ege {
|
||||
/**
|
||||
@ -24,10 +25,8 @@ namespace ege {
|
||||
int32_t m_GL_shininess;
|
||||
int32_t m_GL_texture0;
|
||||
MaterialGlId();
|
||||
void link(ememory::SharedPtr<gale::resource::Program> _prog, const std::string& _baseName);
|
||||
void link(ememory::SharedPtr<gale::resource::Program> _prog, const etk::String& _baseName);
|
||||
};
|
||||
|
||||
|
||||
class Material {
|
||||
private:
|
||||
// values
|
||||
@ -35,54 +34,29 @@ namespace ege {
|
||||
vec4 m_diffuseFactor;
|
||||
vec4 m_specularFactor;
|
||||
float m_shininess;
|
||||
enum gale::openGL::renderMode m_renderMode; // Select Render mode (triangle/Line/point ...)
|
||||
enum gale::openGL::renderMode m_renderMode; //!< Select Render mode (triangle/Line/point ...)
|
||||
ememory::SharedPtr<ewol::resource::Texture> m_texture0;
|
||||
public:
|
||||
std::vector<uint32_t> m_listIndexFaces;
|
||||
etk::Vector<uint32_t> m_listIndexFaces;
|
||||
public:
|
||||
Material();
|
||||
~Material();
|
||||
void draw(ememory::SharedPtr<gale::resource::Program> _prog, const ege::MaterialGlId& _glID);
|
||||
void setAmbientFactor(const vec4& _val) {
|
||||
m_ambientFactor = _val;
|
||||
}
|
||||
void setDiffuseFactor(const vec4& _val) {
|
||||
m_diffuseFactor = _val;
|
||||
}
|
||||
void setSpecularFactor(const vec4& _val) {
|
||||
m_specularFactor = _val;
|
||||
}
|
||||
void setShininess(float _val) {
|
||||
m_shininess = _val;
|
||||
}
|
||||
void setAmbientFactor(const vec4& _val);
|
||||
void setDiffuseFactor(const vec4& _val);
|
||||
void setSpecularFactor(const vec4& _val);
|
||||
void setShininess(float _val);
|
||||
void setRenderMode(enum gale::openGL::renderMode _val);
|
||||
enum gale::openGL::renderMode getRenderModeOpenGl();
|
||||
enum gale::openGL::renderMode getRenderMode() {
|
||||
return m_renderMode;
|
||||
}
|
||||
void setTexture0(const std::string& _filename);
|
||||
enum gale::openGL::renderMode getRenderMode();
|
||||
void setTexture0(const etk::Uri& _uri);
|
||||
void setTexture0Magic(const ivec2& _size);
|
||||
|
||||
void setImageSize(const ivec2& _newSize) {
|
||||
if (m_texture0 == nullptr){
|
||||
return;
|
||||
}
|
||||
m_texture0->setImageSize(_newSize);
|
||||
};
|
||||
void setImageSize(const ivec2& _newSize);
|
||||
// get the reference on this image to draw nomething on it ...
|
||||
egami::Image* get() {
|
||||
if (m_texture0 == nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
return &m_texture0->get();
|
||||
};
|
||||
egami::Image* get();
|
||||
// flush the data to send it at the openGl system
|
||||
void flush() {
|
||||
if (m_texture0 == nullptr){
|
||||
return;
|
||||
}
|
||||
m_texture0->flush();
|
||||
};
|
||||
void flush();
|
||||
bool haveTexture() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/Particule.hpp>
|
||||
#include <ege/ParticuleEngine.hpp>
|
||||
|
||||
ege::Particule::Particule(ege::ParticuleEngine* _particuleEngine, const char* _particuleType) :
|
||||
m_particuleEngine(_particuleEngine),
|
||||
m_particuleType(_particuleType) {
|
||||
m_particuleEngine->add(this);
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
class ParticuleEngine;
|
||||
};
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
/**
|
||||
* @brief The particule class is an element with no control, when it will be created,
|
||||
* it does not have any control, for example smoke or reactor generation ...
|
||||
* or explosion particule ...
|
||||
*/
|
||||
class Particule {
|
||||
protected:
|
||||
ege::ParticuleEngine* m_particuleEngine;
|
||||
const char* m_particuleType;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param[in] _particuleEngine reference on the particule engine ...
|
||||
* @param[in] _particuleType Type of the particule (set nullptr if you did not want to use the respowner ...)
|
||||
*/
|
||||
Particule(ege::ParticuleEngine* _particuleEngine, const char* _particuleType = nullptr);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~Particule() { };
|
||||
/**
|
||||
* @brief init the particule
|
||||
*/
|
||||
virtual void init() { };
|
||||
/**
|
||||
* @brief Un-init the particule
|
||||
*/
|
||||
virtual void UnInit() { };
|
||||
/**
|
||||
* @brief update the paticule properties
|
||||
* @param[in] _delta Delta time from the previous call
|
||||
*/
|
||||
virtual void update(float _delta) { };
|
||||
/**
|
||||
* @brief draw the current particule
|
||||
*/
|
||||
virtual void draw(const ege::Camera& _camera) { };
|
||||
/**
|
||||
* @brief Check if the element might be removed
|
||||
* @return true : The element might be removed
|
||||
* @return false : The element might be keeped
|
||||
*/
|
||||
virtual bool needRemove() {
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* @brief get the type of the particule
|
||||
* @return Type of the current particule
|
||||
*/
|
||||
const char* getParticuleType() {
|
||||
return m_particuleType;
|
||||
};
|
||||
/**
|
||||
* @brief When the particule arrive to his end of life, this function is called.
|
||||
*/
|
||||
virtual void onEnd() {};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,137 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/ParticuleEngine.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/Particule.hpp>
|
||||
|
||||
ege::ParticuleEngine::ParticuleEngine(ege::Environement* _env) :
|
||||
m_env(_env) {
|
||||
|
||||
}
|
||||
|
||||
ege::ParticuleEngine::~ParticuleEngine() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void ege::ParticuleEngine::add(Particule* _particule) {
|
||||
if (_particule == nullptr) {
|
||||
EGE_ERROR("Try to add particule nullptr");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] != nullptr) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii] = _particule;
|
||||
return;
|
||||
}
|
||||
// Just add it at the end ...
|
||||
m_particuleList.push_back(_particule);
|
||||
}
|
||||
|
||||
void ege::ParticuleEngine::addRemoved(Particule* _particule) {
|
||||
if (_particule == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] != nullptr) {
|
||||
continue;
|
||||
}
|
||||
m_particuleRemoved[iii] = _particule;
|
||||
return;
|
||||
}
|
||||
// Just add it at the end ...
|
||||
m_particuleRemoved.push_back(_particule);
|
||||
}
|
||||
|
||||
ege::Particule* ege::ParticuleEngine::respown(const char* _particuleType) {
|
||||
if (_particuleType == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (m_particuleRemoved[iii]->getParticuleType() == _particuleType) {
|
||||
add(m_particuleRemoved[iii]);
|
||||
ege::Particule* tmpParticule = m_particuleRemoved[iii];
|
||||
m_particuleRemoved[iii]=nullptr;
|
||||
tmpParticule->init();
|
||||
return tmpParticule;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ege::ParticuleEngine::update(float _deltaTime) {
|
||||
if (_deltaTime>(1.0f/60.0f)) {
|
||||
_deltaTime = (1.0f/60.0f);
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii]->update(_deltaTime);
|
||||
}
|
||||
// check removing elements
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (m_particuleList[iii]->needRemove()) {
|
||||
m_particuleList[iii]->onEnd();
|
||||
if (m_particuleList[iii]->getParticuleType() == nullptr) {
|
||||
// Real remove particule ...
|
||||
delete (m_particuleList[iii]);
|
||||
} else {
|
||||
addRemoved(m_particuleList[iii]);
|
||||
}
|
||||
m_particuleList[iii] = nullptr;
|
||||
}
|
||||
}
|
||||
/*
|
||||
int32_t nbParticule = 0;
|
||||
for (int32_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
nbParticule++;
|
||||
}
|
||||
EGE_DEBUG("number of particule : " << nbParticule);
|
||||
*/
|
||||
}
|
||||
|
||||
void ege::ParticuleEngine::draw(const ege::Camera& _camera) {
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii]->draw(_camera);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::ParticuleEngine::clear() {
|
||||
// clear element not removed
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
delete m_particuleList[iii];
|
||||
m_particuleList[iii] = nullptr;
|
||||
}
|
||||
m_particuleList.clear();
|
||||
// clear element that are auto-removed
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
delete m_particuleRemoved[iii];
|
||||
m_particuleRemoved[iii] = nullptr;
|
||||
}
|
||||
m_particuleRemoved.clear();
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
namespace ege {
|
||||
class Environement;
|
||||
class Particule;
|
||||
};
|
||||
#include <etk/types.hpp>
|
||||
#include <vector>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
|
||||
namespace ege {
|
||||
class ParticuleEngine {
|
||||
private:
|
||||
ege::Environement* m_env;
|
||||
public:
|
||||
ParticuleEngine(ege::Environement* _env); // note : need the engine to register has an dynamic element ... (the first ...)
|
||||
~ParticuleEngine();
|
||||
private:
|
||||
std::vector<Particule*> m_particuleList; //!< all particule created and active
|
||||
std::vector<Particule*> m_particuleRemoved; //!< removed particule
|
||||
public:
|
||||
/**
|
||||
* @brief clear the particule engine
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief add a particule in the engine (internal acces only)
|
||||
* @param[in] _particule Pointer on the particule to add
|
||||
*/
|
||||
void add(Particule* _particule);
|
||||
private:
|
||||
/**
|
||||
* @brief add a particule in the removed section == > this not delete the particule, but just set it in an other list
|
||||
* @param[in] _particule Pointer on the particule to add
|
||||
*/
|
||||
void addRemoved(Particule* _particule);
|
||||
public:
|
||||
/**
|
||||
* @brief update particule properties
|
||||
* @param[in] _deltaTime delta time to process
|
||||
*/
|
||||
void update(float _deltaTime);
|
||||
/**
|
||||
* @brief draw all the active Particule
|
||||
* @param[in] _camera Reference on the current camera
|
||||
*/
|
||||
void draw(const ege::Camera& _camera);
|
||||
/**
|
||||
* @brief get a particue with his type, we get particule that has been already removed, otherwise, you will create new
|
||||
* @param[in] _particuleType Particule type, this chek only the pointer not the data.
|
||||
* @return nullptr, the particule has not been removed from the created pool
|
||||
* @return The pointer on the requested element (an init has been done).
|
||||
* @note If you did not want to use respawn set type at nullptr.
|
||||
*/
|
||||
Particule* respown(const char* _particuleType);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,65 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/ParticuleSimple.hpp>
|
||||
|
||||
ege::ParticuleSimple::ParticuleSimple(ege::ParticuleEngine* _particuleEngine, const char* _particuleType) :
|
||||
Particule(_particuleEngine, _particuleType) {
|
||||
init();
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::init() {
|
||||
m_lifeFull = 3;
|
||||
m_life = m_lifeFull;
|
||||
m_level = 0;
|
||||
m_pos = vec3(0,0,0);
|
||||
m_angle = 0;
|
||||
m_speed = vec3(0,0,0);
|
||||
m_scale = vec3(1,1,1);
|
||||
m_scaleExpand = vec3(0,0,0);
|
||||
}
|
||||
|
||||
bool ege::ParticuleSimple::needRemove() {
|
||||
return m_life<0.0f;
|
||||
}
|
||||
|
||||
|
||||
void ege::ParticuleSimple::update(float _delta) {
|
||||
//EGE_DEBUG("Life : " << m_life << "-" << _delta);
|
||||
m_life -= _delta;
|
||||
m_pos += m_speed*_delta;
|
||||
m_scale += m_scaleExpand*_delta;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setLife(float _life) {
|
||||
m_lifeFull = _life;
|
||||
m_life = m_lifeFull;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setLevel(float _level) {
|
||||
m_level = _level;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setPosition(const vec3& _pos) {
|
||||
m_pos = _pos;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setAngle(float _angle) {
|
||||
m_angle = _angle;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setMoveSpeed(const vec3& _speed) {
|
||||
m_speed = _speed;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setScale(const vec3& _scale) {
|
||||
m_scale = _scale;
|
||||
}
|
||||
|
||||
void ege::ParticuleSimple::setScaleExpend(const vec3& _scaleExpand) {
|
||||
m_scaleExpand=_scaleExpand;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
class ParticuleSimple;
|
||||
};
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector2D.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Vector4D.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/Particule.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
/**
|
||||
* @brief The particule class is an element with no control, when it will be created,
|
||||
* it does not have any control, for example smoke or reactor generation ...
|
||||
* or explosion particule ...
|
||||
*/
|
||||
class ParticuleSimple : public Particule {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param[in] _name Name of the particule.
|
||||
* @param[in] _standalone The particule are created and have there own life (no dynamic control)
|
||||
*/
|
||||
ParticuleSimple(ege::ParticuleEngine* _particuleEngine, const char* _particuleType);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~ParticuleSimple() { };
|
||||
public: // herited elements:
|
||||
virtual void update(float _delta);
|
||||
//virtual void draw() { };
|
||||
virtual bool needRemove();
|
||||
virtual void init();
|
||||
protected:
|
||||
float m_lifeFull;
|
||||
float m_life;
|
||||
float m_level;
|
||||
vec3 m_pos;
|
||||
float m_angle;
|
||||
vec3 m_speed;
|
||||
vec3 m_scale;
|
||||
vec3 m_scaleExpand;
|
||||
public:
|
||||
/**
|
||||
*
|
||||
*/
|
||||
virtual void setLife(float _life);
|
||||
virtual void setLevel(float _level);
|
||||
virtual void setPosition(const vec3& _pos);
|
||||
virtual void setAngle(float _angle);
|
||||
virtual void setMoveSpeed(const vec3& _speed);
|
||||
virtual void setScale(const vec3& _scale);
|
||||
virtual void setScaleExpend(const vec3& _scaleExpand);
|
||||
};
|
||||
}
|
||||
|
||||
|
51
ege/Ray.cpp
51
ege/Ray.cpp
@ -1,15 +1,14 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/Ray.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/elements/Element.hpp>
|
||||
#include <ege/Entity.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||
|
||||
ege::Ray::Ray(const vec3& _origin, const vec3& _direction) :
|
||||
m_origin(_origin),
|
||||
@ -28,7 +27,7 @@ void ege::Ray::setDirection(const vec3& _direction) {
|
||||
|
||||
|
||||
|
||||
std::ostream& ege::operator <<(std::ostream& _os, const ege::Ray& _obj) {
|
||||
etk::Stream& ege::operator <<(etk::Stream& _os, const ege::Ray& _obj) {
|
||||
_os << "{ori=";
|
||||
_os << _obj.getOrigin();
|
||||
_os << " dir=";
|
||||
@ -37,48 +36,6 @@ std::ostream& ege::operator <<(std::ostream& _os, const ege::Ray& _obj) {
|
||||
return _os;
|
||||
}
|
||||
|
||||
std::pair<vec3,vec3> ege::Ray::testRay(ege::physics::Engine& _engine) {
|
||||
vec3 start = m_origin;
|
||||
vec3 stop = m_origin+m_direction*1000.0f;
|
||||
// Start and End are vectors
|
||||
btCollisionWorld::ClosestRayResultCallback rayCallback(start, stop);
|
||||
EGE_VERBOSE("Process Raycast :");
|
||||
// Perform raycast
|
||||
_engine.getDynamicWorld()->rayTest(start, stop, rayCallback);
|
||||
if(rayCallback.hasHit()) {
|
||||
vec3 end = rayCallback.m_hitPointWorld;
|
||||
vec3 normal = rayCallback.m_hitNormalWorld;
|
||||
EGE_VERBOSE(" hit at point=" << end << " normal=" << normal);
|
||||
return std::pair<vec3,vec3>(end,normal);
|
||||
}
|
||||
EGE_VERBOSE(" No Hit");
|
||||
return std::pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0));
|
||||
}
|
||||
|
||||
|
||||
std::pair<ememory::SharedPtr<ege::Element>, std::pair<vec3,vec3>> ege::Ray::testRayObject(ege::physics::Engine& _engine) {
|
||||
vec3 start = m_origin;
|
||||
vec3 stop = m_origin+m_direction*1000.0f;
|
||||
// Start and End are vectors
|
||||
btCollisionWorld::ClosestRayResultCallback rayCallback(start, stop);
|
||||
EGE_VERBOSE("Process Raycast :");
|
||||
// Perform raycast
|
||||
_engine.getDynamicWorld()->rayTest(start, stop, rayCallback);
|
||||
if(rayCallback.hasHit()) {
|
||||
vec3 end = rayCallback.m_hitPointWorld;
|
||||
vec3 normal = rayCallback.m_hitNormalWorld;
|
||||
ege::Element* elem = static_cast<ege::Element*>(rayCallback.m_collisionObject->getUserPointer());
|
||||
if (elem != nullptr) {
|
||||
EGE_VERBOSE(" hit at point=" << end << " normal=" << normal);
|
||||
return std::pair<ememory::SharedPtr<ege::Element>, std::pair<vec3,vec3>>(elem->sharedFromThis(), std::pair<vec3,vec3>(end,normal));
|
||||
}
|
||||
EGE_VERBOSE(" Can not get the element pointer");
|
||||
return std::pair<ememory::SharedPtr<ege::Element>, std::pair<vec3,vec3>>(nullptr, std::pair<vec3,vec3>(end,normal));
|
||||
} else {
|
||||
EGE_VERBOSE(" No Hit");
|
||||
}
|
||||
return std::pair<ememory::SharedPtr<ege::Element>, std::pair<vec3,vec3>>(nullptr, std::pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0)));
|
||||
}
|
||||
|
||||
vec3 ege::Ray::testRayZeroPlane() {
|
||||
float coef = m_origin.z() / m_direction.z();
|
||||
|
@ -1,14 +1,14 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
namespace ege {
|
||||
class Ray;
|
||||
class Element;
|
||||
class Entity;
|
||||
};
|
||||
#include <ege/physics/Engine.hpp>
|
||||
#include <ememory/memory.hpp>
|
||||
@ -64,10 +64,8 @@ namespace ege {
|
||||
*/
|
||||
void set(const vec3& _origin, const vec3& _direction);
|
||||
public:
|
||||
std::pair<vec3,vec3> testRay(ege::physics::Engine& _engine);
|
||||
std::pair<ememory::SharedPtr<ege::Element>, std::pair<vec3,vec3>> testRayObject(ege::physics::Engine& _engine);
|
||||
vec3 testRayZeroPlane();
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, const ege::Ray& _obj);
|
||||
etk::Stream& operator <<(etk::Stream& _os, const ege::Ray& _obj);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/Ray.hpp>
|
||||
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
|
||||
@ -78,15 +79,15 @@ vec2 ege::Camera::tansformPositionToAngle(vec3 _vect) {
|
||||
if (distance == 0.0f) {
|
||||
return out;
|
||||
}
|
||||
out.setY(std::asin(_vect.z()/distance));
|
||||
out.setY(etk::asin(_vect.z()/distance));
|
||||
_vect.setZ(0.0f);
|
||||
if (_vect.x() == 0 && _vect.y() == 0) {
|
||||
return out;
|
||||
}
|
||||
_vect.normalize();
|
||||
out.setX(std::asin(_vect.y()));
|
||||
out.setX(etk::asin(_vect.y()));
|
||||
if (_vect.x() < 0) {
|
||||
out.setX(out.x()*-1 - M_PI);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -9,12 +9,13 @@
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Vector2D.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <ege/Ray.hpp>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
//#include <ege/Ray.hpp>
|
||||
#include <ewol/resource/Colored3DObject.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class Ray;
|
||||
class Camera : public ememory::EnableSharedFromThis<Camera>{
|
||||
public:
|
||||
/**
|
||||
|
186
ege/camera/ControlBase.cpp
Normal file
186
ege/camera/ControlBase.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#include <ewol/object/Object.hpp>
|
||||
#include <ewol/object/Manager.hpp>
|
||||
#include <ege/camera/ControlBase.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
|
||||
ege::camera::ControlBase::ControlBase() :
|
||||
m_destinationCameraOffset(0,0,0),
|
||||
m_angleTetha(0.0f),
|
||||
m_anglePsy(0.0f),
|
||||
m_distance(1.0f) {
|
||||
|
||||
}
|
||||
|
||||
void ege::camera::ControlBase::setCamera(const ememory::SharedPtr<ege::camera::View>& _camera) {
|
||||
m_camera.reset();
|
||||
m_PCH.disconnect();
|
||||
if (_camera == null) {
|
||||
return;
|
||||
}
|
||||
m_camera = _camera;
|
||||
m_camera->setTarget(vec3(0,0,0));
|
||||
m_camera->setEye(vec3(100*etk::sin(m_angleTetha),100*etk::cos(m_angleTetha),80*etk::cos(m_anglePsy))*m_distance);
|
||||
m_PCH = ewol::Object::getObjectManager().periodicCall.connect(this, &ege::camera::ControlBase::periodicCall);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ege::camera::ControlBase::onEventEntry(const ewol::event::Entry& _event) {
|
||||
if (_event.getType() == gale::key::keyboard::left) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset += vec3(1,0,0);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset -= vec3(1,0,0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::right) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset -= vec3(1,0,0);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset += vec3(1,0,0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::up) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset += vec3(0,1,0);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset -= vec3(0,1,0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::down) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset -= vec3(0,1,0);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset += vec3(0,1,0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::pageUp) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset += vec3(0,0,1);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset -= vec3(0,0,1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::pageDown) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_destinationCameraOffset -= vec3(0,0,1);
|
||||
} else if (_event.getStatus() == gale::key::status::up) {
|
||||
m_destinationCameraOffset += vec3(0,0,1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::start) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_camera->setAngle(m_camera->getAngle() + 0.01f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::end) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_camera->setAngle(m_camera->getAngle() - 0.01f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_event.getType() == gale::key::keyboard::insert) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_camera->setXAngleView(m_camera->getXAngleView() + 0.01f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ( _event.getType() == gale::key::keyboard::character
|
||||
&& _event.getChar() == u32char::Suppress) {
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_camera->setXAngleView(m_camera->getXAngleView() - 0.01f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ege::camera::ControlBase::onEventInput(const ewol::event::Input& _event, const vec2& _relativePosition) {
|
||||
if (m_camera == null) {
|
||||
return false;
|
||||
}
|
||||
if (_event.getId() == 4) {
|
||||
// scrool button ==> zoom in
|
||||
m_distance += 0.01f;
|
||||
m_camera->setEye(vec3(100*etk::sin(m_angleTetha),100*etk::cos(m_angleTetha),80*etk::cos(m_anglePsy))*m_distance);
|
||||
return true;
|
||||
} else if (_event.getId() == 5) {
|
||||
// scrool button ==> zoom OUT
|
||||
m_distance -= 0.01f;
|
||||
if (m_distance <= 0.05f) {
|
||||
m_distance = 0.05f;
|
||||
}
|
||||
m_camera->setEye(vec3(100*etk::sin(m_angleTetha),100*etk::cos(m_angleTetha),80*etk::cos(m_anglePsy))*m_distance);
|
||||
return true;
|
||||
} else if (_event.getId() == 3) {
|
||||
// Middle button ==> move around the target position
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_oldScreenPos = _relativePosition;
|
||||
} else if (_event.getStatus() == gale::key::status::move) {
|
||||
vec2 pos = _relativePosition;
|
||||
m_angleTetha += (m_oldScreenPos.x()-pos.x())*0.02f;
|
||||
m_anglePsy += (m_oldScreenPos.y()-pos.y())*0.01f;
|
||||
m_camera->setEye(m_camera->getTarget() + vec3(100*etk::sin(m_angleTetha),100*etk::cos(m_angleTetha),80*etk::cos(m_anglePsy))*m_distance);
|
||||
m_oldScreenPos = _relativePosition;
|
||||
}
|
||||
return true;
|
||||
} else if (_event.getId() == 2) {
|
||||
// Middle button ==> move the camera view axis
|
||||
if (_event.getStatus() == gale::key::status::down) {
|
||||
m_oldScreenPos = _relativePosition;
|
||||
} else if (_event.getStatus() == gale::key::status::move) {
|
||||
vec2 pos = _relativePosition*0.2;
|
||||
pos -= m_oldScreenPos*0.2;
|
||||
float cameraAngle = m_camera->getTetha();
|
||||
vec3 newPos = vec3(etk::sin(cameraAngle)*pos.x() + etk::cos(cameraAngle)*pos.y(),
|
||||
etk::cos(cameraAngle)*pos.x() + etk::sin(cameraAngle)*pos.y(),
|
||||
0);
|
||||
EGE_ERROR("apply offset = " << newPos << " from pos=" << pos << " angle=" << cameraAngle);
|
||||
newPos += m_camera->getTarget();
|
||||
newPos.setMin(vec3(200,200,200));
|
||||
newPos.setMax(vec3(-200,-200,-200));
|
||||
m_camera->setTarget(newPos);
|
||||
m_oldScreenPos = _relativePosition;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ege::camera::ControlBase::periodicCall(const ewol::event::Time& _event) {
|
||||
if (m_camera == null) {
|
||||
return;
|
||||
}
|
||||
if ( m_destinationCameraOffset.x() < 0.7f
|
||||
&& m_destinationCameraOffset.x() > -0.7f) {
|
||||
m_destinationCameraOffset.setX(0.0f);
|
||||
}
|
||||
if ( m_destinationCameraOffset.y() < 0.7f
|
||||
&& m_destinationCameraOffset.y() > -0.7f) {
|
||||
m_destinationCameraOffset.setY(0.0f);
|
||||
}
|
||||
if ( m_destinationCameraOffset.z() < 0.7f
|
||||
&& m_destinationCameraOffset.z() > -0.7f) {
|
||||
m_destinationCameraOffset.setZ(0.0f);
|
||||
}
|
||||
float delta = _event.getDeltaCall();
|
||||
vec3 tmp = m_destinationCameraOffset * delta * 30.0f;
|
||||
m_camera->setTarget(m_camera->getTarget() + tmp);
|
||||
m_camera->setEye(m_camera->getEye() + tmp);
|
||||
}
|
||||
|
46
ege/camera/ControlBase.hpp
Normal file
46
ege/camera/ControlBase.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/camera/View.hpp>
|
||||
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <ewol/event/Entry.hpp>
|
||||
#include <ewol/event/Input.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace camera {
|
||||
/**
|
||||
* The control position of the camera is principali a basic camera control to prototype an idea ...
|
||||
*/
|
||||
class ControlBase {
|
||||
protected:
|
||||
vec3 m_destinationCameraOffset;
|
||||
float m_angleTetha;
|
||||
float m_anglePsy;
|
||||
float m_distance;
|
||||
vec2 m_oldScreenPos;
|
||||
esignal::Connection m_PCH; //!< Periodic Call Handle to remove it when needed
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*/
|
||||
ControlBase();
|
||||
private:
|
||||
ememory::SharedPtr<ege::camera::View> m_camera;
|
||||
public:
|
||||
void setCamera(const ememory::SharedPtr<ege::camera::View>& _camera);
|
||||
bool onEventEntry(const ewol::event::Entry& _event);
|
||||
bool onEventInput(const ewol::event::Input& _event, const vec2& _relativePosition);
|
||||
/**
|
||||
* @brief Periodic call to update grapgic display
|
||||
* @param[in] _event Time generic event
|
||||
*/
|
||||
void periodicCall(const ewol::event::Time& _event);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,27 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#include <ege/camera/View.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <ege/Ray.hpp>
|
||||
|
||||
void ege::camera::View::update() {
|
||||
//m_matrix = etk::matLookAt(m_eye, m_target, m_up);
|
||||
/*
|
||||
vec3 m_up(0,0,1);
|
||||
m_matrix = etk::matLookAt(m_eye, m_target, m_up);
|
||||
//m_matrix.transpose();
|
||||
//m_matrix.translate(m_eye);
|
||||
*/
|
||||
// The camera view to the-z axis ...
|
||||
m_matrix.identity();
|
||||
// basic camera rotation
|
||||
m_matrix.rotate(vec3(0,0,1), -m_angle);
|
||||
|
||||
vec3 pos = -getViewVector();
|
||||
vec2 angles = tansformPositionToAngle(pos);
|
||||
float distance = pos.length();
|
||||
@ -22,11 +30,10 @@ void ege::camera::View::update() {
|
||||
m_matrix.rotate(vec3(1,0,0), -M_PI*0.5f + angles.y());
|
||||
m_matrix.rotate(vec3(0,0,1), -angles.x()-M_PI/2.0f);
|
||||
m_matrix.translate(-m_target);
|
||||
|
||||
EGE_DEBUG("Camera properties : distance=" << distance );
|
||||
EGE_DEBUG(" psy=" << angles.y());
|
||||
EGE_DEBUG(" Tetha=" << angles.x());
|
||||
EGE_DEBUG(" m_eye=" << etk::to_string(m_eye));
|
||||
EGE_DEBUG(" m_eye=" << m_eye);
|
||||
}
|
||||
|
||||
ege::camera::View::View(const vec3& _eye, const vec3& _target, float _angle) :
|
||||
@ -67,7 +74,6 @@ ege::Ray ege::camera::View::getRayFromScreen(const vec2& _offset) {
|
||||
vec2 cameraAngleOffset(m_angleView*0.5f*_offset.x(), _offset.y()*0.5f*m_angleView/m_aspectRatio);
|
||||
#if 1
|
||||
// It is not the best way to create the ray but it work . (My knowlege is not enought now ...)
|
||||
mat4 inverse = m_matrix.invert();
|
||||
vec3 screenOffset(0,0,-1);
|
||||
screenOffset = screenOffset.rotate(vec3(0,1,0), cameraAngleOffset.x());
|
||||
screenOffset = screenOffset.rotate(vec3(1,0,0), -cameraAngleOffset.y());
|
||||
@ -90,36 +96,38 @@ ege::Ray ege::camera::View::getRayFromScreen(const vec2& _offset) {
|
||||
return out;
|
||||
}
|
||||
|
||||
void ege::camera::View::drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
mat4 mat;
|
||||
if (_camera != sharedFromThis()) {
|
||||
#ifndef __TARGET_OS__Web
|
||||
void ege::camera::View::drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
mat4 mat;
|
||||
if (_camera != sharedFromThis()) {
|
||||
mat.identity();
|
||||
vec2 angles = tansformPositionToAngle(-getViewVector());
|
||||
mat.rotate(vec3(0,0,1), angles.x() - M_PI/2.0f);
|
||||
mat.rotate(vec3(1,0,0), -M_PI*0.5f + angles.y());
|
||||
mat.translate(vec3(0,0,getViewVector().length()));
|
||||
mat.rotate(vec3(0,0,1), m_angle);
|
||||
//mat.translate(vec3(m_eye.x(), m_eye.y(), m_eye.z()));
|
||||
_draw->drawSquare(vec3(2,2,2), mat, etk::Color<float>(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
etk::Vector<vec3> EwolVertices;
|
||||
EwolVertices.pushBack(vec3(0,0,0));
|
||||
EwolVertices.pushBack(vec3(-5,-5,-5));
|
||||
EwolVertices.pushBack(vec3(5,-5,-5));
|
||||
|
||||
EwolVertices.pushBack(vec3(0,0,0));
|
||||
EwolVertices.pushBack(vec3(5,-5,-5));
|
||||
EwolVertices.pushBack(vec3(5,5,-5));
|
||||
|
||||
EwolVertices.pushBack(vec3(0,0,0));
|
||||
EwolVertices.pushBack(vec3(5,5,-5));
|
||||
EwolVertices.pushBack(vec3(-5,5,-5));
|
||||
|
||||
EwolVertices.pushBack(vec3(0,0,0));
|
||||
EwolVertices.pushBack(vec3(-5,5,-5));
|
||||
EwolVertices.pushBack(vec3(-5,-5,-5));
|
||||
_draw->draw(EwolVertices, etk::Color<float>(0.0f, 0.0f, 1.0f, 0.5f), mat);
|
||||
}
|
||||
mat.identity();
|
||||
vec2 angles = tansformPositionToAngle(-getViewVector());
|
||||
mat.rotate(vec3(0,0,1), angles.x() - M_PI/2.0f);
|
||||
mat.rotate(vec3(1,0,0), -M_PI*0.5f + angles.y());
|
||||
mat.translate(vec3(0,0,getViewVector().length()));
|
||||
mat.rotate(vec3(0,0,1), m_angle);
|
||||
//mat.translate(vec3(m_eye.x(), m_eye.y(), m_eye.z()));
|
||||
_draw->drawSquare(vec3(2,2,2), mat, etk::Color<float>(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
std::vector<vec3> EwolVertices;
|
||||
EwolVertices.push_back(vec3(0,0,0));
|
||||
EwolVertices.push_back(vec3(-5,-5,-5));
|
||||
EwolVertices.push_back(vec3(5,-5,-5));
|
||||
|
||||
EwolVertices.push_back(vec3(0,0,0));
|
||||
EwolVertices.push_back(vec3(5,-5,-5));
|
||||
EwolVertices.push_back(vec3(5,5,-5));
|
||||
|
||||
EwolVertices.push_back(vec3(0,0,0));
|
||||
EwolVertices.push_back(vec3(5,5,-5));
|
||||
EwolVertices.push_back(vec3(-5,5,-5));
|
||||
|
||||
EwolVertices.push_back(vec3(0,0,0));
|
||||
EwolVertices.push_back(vec3(-5,5,-5));
|
||||
EwolVertices.push_back(vec3(-5,-5,-5));
|
||||
_draw->draw(EwolVertices, etk::Color<float>(0.0f, 0.0f, 1.0f, 0.5f), mat);
|
||||
mat.translate(m_target);
|
||||
_draw->drawSphere(1, 3, 3, mat, etk::Color<float>(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
}
|
||||
mat.identity();
|
||||
mat.translate(m_target);
|
||||
_draw->drawSphere(1, 3, 3, mat, etk::Color<float>(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2013, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -73,7 +73,9 @@ namespace ege {
|
||||
virtual vec3 getViewVector() const;
|
||||
public:
|
||||
virtual ege::Ray getRayFromScreen(const vec2& _offset);
|
||||
#ifndef __TARGET_OS__Web
|
||||
virtual void drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
#endif
|
||||
virtual float getTetha();
|
||||
virtual float getPsy();
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -12,6 +12,7 @@ namespace ege {
|
||||
};
|
||||
#define EGE_BASE(info,data) ELOG_BASE(ege::getLogId(),info,data)
|
||||
|
||||
#define EGE_PRINT(data) EGE_BASE(-1, data)
|
||||
#define EGE_CRITICAL(data) EGE_BASE(1, data)
|
||||
#define EGE_ERROR(data) EGE_BASE(2, data)
|
||||
#define EGE_WARNING(data) EGE_BASE(3, data)
|
||||
|
@ -1,189 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/elements/Element.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <LinearMath/btTransformUtil.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
|
||||
#include <ege/CollisionShapeCreator.hpp>
|
||||
|
||||
|
||||
const std::string& ege::Element::getType() const {
|
||||
static const std::string nameType("----");
|
||||
return nameType;
|
||||
}
|
||||
|
||||
|
||||
ege::Element::Element(const ememory::SharedPtr<ege::Environement>& _env) :
|
||||
m_env(_env),
|
||||
m_uID(0),
|
||||
m_mesh(),
|
||||
m_life(100),
|
||||
m_lifeMax(100),
|
||||
m_group(0),
|
||||
m_fixe(true),
|
||||
m_radius(0) {
|
||||
static uint32_t unique=0;
|
||||
m_uID = unique;
|
||||
EGE_DEBUG("Create element: uId=" << m_uID);
|
||||
m_debugText.setFontSize(12);
|
||||
unique++;
|
||||
}
|
||||
|
||||
ege::Element::~Element() {
|
||||
EGE_DEBUG("Destroy element: uId=" << m_uID);
|
||||
}
|
||||
|
||||
|
||||
bool ege::Element::init() {
|
||||
EGE_WARNING("init() not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Element::initString(const std::string& _description) {
|
||||
EGE_WARNING("String Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Element::initXML(const exml::Node& _node) {
|
||||
EGE_WARNING("xml Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Element::initJSON(const ejson::Value& _value) {
|
||||
EGE_WARNING("JSON Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Element::initVoid(void* _value) {
|
||||
EGE_WARNING("joid* Init not implemented: uId=" << m_uID);
|
||||
return false;
|
||||
}
|
||||
bool ege::Element::unInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ege::Element::loadMesh(const std::string& _meshFileName) {
|
||||
ememory::SharedPtr<ege::resource::Mesh> tmpMesh = ege::resource::Mesh::create(_meshFileName);
|
||||
if(tmpMesh == nullptr) {
|
||||
EGE_ERROR("can not load the resources : " << _meshFileName);
|
||||
return false;
|
||||
}
|
||||
return setMesh(tmpMesh);
|
||||
}
|
||||
|
||||
bool ege::Element::setMesh(ememory::SharedPtr<ege::resource::Mesh> _mesh) {
|
||||
if (m_mesh != nullptr) {
|
||||
m_mesh.reset();
|
||||
}
|
||||
m_mesh = _mesh;
|
||||
// auto load the shape :
|
||||
if (m_mesh == nullptr) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
float ege::Element::getLifeRatio() {
|
||||
if (0 >= m_life) {
|
||||
return 0;
|
||||
}
|
||||
return m_life/m_lifeMax;
|
||||
}
|
||||
|
||||
void ege::Element::setFireOn(int32_t _groupIdSource, int32_t _type, float _power, const vec3& _center) {
|
||||
float previousLife = m_life;
|
||||
m_life += _power;
|
||||
m_life = std::avg(0.0f, m_life, m_lifeMax);
|
||||
if (m_life <= 0) {
|
||||
EGE_DEBUG("[" << getUID() << "] element is killed ..." << getType());
|
||||
}
|
||||
if (m_life != previousLife) {
|
||||
onLifeChange();
|
||||
}
|
||||
}
|
||||
|
||||
const vec3& ege::Element::getPosition() {
|
||||
// this is to prevent error like segmentation fault ...
|
||||
static vec3 emptyPosition(-1000000,-1000000,-1000000);
|
||||
return emptyPosition;
|
||||
};
|
||||
|
||||
|
||||
const float lifeBorder = 0.1f;
|
||||
const float lifeHeight = 0.3f;
|
||||
const float lifeWidth = 2.0f;
|
||||
const float lifeYPos = 1.7f;
|
||||
|
||||
void ege::Element::drawLife(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
if (_draw == nullptr) {
|
||||
return;
|
||||
}
|
||||
float ratio = getLifeRatio();
|
||||
if (ratio == 1.0f) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
mat4 transformationMatrix = etk::matTranslate(getPosition())
|
||||
* etk::matRotate(vec3(0,0,1),_camera.getAngleZ())
|
||||
* etk::matRotate(vec3(1,0,0),(M_PI/2.0f-_camera.getAngleTeta()));
|
||||
std::vector<vec3> localVertices;
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.push_back(vec3( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
|
||||
localVertices.push_back(vec3( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
|
||||
localVertices.push_back(vec3( lifeWidth/2.0+lifeBorder,lifeYPos -lifeBorder,0));
|
||||
etk::Color<float> myColor(0x0000FF99);
|
||||
_draw->draw(localVertices, myColor, transformationMatrix, false, false);
|
||||
localVertices.clear();
|
||||
/** Bounding box == > model shape **/
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0 ,lifeYPos,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0 ,lifeYPos + lifeHeight,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0 ,lifeYPos,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
|
||||
localVertices.push_back(vec3(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos,0));
|
||||
myColor =0x00FF00FF;
|
||||
if (ratio < 0.2f) {
|
||||
myColor = 0xFF0000FF;
|
||||
} else if (ratio < 0.4f) {
|
||||
myColor = 0xDA7B00FF;
|
||||
}
|
||||
_draw->draw(localVertices, myColor, transformationMatrix, false, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ege::Element::drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
m_debugText.clear();
|
||||
m_debugText.setColor(etk::Color<>(0x00, 0xFF, 0x00, 0xFF));
|
||||
m_debugText.setPos(vec3(-20,32,0));
|
||||
m_debugText.print(getType());
|
||||
m_debugText.setPos(vec3(-20,20,0));
|
||||
m_debugText.print("life=("+etk::to_string(getLifeRatio()));
|
||||
//m_debugText.print(std::string("Axe=(")+std::string(m_tmpAxe.x())+std::string(",")+etk::UString(m_tmpAxe.y())+etk::UString(",")+etk::UString(m_tmpAxe.z())+etk::UString(")"));
|
||||
/*
|
||||
m_debugText.draw( etk::matTranslate(getPosition())
|
||||
* etk::matRotate(vec3(0,0,1),_camera.getAngleZ())
|
||||
* etk::matRotate(vec3(1,0,0),(M_PI/2.0f-_camera.getAngleTeta()))
|
||||
* etk::matScale(vec3(0.05,0.05,0.05)));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,231 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <vector>
|
||||
#include <ewol/debug.hpp>
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <ewol/resource/Colored3DObject.hpp>
|
||||
#include <ege/resource/Mesh.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <ewol/compositing/Text.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
|
||||
#define INDEX_RIGHT_AXIS (0)
|
||||
#define INDEX_FORWARD_AXIS (1)
|
||||
#define INDEX_UP_AXIS (2)
|
||||
|
||||
#define ELEMENT_SCALE (1.0f/8.0f)
|
||||
|
||||
namespace ege {
|
||||
class Element : public ememory::EnableSharedFromThis<Element> {
|
||||
protected:
|
||||
ememory::SharedPtr<ege::Environement> m_env;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor (when constructer is called just add element that did not change.
|
||||
* The objest will be stored in a pool of element and keep a second time if needed == > redure memory allocation,
|
||||
* when needed, the system will call the init and un-init function...
|
||||
*/
|
||||
Element(const ememory::SharedPtr<ege::Environement>& _env);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Element();
|
||||
/**
|
||||
* @brief get the element Type description string.
|
||||
* @return A reference on the descriptive string.
|
||||
*/
|
||||
virtual const std::string& getType() const;
|
||||
/**
|
||||
* @brief init the element with the defined properties
|
||||
* @param[in] _property Type of the next element
|
||||
* @param[in] _value pointer on the value type
|
||||
* @return true, the element is corectly initialized.
|
||||
*/
|
||||
virtual bool init();
|
||||
virtual bool initString(const std::string& _description);
|
||||
virtual bool initXML(const exml::Node& _node);
|
||||
virtual bool initJSON(const ejson::Value& _value);
|
||||
virtual bool initVoid(void* _value);
|
||||
virtual bool unInit();
|
||||
private:
|
||||
uint32_t m_uID; //!< This is a reference on a basic element ID
|
||||
public:
|
||||
/**
|
||||
* @brief get the curent Element Unique ID in the all Game.
|
||||
* @return The requested Unique ID.
|
||||
*/
|
||||
inline uint32_t getUID() const {
|
||||
return m_uID;
|
||||
};
|
||||
protected:
|
||||
ememory::SharedPtr<ege::resource::Mesh> m_mesh; //!< Mesh of the Element (can be nullptr)
|
||||
public:
|
||||
/**
|
||||
* @brief Select a mesh with a specific name.
|
||||
* @param[in] _meshFileName filename of the Mesh.
|
||||
* @note Automaticly load the shape if it is specify in the mesh file
|
||||
* @return true if no error occured
|
||||
*/
|
||||
virtual bool loadMesh(const std::string& _meshFileName);
|
||||
/**
|
||||
* @brief set the the Mesh properties.
|
||||
* @param[in] _mesh The mesh pointer. (nullptr to force the mesh remove ...)
|
||||
* @note : this remove the shape and the mesh properties.
|
||||
* @return true if no error occured
|
||||
*/
|
||||
virtual bool setMesh(ememory::SharedPtr<ege::resource::Mesh> _mesh);
|
||||
/**
|
||||
* @brief get a pointer on the Mesh file.
|
||||
* @return the mesh pointer.
|
||||
*/
|
||||
inline ememory::SharedPtr<ege::resource::Mesh> getMesh() {
|
||||
return m_mesh;
|
||||
};
|
||||
protected:
|
||||
float m_life; //!< Current life of the object
|
||||
float m_lifeMax; //!< Maximum possible life of the element
|
||||
public:
|
||||
/**
|
||||
* @brief get the curent life ratio [0..1]
|
||||
* @return The proportionnal life
|
||||
*/
|
||||
float getLifeRatio();
|
||||
/**
|
||||
* @brief Check if the element is dead.
|
||||
* @return true if the element does not exist anymore, false otherwise.
|
||||
*/
|
||||
bool isDead() {
|
||||
return (0 >= m_life)?true:false;
|
||||
};
|
||||
/**
|
||||
* @brief Request if the element might be removed from the system
|
||||
* @return true == > the object is removed
|
||||
*/
|
||||
virtual bool needToRemove() {
|
||||
return isDead();
|
||||
}
|
||||
/**
|
||||
* @brief apply a fire on the element at a current power and a specific power.
|
||||
* @param[in] _groupIdSource Source Id of the group, by default all event arrive at all group, buf some event can not be obviously apply at the ennemy like reparing ....
|
||||
* @param[in] _type Type of event on the life propertied
|
||||
* @param[in] _power Power of the event (can be >0 for adding life).
|
||||
* @param[in] _center Some fire decrease in function of space distance...
|
||||
*/
|
||||
virtual void setFireOn(int32_t _groupIdSource, int32_t _type, float _power, const vec3& _center=vec3(0,0,0));
|
||||
/**
|
||||
* @brief Call when the element life change.
|
||||
*/
|
||||
virtual void onLifeChange() { };
|
||||
protected:
|
||||
int32_t m_group; //!< Every element has a generic group
|
||||
public:
|
||||
/**
|
||||
* @brief get the Group of the element.
|
||||
* @return The group ID
|
||||
*/
|
||||
inline int32_t getGroup() const {
|
||||
return m_group;
|
||||
};
|
||||
/**
|
||||
* @brief set the group of the curent element
|
||||
* @param[in] newGroup The new Group ID of the element.
|
||||
*/
|
||||
inline void setGroup(int32_t _newGroup) {
|
||||
m_group=_newGroup;
|
||||
};
|
||||
public:
|
||||
/**
|
||||
* @brief Can be call tu opdate the list of the element displayed on the scren (example : no display of the hiden triangle)
|
||||
* @param[in] the camera properties
|
||||
* @ note by default nothing to do ...
|
||||
*/
|
||||
virtual void preCalculationDraw(const ege::Camera& _camera) { };
|
||||
/**
|
||||
* @brief draw the curent element (can have multiple display)
|
||||
* @param[in] pass Id of the current pass : [0..?]
|
||||
*/
|
||||
virtual void draw(int32_t _pass=0) = 0;
|
||||
|
||||
/**
|
||||
* @brief draw the current life of the element
|
||||
*/
|
||||
// TODO : Remove this ...
|
||||
virtual void drawLife(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
|
||||
protected:
|
||||
// For debug only ...
|
||||
ewol::compositing::Text m_debugText;
|
||||
public:
|
||||
/**
|
||||
* @brief Debug display of the current element
|
||||
* @param[in,out] draw Basic system to draw the debug shape and informations
|
||||
*/
|
||||
virtual void drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
|
||||
/**
|
||||
* @brief get the theoric position. Sometimes, the element has move due to an explosion or something else, then its real position in not the one that woult it be at the end ...
|
||||
* @return the theoric position
|
||||
*/
|
||||
virtual vec3 getPositionTheoric() {
|
||||
return getPosition();
|
||||
};
|
||||
/**
|
||||
* @brief get the current position of the element
|
||||
* @return the 3D position.
|
||||
*/
|
||||
virtual const vec3& getPosition();
|
||||
/**
|
||||
* @brief set the current position of the element
|
||||
* @param[in] _pos set the 3D position.
|
||||
*/
|
||||
virtual void setPosition(const vec3& _pos) {};
|
||||
/**
|
||||
* @brief Event arrive when an element has been remove from the system == > this permit to keep pointer of ennemy, and not search them every cycle ...
|
||||
* @param[in] _removedElement Pointer on the element removed.
|
||||
*/
|
||||
virtual void elementIsRemoved(ememory::SharedPtr<ege::Element> _removedElement) { };
|
||||
protected:
|
||||
bool m_fixe; //!< is a fixed element == > used for placement of every elements
|
||||
public:
|
||||
/**
|
||||
* @brief get the element if it is fixed or not. if the element is fixed this is for tower, and all thing does not really move
|
||||
* @return true : The element is fixed.
|
||||
*/
|
||||
inline bool isFixed() {
|
||||
return m_fixe;
|
||||
};
|
||||
protected:
|
||||
float m_radius; //!< Radius of the element (all element have a radius, if == 0 ==> then ghost ...
|
||||
public:
|
||||
/**
|
||||
* @brief get the current space needed by the element in the workspace
|
||||
* @return The dimention needed.
|
||||
*/
|
||||
inline float getRadius() {
|
||||
return m_radius;
|
||||
};
|
||||
/**
|
||||
* @brief, call when the element is removed (call only one time)
|
||||
*/
|
||||
virtual void onDestroy() {};
|
||||
/**
|
||||
* @brief set the elment in the physique engine
|
||||
*/
|
||||
virtual void dynamicEnable() {};
|
||||
/**
|
||||
* @brief remove this element from the physique engine
|
||||
*/
|
||||
virtual void dynamicDisable() {};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
*******************************************
|
||||
** IS REMOVED
|
||||
*******************************************
|
||||
|
||||
#include <ege/elements/ElementBase.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
@ -18,7 +21,7 @@ ege::ElementBase::~ElementBase() {
|
||||
EGE_WARNING("Remove ... ");
|
||||
}
|
||||
|
||||
const std::string& ege::ElementBase::getType() const {
|
||||
const etk::String& ege::ElementBase::getType() const {
|
||||
return ege::Element::getType();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,15 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
*******************************************
|
||||
** IS REMOVED
|
||||
*******************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ege/elements/Element.hpp>
|
||||
@ -25,7 +32,7 @@ namespace ege {
|
||||
* @brief get the element Type description string.
|
||||
* @return A reference on the descriptive string.
|
||||
*/
|
||||
virtual const std::string& getType() const;
|
||||
virtual const etk::String& getType() const;
|
||||
virtual void draw(int32_t _pass=0);
|
||||
private:
|
||||
vec3 m_position;
|
||||
|
@ -1,40 +1,35 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
*******************************************
|
||||
** IS REMOVED
|
||||
*******************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/elements/ElementPhysic.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <LinearMath/btTransformUtil.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
|
||||
#include <ege/CollisionShapeCreator.hpp>
|
||||
|
||||
const std::string& ege::ElementPhysic::getType() const {
|
||||
static const std::string nameType("----");
|
||||
const etk::String& ege::ElementPhysic::getType() const {
|
||||
static const etk::String nameType("----");
|
||||
return nameType;
|
||||
}
|
||||
|
||||
|
||||
ege::ElementPhysic::ElementPhysic(const ememory::SharedPtr<ege::Environement>& _env, bool _autoRigidBody) ://, float _mass) :
|
||||
ege::Element(_env),
|
||||
m_body(nullptr),
|
||||
m_shape(nullptr),
|
||||
m_body(null),
|
||||
//m_shape(null),
|
||||
m_elementInPhysicsSystem(false),
|
||||
m_IA(nullptr),
|
||||
m_IA(null),
|
||||
m_detectCollisionEnable(false) {
|
||||
if (_autoRigidBody == true) {
|
||||
createRigidBody();
|
||||
@ -45,44 +40,48 @@ ege::ElementPhysic::ElementPhysic(const ememory::SharedPtr<ege::Environement>& _
|
||||
|
||||
ege::ElementPhysic::~ElementPhysic() {
|
||||
// in every case remove IA
|
||||
iaDisable();
|
||||
//iaDisable();
|
||||
// same ...
|
||||
dynamicDisable();
|
||||
removeShape();
|
||||
delete m_body;
|
||||
m_body = nullptr;
|
||||
//dynamicDisable();
|
||||
//removeShape();
|
||||
// Destroy the rigid body
|
||||
//m_dynamicsWorld->destroyRigidBody(m_body);
|
||||
m_body = null;
|
||||
}
|
||||
|
||||
|
||||
void ege::ElementPhysic::createRigidBody(float _mass) {
|
||||
/// Create Dynamic Objects
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
vec3 localInertia(0,0,0);
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
if (_mass != 0.0f && getShape()!=nullptr) {
|
||||
getShape()->calculateLocalInertia(_mass, localInertia);
|
||||
void ege::ElementPhysic::createRigidBody(float _mass, bool _static) {
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(0.0, 3.0, 0.0);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body in the world
|
||||
m_body = null;//m_dynamicsWorld->createRigidBody(transform);
|
||||
/*
|
||||
if (_static = true) {
|
||||
m_body->setType(STATIC);
|
||||
//m_body->setType(KINEMATIC);
|
||||
// Disable gravity for this body
|
||||
m_body->enableGravity(false);
|
||||
} else {
|
||||
m_body->setType(DYNAMIC);
|
||||
}
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* motionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(_mass, motionState, getShape(), localInertia);
|
||||
m_body = new btRigidBody(rbInfo);
|
||||
m_body->setUserPointer((void*)this);
|
||||
m_body->setAngularVelocity(vec3(0,0,0));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bool ege::ElementPhysic::setMesh(ememory::SharedPtr<ege::resource::Mesh> _mesh) {
|
||||
EGE_WARNING("Set Mesh");
|
||||
if (m_mesh != nullptr) {
|
||||
removeShape();
|
||||
if (m_mesh != null) {
|
||||
//removeShape();
|
||||
}
|
||||
ege::Element::setMesh(_mesh);
|
||||
// auto load the shape :
|
||||
if (m_mesh == nullptr) {
|
||||
// auto load the shape:
|
||||
if (m_mesh == null) {
|
||||
return true;
|
||||
}
|
||||
if (m_mesh->getShape() != nullptr) {
|
||||
/*
|
||||
if (m_mesh->getShape() != null) {
|
||||
EGE_WARNING("create shape whith mesh internal shape ...");
|
||||
m_shape = static_cast<btCollisionShape*>(m_mesh->getShape());
|
||||
return true;
|
||||
@ -94,15 +93,16 @@ bool ege::ElementPhysic::setMesh(ememory::SharedPtr<ege::resource::Mesh> _mesh)
|
||||
m_shape = static_cast<btCollisionShape*>(m_mesh->getShape());
|
||||
vec3 localInertia(0,0,0);
|
||||
m_shape->calculateLocalInertia(50000000, localInertia); // TODO : BETTER ///
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool ege::ElementPhysic::setShape(btCollisionShape* _shape) {
|
||||
EGE_DEBUG("Set Shape");
|
||||
removeShape();
|
||||
m_shape = _shape;
|
||||
if (_shape == nullptr) {
|
||||
if (_shape == null) {
|
||||
EGE_WARNING("Remove shape ...");
|
||||
} else {
|
||||
EGE_INFO("set shape ...");
|
||||
@ -112,20 +112,20 @@ bool ege::ElementPhysic::setShape(btCollisionShape* _shape) {
|
||||
|
||||
void ege::ElementPhysic::removeShape() {
|
||||
// no shape
|
||||
if (m_shape == nullptr) {
|
||||
if (m_shape == null) {
|
||||
return;
|
||||
}
|
||||
// need to chek if the shape is the same as the mesh shape ...
|
||||
if (m_mesh == nullptr) {
|
||||
if (m_mesh == null) {
|
||||
// no mesh == > standalone shape
|
||||
delete(m_shape);
|
||||
m_shape=nullptr;
|
||||
ETK_DELETE(btCollisionShape, m_shape);
|
||||
m_shape=null;
|
||||
EGE_WARNING("Remove shape .2.");
|
||||
return;
|
||||
}
|
||||
if (m_shape != m_mesh->getShape()) {
|
||||
delete(m_shape);
|
||||
m_shape=nullptr;
|
||||
ETK_DELETE(btCollisionShape, m_shape);
|
||||
m_shape=null;
|
||||
EGE_WARNING("Remove shape .3.");
|
||||
return;
|
||||
}
|
||||
@ -133,52 +133,60 @@ void ege::ElementPhysic::removeShape() {
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::FunctionFreeShape(void* _pointer) {
|
||||
if (_pointer == nullptr) {
|
||||
if (_pointer == null) {
|
||||
return;
|
||||
}
|
||||
delete(static_cast<btCollisionShape*>(_pointer));
|
||||
ETK_DELETE(btCollisionShape, _pointer);
|
||||
}
|
||||
|
||||
*/
|
||||
void ege::ElementPhysic::setPosition(const vec3& _pos) {
|
||||
if (m_body != nullptr) {
|
||||
if (m_body != null) {
|
||||
/*
|
||||
btTransform transformation = m_body->getCenterOfMassTransform();
|
||||
transformation.setOrigin(_pos);
|
||||
m_body->setCenterOfMassTransform(transformation);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
const vec3& ege::ElementPhysic::getPosition() {
|
||||
if (m_body != nullptr) {
|
||||
/*
|
||||
if (m_body != null) {
|
||||
return m_body->getCenterOfMassPosition();
|
||||
}
|
||||
*/
|
||||
return ege::Element::getPosition();
|
||||
};
|
||||
|
||||
const vec3& ege::ElementPhysic::getSpeed() {
|
||||
static vec3 emptySpeed(0,0,0);
|
||||
if (m_body != nullptr) {
|
||||
/*
|
||||
if (m_body != null) {
|
||||
return m_body->getLinearVelocity();
|
||||
}
|
||||
*/
|
||||
return emptySpeed;
|
||||
};
|
||||
|
||||
const float ege::ElementPhysic::getInvMass() {
|
||||
if (m_body != nullptr) {
|
||||
/*
|
||||
if (m_body != null) {
|
||||
return m_body->getInvMass();
|
||||
}
|
||||
*/
|
||||
return 0.0000000001f;
|
||||
};
|
||||
|
||||
void ege::ElementPhysic::drawShape(const btCollisionShape* _shape,
|
||||
void ege::ElementPhysic::drawShape(/*const btCollisionShape* _shape,*/
|
||||
ememory::SharedPtr<ewol::resource::Colored3DObject> _draw,
|
||||
mat4 _transformationMatrix,
|
||||
std::vector<vec3> _tmpVertices) {
|
||||
if( _draw == nullptr
|
||||
|| _shape == nullptr) {
|
||||
etk::Vector<vec3> _tmpVertices) {
|
||||
#if 0
|
||||
if( _draw == null
|
||||
|| _shape == null) {
|
||||
return;
|
||||
}
|
||||
etk::Color<float> tmpColor(1.0, 0.0, 0.0, 0.3);
|
||||
|
||||
//EGE_DEBUG(" draw (6): !btIDebugDraw::DBG_DrawWireframe");
|
||||
int shapetype=_shape->getShapeType();
|
||||
switch (shapetype) {
|
||||
@ -219,7 +227,7 @@ void ege::ElementPhysic::drawShape(const btCollisionShape* _shape,
|
||||
if (_shape->isConvex()) {
|
||||
EGE_DEBUG(" shape->isConvex()");
|
||||
const btConvexPolyhedron* poly = _shape->isPolyhedral() ? ((btPolyhedralConvexShape*) _shape)->getConvexPolyhedron() : 0;
|
||||
if (nullptr!=poly) {
|
||||
if (null!=poly) {
|
||||
EGE_DEBUG(" have poly");
|
||||
/*
|
||||
glBegin(GL_TRIANGLES);
|
||||
@ -314,54 +322,47 @@ void ege::ElementPhysic::drawShape(const btCollisionShape* _shape,
|
||||
EGE_DEBUG(" draw (09): default");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
ege::Element::drawDebug(_draw, _camera);
|
||||
btScalar mmm[16];
|
||||
btDefaultMotionState* myMotionState = (btDefaultMotionState*)m_body->getMotionState();
|
||||
myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm);
|
||||
|
||||
mat4 transformationMatrix(mmm);
|
||||
transformationMatrix.transpose();
|
||||
|
||||
// note : set the vertice here to prevent multiple allocations...
|
||||
std::vector<vec3> EwolVertices;
|
||||
drawShape(m_shape, _draw, transformationMatrix, EwolVertices);
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::draw(int32_t _pass) {
|
||||
if (m_elementInPhysicsSystem == false) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
//EGE_INFO("draw : " << _pass );
|
||||
if (_pass == 0) {
|
||||
if( m_body != nullptr
|
||||
&& m_mesh != nullptr
|
||||
&& m_body->getMotionState() ) {
|
||||
if( m_body != null
|
||||
&& m_mesh != null) {
|
||||
//EGE_INFO("element pos = " << getPosition());
|
||||
btScalar mmm[16];
|
||||
btDefaultMotionState* myMotionState = (btDefaultMotionState*)m_body->getMotionState();
|
||||
myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm);
|
||||
float mmm[16];
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = m_body->getInterpolatedTransform();
|
||||
// Get the OpenGL matrix array of the transform
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
|
||||
//EGE_INFO(" mat = " << mat4(mmm));
|
||||
mat4 transformationMatrix(mmm);
|
||||
transformationMatrix.transpose();
|
||||
//mat4 transformationMatrix = mat4(mmm) * etk::matScale(vec3(20,20,20));
|
||||
// TODO: check this : transformationMatrix.transpose();
|
||||
m_mesh->draw(transformationMatrix);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::dynamicEnable() {
|
||||
if (m_elementInPhysicsSystem == true) {
|
||||
return;
|
||||
}
|
||||
if(m_body != nullptr) {
|
||||
if(m_body != null) {
|
||||
EGE_VERBOSE("dynamicEnable : RigidBody");
|
||||
m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body);
|
||||
}
|
||||
if(m_IA != nullptr) {
|
||||
if(m_IA != null) {
|
||||
EGE_VERBOSE("dynamicEnable : IA");
|
||||
m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
|
||||
}
|
||||
m_elementInPhysicsSystem = true;
|
||||
}
|
||||
@ -370,95 +371,107 @@ void ege::ElementPhysic::dynamicDisable() {
|
||||
if (m_elementInPhysicsSystem == false) {
|
||||
return;
|
||||
}
|
||||
if(m_IA != nullptr) {
|
||||
if(m_IA != null) {
|
||||
EGE_VERBOSE("dynamicDisable : IA");
|
||||
m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
|
||||
}
|
||||
if(m_body != nullptr) {
|
||||
if(m_body != null) {
|
||||
EGE_VERBOSE("dynamicDisable : RigidBody");
|
||||
// Unlink element from the engine
|
||||
m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body);
|
||||
m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body);
|
||||
}
|
||||
m_elementInPhysicsSystem = false;
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::iaEnable() {
|
||||
if (m_IA != nullptr) {
|
||||
if (m_IA != null) {
|
||||
// IA already started ...
|
||||
return;
|
||||
}
|
||||
m_IA = new localIA(*this);
|
||||
if (m_IA == nullptr) {
|
||||
EGE_ERROR("Can not start the IA == > allocation error");
|
||||
m_IA = ETK_NEW(localIA, *this);
|
||||
if (m_IA == null) {
|
||||
EGE_ERROR("Can not start the IA == > allocation error");
|
||||
return;
|
||||
}
|
||||
if (m_elementInPhysicsSystem == true) {
|
||||
m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::iaDisable() {
|
||||
if (m_IA == nullptr) {
|
||||
if (m_IA == null) {
|
||||
// IA already stopped ...
|
||||
return;
|
||||
}
|
||||
if (m_elementInPhysicsSystem == true) {
|
||||
m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
|
||||
//m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
|
||||
}
|
||||
// remove IA :
|
||||
delete(m_IA);
|
||||
m_IA = nullptr;
|
||||
// remove IA:
|
||||
ETK_DELETE(localIA, m_IA);
|
||||
m_IA = null;
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::setMass(float _value) {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
vec3 localInertia(0,0,0);
|
||||
if (_value != 0.0f && getShape()!=nullptr) {
|
||||
getShape()->calculateLocalInertia(_value, localInertia);
|
||||
if (_value != 0.0f && getShape()!=null) {
|
||||
//getShape()->calculateLocalInertia(_value, localInertia);
|
||||
EWOL_ERROR("Update inertia calculated : " << localInertia);
|
||||
}
|
||||
m_body->setMassProps(_value, localInertia);
|
||||
*/
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::setLinearVelocity(const vec3& _value) {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
EGE_WARNING("no body");
|
||||
return;
|
||||
}
|
||||
m_body->setLinearVelocity(_value);
|
||||
// Force vector (in Newton)
|
||||
rp3d::Vector3 force(_value.x(), _value.y(), _value.z());
|
||||
// Apply a force to the center of the body
|
||||
m_body->applyForceToCenterOfMass(force);
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::setTorqueImpulse(const vec3& _value) {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
EGE_WARNING("no body");
|
||||
return;
|
||||
}
|
||||
m_body->applyTorqueImpulse(_value);
|
||||
// Torque vector
|
||||
rp3d::Vector3 torque(_value.x(), _value.y(), _value.z());
|
||||
// Apply a torque to the body
|
||||
m_body->applyTorque(torque);
|
||||
}
|
||||
|
||||
void ege::ElementPhysic::setAngularVelocity(const vec3& _value) {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
EGE_WARNING("no body");
|
||||
return;
|
||||
}
|
||||
m_body->setAngularVelocity(_value);
|
||||
//m_body->setAngularVelocity(_value);
|
||||
}
|
||||
|
||||
/*
|
||||
btQuaternion ege::ElementPhysic::getOrientation() const {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
EGE_WARNING("no body");
|
||||
return btQuaternion(0,0,0,0);
|
||||
}
|
||||
return m_body->getOrientation();
|
||||
//return m_body->getOrientation();
|
||||
return btQuaternion(0,0,0,0);
|
||||
}
|
||||
*/
|
||||
|
||||
void ege::ElementPhysic::setCollisionDetectionStatus(bool _status) {
|
||||
if (m_body == nullptr) {
|
||||
if (m_body == null) {
|
||||
EGE_WARNING("no body");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if (m_detectCollisionEnable == _status) {
|
||||
return;
|
||||
}
|
||||
@ -470,5 +483,6 @@ void ege::ElementPhysic::setCollisionDetectionStatus(bool _status) {
|
||||
m_body->setCollisionFlags(m_body->getCollisionFlags() - btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,21 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
*******************************************
|
||||
** IS REMOVED
|
||||
*******************************************
|
||||
|
||||
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <vector>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <ewol/debug.hpp>
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
@ -18,8 +25,8 @@
|
||||
#include <ewol/compositing/Text.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/elements/Element.hpp>
|
||||
#include <ephysics/reactphysics3d.h>
|
||||
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
|
||||
#define INDEX_RIGHT_AXIS (0)
|
||||
#define INDEX_FORWARD_AXIS (1)
|
||||
@ -32,9 +39,9 @@ namespace ege {
|
||||
private:
|
||||
static void FunctionFreeShape(void* _pointer);
|
||||
protected:
|
||||
btRigidBody* m_body; //!< all the element have a body == > otherwise it will be not manage with this system...
|
||||
rp3d::RigidBody* m_body; //!< all the element have a body == > otherwise it will be not manage with this system...
|
||||
public:
|
||||
void createRigidBody(float _mass=400000000.0f);
|
||||
void createRigidBody(float _mass=400000000.0f, bool _static=false);
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor (when constructer is called just add element that did not change.
|
||||
@ -52,9 +59,9 @@ namespace ege {
|
||||
* @brief get the element Type description string.
|
||||
* @return A reference on the descriptive string.
|
||||
*/
|
||||
virtual const std::string& getType() const;
|
||||
virtual const etk::String& getType() const;
|
||||
protected:
|
||||
btCollisionShape* m_shape; //!< shape of the element (set a copy here to have the debug display of it)
|
||||
//btCollisionShape* m_shape; //!< shape of the element (set a copy here to have the debug display of it)
|
||||
public:
|
||||
/**
|
||||
* @brief set the shape properties.
|
||||
@ -62,19 +69,21 @@ namespace ege {
|
||||
* @note : this remove the shape properties.
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool setShape(btCollisionShape* _shape);
|
||||
//bool setShape(btCollisionShape* _shape);
|
||||
/**
|
||||
* @brief get a pointer on the bullet collision shape.
|
||||
* @return the collision pointer.
|
||||
*/
|
||||
/*
|
||||
inline btCollisionShape* getShape() {
|
||||
return m_shape;
|
||||
};
|
||||
*/
|
||||
private:
|
||||
/**
|
||||
* @brief remove the curent selected shape.
|
||||
*/
|
||||
void removeShape();
|
||||
//void removeShape();
|
||||
public:
|
||||
virtual bool setMesh(ememory::SharedPtr<ege::resource::Mesh> _mesh);
|
||||
/**
|
||||
@ -87,6 +96,7 @@ namespace ege {
|
||||
* @brief draw the current life of the element
|
||||
*/
|
||||
// virtual void drawLife(const ememory::SharedPtr<ewol::resource::Colored3DObject>& _draw, const ememory::SharedPtr<ege::Camera>& _camera);
|
||||
virtual void drawNormalDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
// TODO : Remove this ...
|
||||
protected:
|
||||
vec3 m_theoricPosition;
|
||||
@ -121,7 +131,7 @@ namespace ege {
|
||||
virtual void setTorqueImpulse(const vec3& _value);
|
||||
virtual void setAngularVelocity(const vec3& _value);
|
||||
|
||||
btQuaternion getOrientation() const;
|
||||
//btQuaternion getOrientation() const;
|
||||
|
||||
protected:
|
||||
bool m_elementInPhysicsSystem;
|
||||
@ -129,7 +139,7 @@ namespace ege {
|
||||
virtual void dynamicEnable();
|
||||
virtual void dynamicDisable();
|
||||
private:
|
||||
class localIA : public btActionInterface {
|
||||
class localIA {
|
||||
private:
|
||||
ege::ElementPhysic& m_element;
|
||||
public:
|
||||
@ -147,12 +157,14 @@ namespace ege {
|
||||
|
||||
};
|
||||
public: // herited function
|
||||
/*
|
||||
void debugDraw(btIDebugDraw* _debugDrawer) {
|
||||
|
||||
};
|
||||
void updateAction(btCollisionWorld* _collisionWorld, btScalar _step) {
|
||||
m_element.iaAction(_step);
|
||||
};
|
||||
*/
|
||||
};
|
||||
localIA* m_IA;
|
||||
public:
|
||||
@ -177,10 +189,10 @@ namespace ege {
|
||||
virtual void setPosition(const vec3& _pos);
|
||||
virtual void drawDebug(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
protected:
|
||||
void drawShape(const btCollisionShape* _shape,
|
||||
void drawShape(/*const btCollisionShape* _shape,*/
|
||||
ememory::SharedPtr<ewol::resource::Colored3DObject> _draw,
|
||||
mat4 _transformationMatrix,
|
||||
std::vector<vec3> _tmpVertices);
|
||||
etk::Vector<vec3> _tmpVertices);
|
||||
protected:
|
||||
bool m_detectCollisionEnable; //!< physic collision detect enable.
|
||||
public:
|
||||
|
15
ege/ia/Component.cpp
Normal file
15
ege/ia/Component.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/ia/Component.hpp>
|
||||
|
||||
const etk::String& ege::ia::Component::getType() const {
|
||||
static etk::String tmp("ia");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ege::ia::Component::update(float _delta) {
|
||||
|
||||
}
|
23
ege/ia/Component.hpp
Normal file
23
ege/ia/Component.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
#include <ege/Component.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace ia {
|
||||
class Component : public ege::Component {
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual const etk::String& getType() const override;
|
||||
// call of this function every time the call will be done
|
||||
virtual void update(float _delta);
|
||||
};
|
||||
}
|
||||
}
|
16
ege/ia/ComponentLua.cpp
Normal file
16
ege/ia/ComponentLua.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/ia/ComponentLua.hpp>
|
||||
|
||||
ege::ia::ComponentLua::ComponentLua(const etk::String& _fileName) {
|
||||
// Load the current IA file interface ==> init...
|
||||
m_engine.executeFile(_fileName);
|
||||
}
|
||||
|
||||
|
||||
void ege::ia::ComponentLua::update(float _delta) {
|
||||
m_engine.callVoid("update", float(_delta));
|
||||
}
|
21
ege/ia/ComponentLua.hpp
Normal file
21
ege/ia/ComponentLua.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/ia/Component.hpp>
|
||||
#include <luaWrapper/luaWrapper.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace ia {
|
||||
class ComponentLua : public ege::ia::Component {
|
||||
public:
|
||||
ComponentLua(const etk::String& _fileName);
|
||||
void update(float _delta) override;
|
||||
private:
|
||||
luaWrapper::Lua m_engine;
|
||||
};
|
||||
}
|
||||
}
|
82
ege/ia/Engine.cpp
Normal file
82
ege/ia/Engine.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/ia/Engine.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
ege::ia::Engine::Engine(ege::Environement* _env) :
|
||||
ege::Engine(_env) {
|
||||
|
||||
}
|
||||
|
||||
const etk::String& ege::ia::Engine::getType() const {
|
||||
static etk::String tmp("ia");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ege::ia::Engine::componentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
ememory::SharedPtr<ege::ia::Component> ref = ememory::dynamicPointerCast<ege::ia::Component>(_ref);
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it == ref) {
|
||||
it->reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ege::ia::Engine::componentAdd(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
ememory::SharedPtr<ege::ia::Component> ref = ememory::dynamicPointerCast<ege::ia::Component>(_ref);
|
||||
EGE_WARNING("ADD COMPONENT " << uint64_t(ref.get()) );
|
||||
if (ref == null) {
|
||||
return;
|
||||
}
|
||||
#if DEBUG
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it != null) {
|
||||
if (*it == ref) {
|
||||
EGE_ERROR("Try Add multiple time the same Component in the IA Engine " << uint64_t(ref.get()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it == null) {
|
||||
*it = ref;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_component.pushBack(ref);
|
||||
}
|
||||
|
||||
// Constant physics time step ==> 10 time / seconds
|
||||
// TODO: set it configurable, some games need more, and soem other just need really less ==> or set it configurable with the internal component
|
||||
static const float timeStep = 5.0;
|
||||
|
||||
void ege::ia::Engine::update(const echrono::Duration& _delta) {
|
||||
float deltaTime = _delta.toSeconds();
|
||||
// Add the time difference in the accumulator
|
||||
m_accumulator += deltaTime;
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (m_accumulator >= timeStep) {
|
||||
EGE_WARNING("Generate for " << m_accumulator << " / " << timeStep << " for:" << m_component.size());
|
||||
// call every object to usdate their constant forces applyed
|
||||
for (auto &it: m_component) {
|
||||
// check null pointer
|
||||
if (it == null) {
|
||||
// no pointer null are set in the output list ...
|
||||
continue;
|
||||
}
|
||||
it->update(timeStep);
|
||||
}
|
||||
// Decrease the accumulated time
|
||||
m_accumulator -= timeStep;
|
||||
}
|
||||
}
|
35
ege/ia/Engine.hpp
Normal file
35
ege/ia/Engine.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
#include <ege/Engine.hpp>
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/ia/Component.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace ia {
|
||||
class Engine : public ege::Engine {
|
||||
public:
|
||||
Engine(ege::Environement* _env);
|
||||
~Engine() {}
|
||||
|
||||
// update cycle
|
||||
void update(const echrono::Duration& _delta) override;
|
||||
public:
|
||||
const etk::String& getType() const override;
|
||||
void componentRemove(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
void componentAdd(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
protected:
|
||||
etk::Vector<ememory::SharedPtr<ege::ia::Component>> m_component;
|
||||
float m_accumulator; // limit call of IA process
|
||||
};
|
||||
}
|
||||
}
|
||||
|
20
ege/particule/Component.cpp
Normal file
20
ege/particule/Component.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/particule/Component.hpp>
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/particule/Engine.hpp>
|
||||
|
||||
const etk::String& ege::particule::Component::getType() const {
|
||||
static etk::String tmp("particule");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ege::particule::Component::Component(ege::particule::Engine* _particuleEngine, const char* _particuleType) :
|
||||
m_particuleEngine(_particuleEngine),
|
||||
m_particuleType(_particuleType) {
|
||||
m_particuleEngine->add(ememory::staticPointerCast<ege::particule::Component>(sharedFromThis()));
|
||||
}
|
||||
|
72
ege/particule/Component.hpp
Normal file
72
ege/particule/Component.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
#include <ege/Component.hpp>
|
||||
|
||||
#include <ege/camera/Camera.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace particule {
|
||||
class Engine;
|
||||
class Component : public ege::Component {
|
||||
public:
|
||||
virtual const etk::String& getType() const override;
|
||||
protected:
|
||||
ege::particule::Engine* m_particuleEngine;
|
||||
const char* m_particuleType;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param[in] _particuleEngine reference on the particule engine ...
|
||||
* @param[in] _particuleType Type of the particule (set null if you did not want to use the respowner ...)
|
||||
*/
|
||||
Component(ege::particule::Engine* _particuleEngine, const char* _particuleType = null);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~Component() = default;
|
||||
/**
|
||||
* @brief init the particule
|
||||
*/
|
||||
virtual void init() { };
|
||||
/**
|
||||
* @brief Un-init the particule
|
||||
*/
|
||||
virtual void UnInit() { };
|
||||
/**
|
||||
* @brief update the paticule properties
|
||||
* @param[in] _delta Delta time from the previous call
|
||||
*/
|
||||
virtual void update(float _delta) { };
|
||||
/**
|
||||
* @brief draw the current particule
|
||||
*/
|
||||
virtual void draw(const ege::Camera& _camera) { };
|
||||
/**
|
||||
* @brief Check if the element might be removed
|
||||
* @return true : The element might be removed
|
||||
* @return false : The element might be keeped
|
||||
*/
|
||||
virtual bool needRemove() {
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* @brief get the type of the particule
|
||||
* @return Type of the current particule
|
||||
*/
|
||||
const char* getParticuleType() {
|
||||
return m_particuleType;
|
||||
};
|
||||
/**
|
||||
* @brief When the particule arrive to his end of life, this function is called.
|
||||
*/
|
||||
virtual void onEnd() {};
|
||||
};
|
||||
}
|
||||
}
|
152
ege/particule/Engine.cpp
Normal file
152
ege/particule/Engine.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/particule/Engine.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/particule/Component.hpp>
|
||||
|
||||
ege::particule::Engine::Engine(ege::Environement* _env) :
|
||||
ege::Engine(_env) {
|
||||
|
||||
}
|
||||
|
||||
ege::particule::Engine::~Engine() {
|
||||
clear();
|
||||
}
|
||||
|
||||
const etk::String& ege::particule::Engine::getType() const {
|
||||
static etk::String tmp("particule");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ege::particule::Engine::componentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
|
||||
}
|
||||
|
||||
void ege::particule::Engine::componentAdd(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ege::particule::Engine::add(const ememory::SharedPtr<ege::particule::Component>& _particule) {
|
||||
if (_particule == null) {
|
||||
EGE_ERROR("Try to add particule null");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] != null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii] = _particule;
|
||||
return;
|
||||
}
|
||||
// Just add it at the end ...
|
||||
m_particuleList.pushBack(_particule);
|
||||
}
|
||||
|
||||
void ege::particule::Engine::addRemoved(const ememory::SharedPtr<ege::particule::Component>& _particule) {
|
||||
if (_particule == null) {
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] != null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleRemoved[iii] = _particule;
|
||||
return;
|
||||
}
|
||||
// Just add it at the end ...
|
||||
m_particuleRemoved.pushBack(_particule);
|
||||
}
|
||||
|
||||
ememory::SharedPtr<ege::particule::Component> ege::particule::Engine::respown(const char* _particuleType) {
|
||||
if (_particuleType == null) {
|
||||
return null;
|
||||
}
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_particuleRemoved[iii]->getParticuleType() == _particuleType) {
|
||||
add(m_particuleRemoved[iii]);
|
||||
ememory::SharedPtr<ege::particule::Component> tmpParticule = m_particuleRemoved[iii];
|
||||
m_particuleRemoved[iii].reset();
|
||||
tmpParticule->init();
|
||||
return tmpParticule;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void ege::particule::Engine::update(const echrono::Duration& _delta) {
|
||||
float deltaTime = _delta.toSeconds();
|
||||
if (deltaTime>(1.0f/60.0f)) {
|
||||
deltaTime = (1.0f/60.0f);
|
||||
}
|
||||
EGE_DEBUG("Update the Particule engine ... " << deltaTime);
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii]->update(deltaTime);
|
||||
}
|
||||
// check removing elements
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
if (m_particuleList[iii]->needRemove()) {
|
||||
m_particuleList[iii]->onEnd();
|
||||
if (m_particuleList[iii]->getParticuleType() == null) {
|
||||
// Real remove particule ...
|
||||
m_particuleList[iii].reset();
|
||||
} else {
|
||||
addRemoved(m_particuleList[iii]);
|
||||
}
|
||||
m_particuleList[iii] = null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
int32_t nbParticule = 0;
|
||||
for (int32_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
nbParticule++;
|
||||
}
|
||||
EGE_DEBUG("number of particule : " << nbParticule);
|
||||
*/
|
||||
}
|
||||
|
||||
void ege::particule::Engine::render(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii]->draw(*_camera);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::particule::Engine::clear() {
|
||||
// clear element not removed
|
||||
for (size_t iii=0; iii<m_particuleList.size(); ++iii) {
|
||||
if (m_particuleList[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleList[iii].reset();
|
||||
}
|
||||
m_particuleList.clear();
|
||||
// clear element that are auto-removed
|
||||
for (size_t iii=0; iii<m_particuleRemoved.size(); ++iii) {
|
||||
if (m_particuleRemoved[iii] == null) {
|
||||
continue;
|
||||
}
|
||||
m_particuleRemoved[iii].reset();
|
||||
}
|
||||
m_particuleRemoved.clear();
|
||||
}
|
59
ege/particule/Engine.hpp
Normal file
59
ege/particule/Engine.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
#include <ege/Engine.hpp>
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <ege/particule/Component.hpp>
|
||||
|
||||
namespace ege {
|
||||
class Environement;
|
||||
namespace particule {
|
||||
class Component;
|
||||
class Engine : public ege::Engine {
|
||||
public:
|
||||
Engine(ege::Environement* _env); // note : need the engine to register has an dynamic element ... (the first ...)
|
||||
~Engine();
|
||||
private:
|
||||
etk::Vector<ememory::SharedPtr<ege::particule::Component>> m_particuleList; //!< all particule created and active
|
||||
etk::Vector<ememory::SharedPtr<ege::particule::Component>> m_particuleRemoved; //!< removed particule
|
||||
public:
|
||||
/**
|
||||
* @brief clear the particule engine
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief add a particule in the engine (internal acces only)
|
||||
* @param[in] _particule Pointer on the particule to add
|
||||
*/
|
||||
void add(const ememory::SharedPtr<ege::particule::Component>& _particule);
|
||||
private:
|
||||
/**
|
||||
* @brief add a particule in the removed section == > this not delete the particule, but just set it in an other list
|
||||
* @param[in] _particule Pointer on the particule to add
|
||||
*/
|
||||
void addRemoved(const ememory::SharedPtr<ege::particule::Component>& _particule);
|
||||
public:
|
||||
/**
|
||||
* @brief get a particue with his type, we get particule that has been already removed, otherwise, you will create new
|
||||
* @param[in] _particuleType Particule type, this chek only the pointer not the data.
|
||||
* @return null, the particule has not been removed from the created pool
|
||||
* @return The pointer on the requested element (an init has been done).
|
||||
* @note If you did not want to use respawn set type at null.
|
||||
*/
|
||||
ememory::SharedPtr<ege::particule::Component> respown(const char* _particuleType);
|
||||
|
||||
public:
|
||||
const etk::String& getType() const override;
|
||||
void componentRemove(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
void componentAdd(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
void update(const echrono::Duration& _delta) override;
|
||||
void render(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
0
ege/particule/Particule.hpp
Normal file
0
ege/particule/Particule.hpp
Normal file
65
ege/particule/Simple.cpp
Normal file
65
ege/particule/Simple.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/particule/Simple.hpp>
|
||||
|
||||
ege::particule::Simple::Simple(ege::particule::Engine* _particuleEngine, const char* _particuleType) :
|
||||
ege::particule::Component(_particuleEngine, _particuleType) {
|
||||
init();
|
||||
}
|
||||
|
||||
void ege::particule::Simple::init() {
|
||||
m_lifeFull = 3;
|
||||
m_life = m_lifeFull;
|
||||
m_level = 0;
|
||||
m_pos = vec3(0,0,0);
|
||||
m_angle = 0;
|
||||
m_speed = vec3(0,0,0);
|
||||
m_scale = vec3(1,1,1);
|
||||
m_scaleExpand = vec3(0,0,0);
|
||||
}
|
||||
|
||||
bool ege::particule::Simple::needRemove() {
|
||||
return m_life<0.0f;
|
||||
}
|
||||
|
||||
|
||||
void ege::particule::Simple::update(float _delta) {
|
||||
//EGE_DEBUG("Life : " << m_life << "-" << _delta);
|
||||
m_life -= _delta;
|
||||
m_pos += m_speed*_delta;
|
||||
m_scale += m_scaleExpand*_delta;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setLife(float _life) {
|
||||
m_lifeFull = _life;
|
||||
m_life = m_lifeFull;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setLevel(float _level) {
|
||||
m_level = _level;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setPosition(const vec3& _pos) {
|
||||
m_pos = _pos;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setAngle(float _angle) {
|
||||
m_angle = _angle;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setMoveSpeed(const vec3& _speed) {
|
||||
m_speed = _speed;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setScale(const vec3& _scale) {
|
||||
m_scale = _scale;
|
||||
}
|
||||
|
||||
void ege::particule::Simple::setScaleExpend(const vec3& _scaleExpand) {
|
||||
m_scaleExpand=_scaleExpand;
|
||||
}
|
68
ege/particule/Simple.hpp
Normal file
68
ege/particule/Simple.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ege {
|
||||
class ParticuleSimple;
|
||||
};
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector2D.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Vector4D.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/particule/Component.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace particule {
|
||||
/**
|
||||
* @brief The particule class is an element with no control, when it will be created,
|
||||
* it does not have any control, for example smoke or reactor generation ...
|
||||
* or explosion particule ...
|
||||
*/
|
||||
class Simple : public ege::particule::Component {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param[in] _name Name of the particule.
|
||||
* @param[in] _standalone The particule are created and have there own life (no dynamic control)
|
||||
*/
|
||||
Simple(ege::particule::Engine* _particuleEngine, const char* _particuleType);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~Simple() { };
|
||||
public: // herited elements:
|
||||
virtual void update(float _delta);
|
||||
//virtual void draw() { };
|
||||
virtual bool needRemove();
|
||||
virtual void init();
|
||||
protected:
|
||||
float m_lifeFull;
|
||||
float m_life;
|
||||
float m_level;
|
||||
vec3 m_pos;
|
||||
float m_angle;
|
||||
vec3 m_speed;
|
||||
vec3 m_scale;
|
||||
vec3 m_scaleExpand;
|
||||
public:
|
||||
/**
|
||||
*
|
||||
*/
|
||||
virtual void setLife(float _life);
|
||||
virtual void setLevel(float _level);
|
||||
virtual void setPosition(const vec3& _pos);
|
||||
virtual void setAngle(float _angle);
|
||||
virtual void setMoveSpeed(const vec3& _speed);
|
||||
virtual void setScale(const vec3& _scale);
|
||||
virtual void setScaleExpend(const vec3& _scaleExpand);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
531
ege/physics/Component.cpp
Normal file
531
ege/physics/Component.cpp
Normal file
@ -0,0 +1,531 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/physics/Component.hpp>
|
||||
#include <ege/physics/Engine.hpp>
|
||||
#include <ege/Environement.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
#include <ege/physics/shape/Box.hpp>
|
||||
#include <ege/physics/shape/Capsule.hpp>
|
||||
#include <ege/physics/shape/Cone.hpp>
|
||||
#include <ege/physics/shape/ConvexHull.hpp>
|
||||
#include <ege/physics/shape/Cylinder.hpp>
|
||||
#include <ege/physics/shape/Sphere.hpp>
|
||||
#include <ege/physics/shape/Concave.hpp>
|
||||
#include <ephysics/collision/shapes/ConcaveShape.hpp>
|
||||
#include <ephysics/collision/shapes/ConcaveMeshShape.hpp>
|
||||
|
||||
const etk::String& ege::physics::Component::getType() const {
|
||||
static etk::String tmp("physics");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ege::physics::Component::beginContact(ege::physics::Component* _other, const vec3& _normal, const vec3& _pos, const vec3& _posOther, float _penetrationDepth) {
|
||||
EGE_WARNING(" collision [BEGIN] " << _pos << " depth=" << _penetrationDepth);
|
||||
}
|
||||
|
||||
void ege::physics::Component::newContact(ege::physics::Component* _other, const vec3& _normal, const vec3& _pos, const vec3& _posOther, float _penetrationDepth) {
|
||||
EGE_WARNING(" collision [ NEW ] " << _pos << " depth=" << _penetrationDepth);
|
||||
}
|
||||
|
||||
ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _env):
|
||||
m_staticForceApplyCenterOfMass(0,0,0),
|
||||
m_staticTorqueApply(0,0,0) {
|
||||
m_engine = ememory::dynamicPointerCast<ege::physics::Engine>(_env->getEngine(getType()));
|
||||
// Initial position and orientation of the rigid body
|
||||
m_lastTransformEmit = etk::Transform3D(vec3(0,0,0), etk::Quaternion::identity());
|
||||
m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(m_lastTransformEmit);
|
||||
m_rigidBody->setUserData(this);
|
||||
// set collision callback:
|
||||
//m_engine->getDynamicWorld()->testCollision(m_rigidBody, this);
|
||||
}
|
||||
|
||||
ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _env, const etk::Transform3D& _transform):
|
||||
m_staticForceApplyCenterOfMass(0,0,0),
|
||||
m_staticTorqueApply(0,0,0) {
|
||||
m_engine = ememory::dynamicPointerCast<ege::physics::Engine>(_env->getEngine(getType()));
|
||||
// Create a rigid body in the world
|
||||
m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(_transform);
|
||||
m_rigidBody->setUserData(this);
|
||||
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());
|
||||
EGE_ERROR("LinearDamping=" << m_rigidBody->getLinearDamping());
|
||||
EGE_ERROR("AngularDamping=" << m_rigidBody->getAngularDamping());
|
||||
m_rigidBody->getMaterial().setBounciness(0.4);
|
||||
//m_rigidBody->getMaterial().setFrictionCoefficient(0.01);
|
||||
//m_rigidBody->getMaterial().setRollingResistance(0.01);
|
||||
m_rigidBody->setAngularDamping(0.9);
|
||||
m_rigidBody->setLinearDamping(0.9);
|
||||
}
|
||||
|
||||
void ege::physics::Component::setType(enum ege::physics::Component::type _type) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
switch(_type) {
|
||||
case ege::physics::Component::type::bodyStatic:
|
||||
m_rigidBody->setType(ephysics::STATIC);
|
||||
break;
|
||||
case ege::physics::Component::type::bodyKinematic:
|
||||
m_rigidBody->setType(ephysics::KINEMATIC);
|
||||
break;
|
||||
case ege::physics::Component::type::bodyDynamic:
|
||||
m_rigidBody->setType(ephysics::DYNAMIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ege::physics::Component::~Component() {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
// disable callback
|
||||
m_rigidBody->setUserData(null);
|
||||
m_engine->getDynamicWorld()->testCollision(m_rigidBody, null);
|
||||
m_engine->getDynamicWorld()->destroyRigidBody(m_rigidBody);
|
||||
m_rigidBody = null;
|
||||
}
|
||||
|
||||
void ege::physics::Component::generate() {
|
||||
if (m_shape.size() == 0) {
|
||||
EGE_WARNING("No Shape Availlable ...");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &it: m_shape) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
switch (it->getType()) {
|
||||
case ege::physics::Shape::type::box: {
|
||||
EGE_DEBUG(" Box");
|
||||
const ege::physics::shape::Box* tmpElement = it->toBox();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Box ==> can not cast in BOX");
|
||||
continue;
|
||||
}
|
||||
// Half extents of the box in the x, y and z directions
|
||||
const vec3 halfExtents(tmpElement->getSize().x(),
|
||||
tmpElement->getSize().y(),
|
||||
tmpElement->getSize().z());
|
||||
// Create the box shape
|
||||
ephysics::BoxShape* shape = ETK_NEW(ephysics::BoxShape, halfExtents, 0.0001);
|
||||
m_listShape.pushBack(shape);
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
//orientation = orientation * ephysics::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), it->getOrientation());
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::cylinder: {
|
||||
EGE_DEBUG(" Cylinder");
|
||||
const ege::physics::shape::Cylinder* tmpElement = it->toCylinder();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Cylinder ==> can not cast in Cylinder");
|
||||
continue;
|
||||
}
|
||||
// Create the Cylinder shape
|
||||
ephysics::CylinderShape* shape = ETK_NEW(ephysics::CylinderShape, tmpElement->getRadius(), tmpElement->getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
etk::Quaternion orientation = it->getOrientation() * etk::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), orientation);
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::capsule: {
|
||||
EGE_DEBUG(" Capsule");
|
||||
const ege::physics::shape::Capsule* tmpElement = it->toCapsule();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Capsule ==> can not cast in Capsule");
|
||||
continue;
|
||||
}
|
||||
// Create the Capsule shape
|
||||
ephysics::CapsuleShape* shape = ETK_NEW(ephysics::CapsuleShape, tmpElement->getRadius(), tmpElement->getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
etk::Quaternion orientation = it->getOrientation() * etk::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), orientation);
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::cone: {
|
||||
EGE_DEBUG(" Cone");
|
||||
const ege::physics::shape::Cone* tmpElement = it->toCone();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Cone ==> can not cast in Cone");
|
||||
continue;
|
||||
}
|
||||
// Create the Cone shape
|
||||
ephysics::ConeShape* shape = ETK_NEW(ephysics::ConeShape, tmpElement->getRadius(), tmpElement->getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
etk::Quaternion orientation = it->getOrientation() * etk::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), orientation);
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::sphere: {
|
||||
EGE_DEBUG(" Sphere");
|
||||
const ege::physics::shape::Sphere* tmpElement = it->toSphere();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Sphere ==> can not cast in Sphere");
|
||||
continue;
|
||||
}
|
||||
// Create the box shape
|
||||
ephysics::SphereShape* shape = ETK_NEW(ephysics::SphereShape, tmpElement->getRadius());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
etk::Quaternion orientation = it->getOrientation() * etk::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), orientation);
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::concave: {
|
||||
EGE_DEBUG(" Concave");
|
||||
const ege::physics::shape::Concave* tmpElement = it->toConcave();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" etkConcave ==> can not cast in Concave");
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
static const etk::Vector<vec3> vertices = {vec3(-100.0f,-100.0f,-50.0f),vec3(100.0f,-100.0f,-50.0f),vec3(100.0f,100.0f,-50.0f)};
|
||||
static const etk::Vector<uint32_t> indices = {0,1,2};
|
||||
|
||||
ephysics::TriangleVertexArray* triangleArray = ETK_NEW(ephysics::TriangleVertexArray, vertices, indices);
|
||||
#else
|
||||
ephysics::TriangleVertexArray* triangleArray = ETK_NEW(ephysics::TriangleVertexArray, tmpElement->getVertex(), tmpElement->getIndices());
|
||||
#endif
|
||||
// Now that we have a TriangleVertexArray, we need to create a TriangleMesh and add the TriangleVertexArray into it as a subpart.
|
||||
// Once this is done, we can create the actual ConcaveMeshShape and add it to the body we want to simulate as in the following example:
|
||||
ephysics::TriangleMesh* triangleMesh = ETK_NEW(ephysics::TriangleMesh);
|
||||
// Add the triangle vertex array to the triangle mesh
|
||||
triangleMesh->addSubpart(triangleArray);
|
||||
// Create the concave mesh shape
|
||||
// TODO : Manage memory leak ...
|
||||
ephysics::ConcaveShape* shape = ETK_NEW(ephysics::ConcaveMeshShape, triangleMesh);
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
etk::Quaternion orientation = it->getOrientation() * etk::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
etk::Transform3D transform(it->getOrigin(), it->getOrientation());
|
||||
ephysics::ProxyShape* proxyShape = m_rigidBody->addCollisionShape(shape, transform, it->getMass());
|
||||
proxyShape->setUserData(this);
|
||||
m_listProxyShape.pushBack(proxyShape);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
EGE_DEBUG(" ???");
|
||||
// TODO: UNKNOW type ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ege::physics::Component::emitAll() {
|
||||
// emit onbly of new ...
|
||||
etk::Transform3D transform = getTransform();
|
||||
if (m_lastTransformEmit != transform) {
|
||||
m_lastTransformEmit = transform;
|
||||
signalPosition.emit(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Component::update(float _delta) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
if (m_staticForceApplyCenterOfMass != vec3(0,0,0)) {
|
||||
vec3 tmp = m_staticForceApplyCenterOfMass*_delta;
|
||||
EGE_ERROR("FORCE : " << tmp );
|
||||
m_rigidBody->applyForceToCenterOfMass(tmp);
|
||||
}
|
||||
if (m_staticTorqueApply != vec3(0,0,0)) {
|
||||
vec3 tmp = m_staticTorqueApply*_delta;
|
||||
EGE_ERROR("TORQUE : " << tmp);
|
||||
m_rigidBody->applyTorque(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ege::physics::Component::setTransform(const etk::Transform3D& _transform) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
m_rigidBody->setTransform(_transform);
|
||||
}
|
||||
|
||||
etk::Transform3D ege::physics::Component::getTransform() const {
|
||||
if (m_rigidBody == null) {
|
||||
return etk::Transform3D::identity();
|
||||
}
|
||||
return m_rigidBody->getTransform();
|
||||
}
|
||||
|
||||
vec3 ege::physics::Component::getLinearVelocity() const {
|
||||
if (m_rigidBody == null) {
|
||||
return vec3(0,0,0);
|
||||
}
|
||||
return m_rigidBody->getLinearVelocity();
|
||||
}
|
||||
|
||||
void ege::physics::Component::setLinearVelocity(const vec3& _linearVelocity) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
m_rigidBody->setLinearVelocity(_linearVelocity);
|
||||
}
|
||||
|
||||
vec3 ege::physics::Component::getRelativeLinearVelocity() const {
|
||||
if (m_rigidBody == null) {
|
||||
return vec3(0,0,0);
|
||||
}
|
||||
vec3 value = m_rigidBody->getLinearVelocity();
|
||||
return m_rigidBody->getTransform().getOrientation().getInverse()*value;
|
||||
}
|
||||
|
||||
void ege::physics::Component::setRelativeLinearVelocity(const vec3& _linearVelocity) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
vec3 value = m_rigidBody->getTransform().getOrientation()*_linearVelocity;
|
||||
m_rigidBody->setLinearVelocity(value);
|
||||
}
|
||||
|
||||
vec3 ege::physics::Component::getAngularVelocity() const {
|
||||
if (m_rigidBody == null) {
|
||||
return vec3(0,0,0);
|
||||
}
|
||||
return m_rigidBody->getAngularVelocity();
|
||||
}
|
||||
void ege::physics::Component::setAngularVelocity(const vec3& _angularVelocity) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
m_rigidBody->setAngularVelocity(_angularVelocity);
|
||||
}
|
||||
|
||||
vec3 ege::physics::Component::getRelativeAngularVelocity() const {
|
||||
if (m_rigidBody == null) {
|
||||
return vec3(0,0,0);
|
||||
}
|
||||
vec3 value = m_rigidBody->getAngularVelocity();
|
||||
return m_rigidBody->getTransform().getOrientation().getInverse()*value;
|
||||
}
|
||||
void ege::physics::Component::setRelativeAngularVelocity(const vec3& _angularVelocity) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
vec3 value = m_rigidBody->getTransform().getOrientation()*_angularVelocity;
|
||||
m_rigidBody->setAngularVelocity(value);
|
||||
}
|
||||
|
||||
|
||||
void ege::physics::Component::applyForce(const vec3& _force,const vec3& _point) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
m_rigidBody->applyForce(_force, _point);
|
||||
}
|
||||
|
||||
void ege::physics::Component::applyForceToCenterOfMass(const vec3& _force, bool _static) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
if(_static == true) {
|
||||
m_staticForceApplyCenterOfMass = _force;
|
||||
} else {
|
||||
m_rigidBody->applyForceToCenterOfMass(_force);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Component::applyRelativeForceToCenterOfMass(const vec3& _force, bool _static) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
vec3 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 == null) {
|
||||
return;
|
||||
}
|
||||
if(_static == true) {
|
||||
m_staticTorqueApply = _torque;
|
||||
} else {
|
||||
m_rigidBody->applyTorque(_torque);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Component::applyRelativeTorque(const vec3& _torque, bool _static) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
vec3 torque = m_rigidBody->getTransform().getOrientation()*_torque;
|
||||
if(_static == true) {
|
||||
m_staticTorqueApply = torque;
|
||||
} else {
|
||||
m_rigidBody->applyTorque(torque);
|
||||
}
|
||||
}
|
||||
|
||||
const etk::Vector<ememory::SharedPtr<ege::physics::Shape>>& ege::physics::Component::getShape() const {
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
void ege::physics::Component::setShape(const etk::Vector<ememory::SharedPtr<ege::physics::Shape>>& _prop) {
|
||||
m_shape = _prop;
|
||||
}
|
||||
|
||||
void ege::physics::Component::addShape(const ememory::SharedPtr<ege::physics::Shape>& _shape) {
|
||||
m_shape.pushBack(_shape);
|
||||
}
|
||||
|
||||
|
||||
void ege::physics::Component::drawShape(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
etk::Transform3D transform = getTransform();
|
||||
float mmm[16];
|
||||
// Get the OpenGL matrix array of the transform
|
||||
transform.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrix(mmm);
|
||||
transformationMatrix.transpose();
|
||||
etk::Color<float> tmpColor(1.0, 0.0, 0.0, 0.3);
|
||||
for (auto &it: m_shape) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
switch (it->getType()) {
|
||||
case ege::physics::Shape::type::box: {
|
||||
EGE_DEBUG(" Box");
|
||||
const ege::physics::shape::Box* tmpElement = it->toBox();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Box ==> can not cast in BOX");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
_draw->drawSquare(tmpElement->getSize(), transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::cylinder: {
|
||||
EGE_DEBUG(" Cylinder");
|
||||
const ege::physics::shape::Cylinder* tmpElement = it->toCylinder();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Cylinder ==> can not cast in Cylinder");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
_draw->drawCylinder(tmpElement->getRadius(), tmpElement->getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::capsule: {
|
||||
EGE_DEBUG(" Capsule");
|
||||
const ege::physics::shape::Capsule* tmpElement = it->toCapsule();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Capsule ==> can not cast in Capsule");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
_draw->drawCapsule(tmpElement->getRadius(), tmpElement->getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::cone: {
|
||||
EGE_DEBUG(" Cone");
|
||||
const ege::physics::shape::Cone* tmpElement = it->toCone();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Cone ==> can not cast in Cone");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
_draw->drawCone(tmpElement->getRadius(), tmpElement->getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::sphere: {
|
||||
EGE_DEBUG(" Sphere");
|
||||
const ege::physics::shape::Sphere* tmpElement = it->toSphere();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" Sphere ==> can not cast in Sphere");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
_draw->drawSphere(tmpElement->getRadius(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::concave: {
|
||||
EGE_DEBUG(" concave");
|
||||
const ege::physics::shape::Concave* tmpElement = it->toConcave();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" concave ==> can not cast in convexHull");
|
||||
continue;
|
||||
}
|
||||
etk::Transform3D transformLocal(it->getOrigin(), it->getOrientation());
|
||||
transformLocal.getOpenGLMatrix(mmm);
|
||||
mat4 transformationMatrixLocal(mmm);
|
||||
transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix * transformationMatrixLocal;
|
||||
|
||||
_draw->drawTriangles(tmpElement->getVertex(), tmpElement->getIndices(), transformationMatrixLocal, tmpColor);
|
||||
break;
|
||||
}
|
||||
case ege::physics::Shape::type::convexHull: {
|
||||
EGE_DEBUG(" convexHull");
|
||||
const ege::physics::shape::ConvexHull* tmpElement = it->toConvexHull();
|
||||
if (tmpElement == null) {
|
||||
EGE_ERROR(" convexHull ==> can not cast in convexHull");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
EGE_DEBUG(" ???");
|
||||
// TODO: UNKNOW type ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Component::drawAABB(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
|
||||
if (m_rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
mat4 transformationMatrix;
|
||||
etk::Color<float> tmpColor(0.0, 1.0, 0.0, 0.8);
|
||||
ephysics::AABB value = m_rigidBody->getAABB();
|
||||
_draw->drawCubeLine(value.getMin(), value.getMax(), tmpColor, transformationMatrix);
|
||||
|
||||
}
|
188
ege/physics/Component.hpp
Normal file
188
ege/physics/Component.hpp
Normal file
@ -0,0 +1,188 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
#include <ege/Component.hpp>
|
||||
#include <etk/math/Transform3D.hpp>
|
||||
#include <esignal/Signal.hpp>
|
||||
#include <ephysics/ephysics.hpp>
|
||||
#include <ege/resource/Mesh.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
|
||||
namespace ege {
|
||||
class Environement;
|
||||
namespace physics {
|
||||
class Engine;
|
||||
class Component :
|
||||
public ege::Component/*,
|
||||
public ephysics::CollisionCallback*/ {
|
||||
public:
|
||||
esignal::Signal<etk::Transform3D> signalPosition;
|
||||
protected:
|
||||
etk::Transform3D m_lastTransformEmit;
|
||||
protected:
|
||||
ememory::SharedPtr<ege::physics::Engine> m_engine;
|
||||
ephysics::RigidBody* m_rigidBody;
|
||||
etk::Vector<ephysics::CollisionShape*> m_listShape;
|
||||
etk::Vector<ephysics::ProxyShape*> m_listProxyShape;
|
||||
public:
|
||||
/**
|
||||
* @brief Create a basic position component (no orientation and position (0,0,0))
|
||||
*/
|
||||
Component(ememory::SharedPtr<ege::Environement> _env);
|
||||
/**
|
||||
* @brief Create a basic position component
|
||||
* @param[in] _transform transformation of the position
|
||||
*/
|
||||
Component(ememory::SharedPtr<ege::Environement> _env, const etk::Transform3D& _transform);
|
||||
~Component();
|
||||
public:
|
||||
virtual const etk::String& getType() const override;
|
||||
|
||||
enum class type {
|
||||
bodyDynamic,
|
||||
bodyStatic,
|
||||
bodyKinematic
|
||||
};
|
||||
void setType(enum ege::physics::Component::type _type);
|
||||
/**
|
||||
* @brief set a new transformation
|
||||
* @param[in] _transform transformation of the position
|
||||
*/
|
||||
void setTransform(const etk::Transform3D& _transform);
|
||||
/**
|
||||
* @brief set a new transformation
|
||||
* @return Transformation of the position
|
||||
*/
|
||||
etk::Transform3D getTransform() const;
|
||||
/**
|
||||
* @brief Get the linear velocity (whole world).
|
||||
* @return The linear velocity vector of the body
|
||||
*/
|
||||
vec3 getLinearVelocity() const;
|
||||
/**
|
||||
* @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 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 (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:
|
||||
vec3 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:
|
||||
vec3 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:
|
||||
etk::Vector<ememory::SharedPtr<ege::physics::Shape>> m_shape; //!< collision shape module ... (independent of bullet lib)
|
||||
public:
|
||||
const etk::Vector<ememory::SharedPtr<ege::physics::Shape>>& getShape() const;
|
||||
void setShape(const etk::Vector<ememory::SharedPtr<ege::physics::Shape>>& _prop);
|
||||
void addShape(const ememory::SharedPtr<ege::physics::Shape>& _shape);
|
||||
void generate();
|
||||
void drawShape(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
|
||||
void drawAABB(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _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:
|
||||
/**
|
||||
* @brief Called when a new contact point is found between two bodies that were separated before.
|
||||
* @param[in] _other The other component that have the impact
|
||||
* @param[in] _normal Normal of the impact
|
||||
* @param[in] _pos Position of the impact at the current object
|
||||
* @param[in] _posOther Position of the impact at the other object
|
||||
* @param[in] _penetrationDepth Depth penetration in the object
|
||||
*/
|
||||
void beginContact(ege::physics::Component* _other, const vec3& _normal, const vec3& _pos, const vec3& _posOther, float _penetrationDepth);
|
||||
/**
|
||||
* @brief Called when a new contact point is found between two bodies.
|
||||
* @param[in] _other The other component that have the impact
|
||||
* @param[in] _normal Normal of the impact
|
||||
* @param[in] _pos Position of the impact at the current object
|
||||
* @param[in] _posOther Position of the impact at the other object
|
||||
* @param[in] _penetrationDepth Depth penetration in the object
|
||||
*/
|
||||
void newContact(ege::physics::Component* _other, const vec3& _normal, const vec3& _pos, const vec3& _posOther, float _penetrationDepth);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,136 +1,249 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <ege/Entity.hpp>
|
||||
#include <ege/physics/Engine.hpp>
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <LinearMath/btTransformUtil.h>
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
|
||||
#include <ege/elements/ElementPhysic.hpp>
|
||||
|
||||
|
||||
// unique callback function :
|
||||
extern ContactProcessedCallback gContactProcessedCallback;
|
||||
|
||||
// TODO : remove double collision call ...
|
||||
static bool handleContactsProcess(btManifoldPoint& _point, btCollisionObject* _body0, btCollisionObject* _body1) {
|
||||
ege::ElementPhysic* elem0 = static_cast<ege::ElementPhysic*>(_body0->getUserPointer());
|
||||
ege::ElementPhysic* elem1 = static_cast<ege::ElementPhysic*>(_body1->getUserPointer());
|
||||
if ( elem0 == nullptr
|
||||
|| elem1 == nullptr) {
|
||||
EGE_WARNING("callback of collision error");
|
||||
return false;
|
||||
}
|
||||
EGE_VERBOSE("collision process between " << elem0->getUID() << " && " << elem1->getUID() << " pos=" << _point.getPositionWorldOnA() << " norm=" << _point.m_normalWorldOnB);
|
||||
if (elem0->getCollisionDetectionStatus() == true) {
|
||||
elem0->onCollisionDetected(elem1->sharedFromThis(), _point.getPositionWorldOnA(), -_point.m_normalWorldOnB);
|
||||
}
|
||||
if (elem1->getCollisionDetectionStatus() == true) {
|
||||
elem1->onCollisionDetected(elem0->sharedFromThis(), _point.getPositionWorldOnA(), _point.m_normalWorldOnB);
|
||||
}
|
||||
return true;
|
||||
const etk::String& ege::physics::Engine::getType() const {
|
||||
static etk::String tmp("physics");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
ege::physics::Engine::Engine() {
|
||||
setBulletConfig();
|
||||
// set callback for collisions ...
|
||||
gContactProcessedCallback = (ContactProcessedCallback)handleContactsProcess;
|
||||
void ege::physics::Engine::beginContact(const ephysics::ContactPointInfo& _contact) {
|
||||
ege::physics::Component* component1 = null;
|
||||
ege::physics::Component* component2 = null;
|
||||
// Called when a new contact point is found between two bodies that were separated before.
|
||||
EGE_WARNING("collision detection [BEGIN] " << _contact.localPoint1 << " depth=" << _contact.penetrationDepth);
|
||||
if ( _contact.shape1 != null
|
||||
&& _contact.shape1->getUserData() != null) {
|
||||
component1 = static_cast<ege::physics::Component*>(_contact.shape1->getUserData());
|
||||
}
|
||||
if ( _contact.shape2 != null
|
||||
&& _contact.shape2->getUserData() != null) {
|
||||
component2 = static_cast<ege::physics::Component*>(_contact.shape2->getUserData());
|
||||
}
|
||||
if (component1 != null) {
|
||||
component1->beginContact(component2, _contact.normal, _contact.localPoint1, _contact.localPoint2, _contact.penetrationDepth);
|
||||
}
|
||||
if (component2 != null) {
|
||||
component2->beginContact(component1, -_contact.normal, _contact.localPoint2, _contact.localPoint1, _contact.penetrationDepth);
|
||||
}
|
||||
}
|
||||
|
||||
ege::physics::Engine::~Engine() {
|
||||
/*
|
||||
m_dynamicsWorld.release();
|
||||
m_solver.release();
|
||||
m_broadphase.release();
|
||||
m_dispatcher.release();
|
||||
m_collisionConfiguration.release();
|
||||
*/
|
||||
void ege::physics::Engine::newContact(const ephysics::ContactPointInfo& _contact) {
|
||||
ege::physics::Component* component1 = null;
|
||||
ege::physics::Component* component2 = null;
|
||||
//Called when a new contact point is found between two bodies.
|
||||
EGE_WARNING("collision detection [ NEW ] " << _contact.localPoint1 << " depth=" << _contact.penetrationDepth);
|
||||
if ( _contact.shape1 != null
|
||||
&& _contact.shape1->getUserData() != null) {
|
||||
component1 = static_cast<ege::physics::Component*>(_contact.shape1->getUserData());
|
||||
}
|
||||
if ( _contact.shape2 != null
|
||||
&& _contact.shape2->getUserData() != null) {
|
||||
component2 = static_cast<ege::physics::Component*>(_contact.shape2->getUserData());
|
||||
}
|
||||
if (component1 != null) {
|
||||
component1->newContact(component2, _contact.normal, _contact.localPoint1, _contact.localPoint2, _contact.penetrationDepth);
|
||||
}
|
||||
if (component2 != null) {
|
||||
component2->newContact(component1, -_contact.normal, _contact.localPoint2, _contact.localPoint1, _contact.penetrationDepth);
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Engine::setBulletConfig(ememory::SharedPtr<btDefaultCollisionConfiguration> _collisionConfiguration,
|
||||
ememory::SharedPtr<btCollisionDispatcher> _dispatcher,
|
||||
ememory::SharedPtr<btBroadphaseInterface> _broadphase,
|
||||
ememory::SharedPtr<btConstraintSolver> _solver,
|
||||
ememory::SharedPtr<btDynamicsWorld> _dynamicsWorld) {
|
||||
if (_collisionConfiguration != nullptr) {
|
||||
m_collisionConfiguration = _collisionConfiguration;
|
||||
} else {
|
||||
m_collisionConfiguration = ememory::makeShared<btDefaultCollisionConfiguration>();
|
||||
void ege::physics::Engine::componentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
ememory::SharedPtr<ege::physics::Component> ref = ememory::dynamicPointerCast<ege::physics::Component>(_ref);
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it == ref) {
|
||||
it->reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
///use the default collision dispatcher.
|
||||
if (_dispatcher != nullptr) {
|
||||
m_dispatcher = _dispatcher;
|
||||
} else {
|
||||
m_dispatcher = ememory::makeShared<btCollisionDispatcher>(m_collisionConfiguration.get());
|
||||
}
|
||||
if (_broadphase != nullptr) {
|
||||
m_broadphase = _broadphase;
|
||||
} else {
|
||||
m_broadphase = ememory::makeShared<btDbvtBroadphase>();
|
||||
}
|
||||
|
||||
///the default constraint solver.
|
||||
if (_solver != nullptr) {
|
||||
m_solver = _solver;
|
||||
} else {
|
||||
m_solver = ememory::makeShared<btSequentialImpulseConstraintSolver>();
|
||||
}
|
||||
|
||||
if (_dynamicsWorld != nullptr) {
|
||||
m_dynamicsWorld = _dynamicsWorld;
|
||||
} else {
|
||||
m_dynamicsWorld = ememory::makeShared<btDiscreteDynamicsWorld>(m_dispatcher.get(),m_broadphase.get(),m_solver.get(),m_collisionConfiguration.get());
|
||||
// By default we set no gravity
|
||||
m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
||||
}
|
||||
//m_env.setDynamicWorld(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
// some doccumantation : http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
|
||||
std::vector<ege::physics::Engine::collisionPoints> ege::physics::Engine::getListOfCollision() {
|
||||
std::vector<collisionPoints> out;
|
||||
if (m_dynamicsWorld != nullptr) {
|
||||
int32_t numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
|
||||
for (int i=0;i<numManifolds;i++) {
|
||||
btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
||||
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
|
||||
const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
|
||||
if ( obA == nullptr
|
||||
|| obB == nullptr) {
|
||||
continue;
|
||||
}
|
||||
ege::ElementPhysic* elem0 = static_cast<ege::ElementPhysic*>(obA->getUserPointer());
|
||||
ege::ElementPhysic* elem1 = static_cast<ege::ElementPhysic*>(obB->getUserPointer());
|
||||
if ( elem0 == nullptr
|
||||
|| elem1 == nullptr) {
|
||||
continue;
|
||||
}
|
||||
int numContacts = contactManifold->getNumContacts();
|
||||
for (int j=0;j<numContacts;j++) {
|
||||
btManifoldPoint& pt = contactManifold->getContactPoint(j);
|
||||
if (pt.getDistance()<0.f) {
|
||||
out.push_back(collisionPoints(elem0->sharedFromThis(), elem1->sharedFromThis(), pt.getPositionWorldOnA(), pt.getPositionWorldOnB(), pt.m_normalWorldOnB));
|
||||
void ege::physics::Engine::componentAdd(const ememory::SharedPtr<ege::Component>& _ref) {
|
||||
ememory::SharedPtr<ege::physics::Component> ref = ememory::dynamicPointerCast<ege::physics::Component>(_ref);
|
||||
#if DEBUG
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it != null) {
|
||||
if (*it == ref) {
|
||||
EGE_ERROR("Try Add multiple time the same Component in the Physic Engine " << uint64_t(ref.get()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (auto it=m_component.begin();
|
||||
it != m_component.end();
|
||||
++it) {
|
||||
if (*it == null) {
|
||||
*it = ref;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
m_component.pushBack(ref);
|
||||
}
|
||||
|
||||
ege::physics::Engine::Engine(ege::Environement* _env) :
|
||||
ege::Engine(_env),
|
||||
propertyDebugAABB(this, "debug-AABB", false, "display the global AABB box of every shape"),
|
||||
propertyDebugShape(this, "debug-shape", false, "display the physic shape"),
|
||||
m_dynamicsWorld(null),
|
||||
m_accumulator(0.0f) {
|
||||
m_debugDrawProperty = ewol::resource::Colored3DObject::create();
|
||||
// Start engine with no gravity
|
||||
vec3 gravity(0.0f, 0.0f, 0.0f);
|
||||
// Create the dynamics world
|
||||
m_dynamicsWorld = ETK_NEW(ephysics::DynamicsWorld, gravity);
|
||||
if (m_dynamicsWorld != null) {
|
||||
// Set the number of iterations of the constraint solver
|
||||
m_dynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
m_dynamicsWorld->setEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
ege::physics::Engine::~Engine() {
|
||||
if (m_dynamicsWorld != null) {
|
||||
m_dynamicsWorld->setEventListener(null);
|
||||
ETK_DELETE(ephysics::DynamicsWorld, m_dynamicsWorld);
|
||||
m_dynamicsWorld = null;
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Engine::setGravity(const vec3& _axePower) {
|
||||
if (m_dynamicsWorld != null) {
|
||||
vec3 gravity(_axePower);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
}
|
||||
}
|
||||
|
||||
// Constant physics time step
|
||||
static const float timeStep = 1.0 / 60.0;
|
||||
|
||||
void ege::physics::Engine::update(const echrono::Duration& _delta) {
|
||||
float deltaTime = _delta.toSeconds();
|
||||
// Add the time difference in the accumulator
|
||||
m_accumulator += deltaTime;
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (m_accumulator >= timeStep) {
|
||||
if (m_dynamicsWorld != null) {
|
||||
// call every object to usdate their constant forces applyed
|
||||
for (auto &it: m_component) {
|
||||
// check null pointer
|
||||
if (it == null) {
|
||||
// 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);
|
||||
}
|
||||
// Decrease the accumulated time
|
||||
m_accumulator -= timeStep;
|
||||
}
|
||||
for (auto &it: m_component) {
|
||||
// check null pointer
|
||||
if (it == null) {
|
||||
// no pointer null are set in the output list ...
|
||||
continue;
|
||||
}
|
||||
it->emitAll();
|
||||
}
|
||||
}
|
||||
|
||||
void ege::physics::Engine::renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) {
|
||||
if (propertyDebugShape.get() == true) {
|
||||
for (auto &it : m_component) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
it->drawShape(m_debugDrawProperty, _camera);
|
||||
}
|
||||
}
|
||||
if (propertyDebugAABB.get() == true) {
|
||||
for (auto &it : m_component) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
it->drawAABB(m_debugDrawProperty, _camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyCallbackClass : public ephysics::RaycastCallback {
|
||||
public:
|
||||
vec3 m_position;
|
||||
vec3 m_normal;
|
||||
bool m_haveImpact;
|
||||
ephysics::CollisionBody* m_body;
|
||||
MyCallbackClass():
|
||||
m_haveImpact(false),
|
||||
m_body(null) {
|
||||
|
||||
}
|
||||
public:
|
||||
virtual float notifyRaycastHit(const ephysics::RaycastInfo& _info) {
|
||||
m_haveImpact = true;
|
||||
// Display the world hit point coordinates
|
||||
m_position = _info.worldPoint;
|
||||
m_normal = _info.worldNormal;
|
||||
m_body = _info.body;
|
||||
EGE_WARNING("Hit point: " << m_position);
|
||||
// Return a fraction of 1.0 to gather all hits
|
||||
return 1.0f;
|
||||
}
|
||||
};
|
||||
|
||||
etk::Pair<vec3,vec3> ege::physics::Engine::testRay(const ege::Ray& _ray) {
|
||||
vec3 start = _ray.getOrigin();
|
||||
vec3 stop = _ray.getOrigin()+_ray.getDirection()*1000.0f;
|
||||
// Start and End are vectors
|
||||
// Create the ray
|
||||
ephysics::Ray ray(start, stop);
|
||||
// Create an instance of your callback class
|
||||
MyCallbackClass callbackObject;
|
||||
// Raycast test
|
||||
m_dynamicsWorld->raycast(ray, &callbackObject);
|
||||
if (callbackObject.m_haveImpact == true) {
|
||||
return etk::Pair<vec3,vec3>(callbackObject.m_position, callbackObject.m_normal);
|
||||
}
|
||||
EGE_VERBOSE(" No Hit");
|
||||
return etk::Pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0));
|
||||
}
|
||||
|
||||
etk::Pair<ememory::SharedPtr<ege::Component>, etk::Pair<vec3,vec3>> ege::physics::Engine::testRayObject(const ege::Ray& _ray) {
|
||||
vec3 start = _ray.getOrigin();
|
||||
vec3 stop = _ray.getOrigin()+_ray.getDirection()*1000.0f;
|
||||
// Start and End are vectors
|
||||
// Create the ray
|
||||
ephysics::Ray ray(start, stop);
|
||||
// Create an instance of your callback class
|
||||
MyCallbackClass callbackObject;
|
||||
// Raycast test
|
||||
m_dynamicsWorld->raycast(ray, &callbackObject);
|
||||
if (callbackObject.m_haveImpact == true) {
|
||||
if ( callbackObject.m_body == null
|
||||
|| callbackObject.m_body->getUserData() == null) {
|
||||
etk::Pair<ememory::SharedPtr<ege::Component>, etk::Pair<vec3,vec3>>(null, etk::Pair<vec3,vec3>(callbackObject.m_position, callbackObject.m_normal));
|
||||
}
|
||||
// TODO: je n'ai pas une entity, main un component ...
|
||||
ege::physics::Component* elem = static_cast<ege::physics::Component*>(callbackObject.m_body->getUserData());
|
||||
return etk::Pair<ememory::SharedPtr<ege::Component>, etk::Pair<vec3,vec3>>(elem->sharedFromThis(), etk::Pair<vec3,vec3>(callbackObject.m_position, callbackObject.m_normal));
|
||||
}
|
||||
EGE_VERBOSE(" No Hit");
|
||||
return etk::Pair<ememory::SharedPtr<ege::Component>, etk::Pair<vec3,vec3>>(null, etk::Pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0)));
|
||||
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/Engine.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
class Engine;
|
||||
@ -12,88 +14,71 @@ namespace ege {
|
||||
};
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Matrix4.hpp>
|
||||
#include <vector>
|
||||
#include <etk/math/Matrix4x4.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <ewol/debug.hpp>
|
||||
#include <ege/camera/Camera.hpp>
|
||||
#include <ewol/widget/Widget.hpp>
|
||||
#include <gale/renderer/openGL/openGL.hpp>
|
||||
#include <gale/resource/Manager.hpp>
|
||||
#include <gale/Dimension.hpp>
|
||||
#include <ephysics/ephysics.hpp>
|
||||
#include <ege/physics/Component.hpp>
|
||||
#include <eproperty/Value.hpp>
|
||||
#include <ege/Ray.hpp>
|
||||
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
class btOverlappingPairCache;
|
||||
class btCollisionDispatcher;
|
||||
class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
class btDynamicsWorld;
|
||||
#include <LinearMath/btScalar.h>
|
||||
class btVector3;
|
||||
|
||||
|
||||
//#include <ege/elements/Element.h>
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
class Engine {
|
||||
class Engine:
|
||||
public ege::Engine,
|
||||
public ephysics::EventListener {
|
||||
public:
|
||||
eproperty::Value<bool> propertyDebugAABB;
|
||||
eproperty::Value<bool> propertyDebugShape;
|
||||
private:
|
||||
///this is the most important class
|
||||
ememory::SharedPtr<btDefaultCollisionConfiguration> m_collisionConfiguration;
|
||||
ememory::SharedPtr<btCollisionDispatcher> m_dispatcher;
|
||||
ememory::SharedPtr<btBroadphaseInterface> m_broadphase;
|
||||
ememory::SharedPtr<btConstraintSolver> m_solver;
|
||||
ememory::SharedPtr<btDynamicsWorld> m_dynamicsWorld;
|
||||
ephysics::DynamicsWorld* m_dynamicsWorld;
|
||||
float m_accumulator; // limit call of the step rendering
|
||||
public:
|
||||
Engine();
|
||||
Engine(ege::Environement* _env);
|
||||
~Engine();
|
||||
void setBulletConfig(ememory::SharedPtr<btDefaultCollisionConfiguration> _collisionConfiguration=nullptr,
|
||||
ememory::SharedPtr<btCollisionDispatcher> _dispatcher=nullptr,
|
||||
ememory::SharedPtr<btBroadphaseInterface> _broadphase=nullptr,
|
||||
ememory::SharedPtr<btConstraintSolver> _solver=nullptr,
|
||||
ememory::SharedPtr<btDynamicsWorld> _dynamicsWorld=nullptr);
|
||||
/**
|
||||
* @brief set the curent world
|
||||
* @param[in] _newWorld Pointer on the current world
|
||||
*/
|
||||
void setDynamicWorld(const ememory::SharedPtr<btDynamicsWorld>& _newWorld) {
|
||||
m_dynamicsWorld=_newWorld;
|
||||
};
|
||||
/**
|
||||
* @brief get the curent world
|
||||
* @return pointer on the current world
|
||||
*/
|
||||
ememory::SharedPtr<btDynamicsWorld> getDynamicWorld() {
|
||||
return m_dynamicsWorld;
|
||||
};
|
||||
public:
|
||||
// Define a collision point ==> for debug only ...
|
||||
//! @not_in_doc
|
||||
class collisionPoints {
|
||||
public:
|
||||
ememory::SharedPtr<ege::Element> elem1;
|
||||
ememory::SharedPtr<ege::Element> elem2;
|
||||
vec3 positionElem1;
|
||||
vec3 positionElem2;
|
||||
vec3 normalElem2;
|
||||
collisionPoints(const ememory::SharedPtr<ege::Element>& _elem1,
|
||||
const ememory::SharedPtr<ege::Element>& _elem2,
|
||||
const vec3& _pos1,
|
||||
const vec3& _pos2,
|
||||
const vec3& _normal) :
|
||||
elem1(_elem1),
|
||||
elem2(_elem2),
|
||||
positionElem1(_pos1),
|
||||
positionElem2(_pos2),
|
||||
normalElem2(_normal) { }
|
||||
};
|
||||
/**
|
||||
* @brief Get the list of all collision point actually availlable ...
|
||||
* @return the requested list of points
|
||||
* @brief Set the gravity axis of the physic engine
|
||||
* @param[in] _axePower energy of this gravity
|
||||
*/
|
||||
std::vector<ege::physics::Engine::collisionPoints> getListOfCollision();
|
||||
void setGravity(const vec3& _axePower);
|
||||
ephysics::DynamicsWorld* getDynamicWorld() {
|
||||
return m_dynamicsWorld;
|
||||
}
|
||||
protected:
|
||||
etk::Vector<ememory::SharedPtr<ege::physics::Component>> m_component;
|
||||
//TODO : set it not in ewol ...
|
||||
ememory::SharedPtr<ewol::resource::Colored3DObject> m_debugDrawProperty;
|
||||
public:
|
||||
const etk::String& getType() const override;
|
||||
void componentRemove(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
void componentAdd(const ememory::SharedPtr<ege::Component>& _ref) override;
|
||||
void update(const echrono::Duration& _delta) override;
|
||||
void renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) override;
|
||||
private:
|
||||
// herited from rp3D::EventListener
|
||||
void beginContact(const ephysics::ContactPointInfo& _contact) override;
|
||||
void newContact(const ephysics::ContactPointInfo& _contact) override;
|
||||
public:
|
||||
/**
|
||||
* @brief Test a rayCasting on the physic engine
|
||||
* @param[in] _ray Ray top test
|
||||
* @return Impact position and normal of the impact (if normal == vec3(0,0,0) then no object impact...
|
||||
*/
|
||||
etk::Pair<vec3,vec3> testRay(const ege::Ray& _ray);
|
||||
/**
|
||||
* @brief Test a rayCasting on the physic engine
|
||||
* @param[in] _ray Ray top test
|
||||
* @return Impact Component, position and normal of the impact (if normal == vec3(0,0,0) then no object impact...
|
||||
*/
|
||||
etk::Pair<ememory::SharedPtr<ege::Component>, etk::Pair<vec3,vec3>> testRayObject(const ege::Ray& _ray);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
21
ege/physics/shape/Box.cpp
Normal file
21
ege/physics/shape/Box.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <ege/physics/shape/Box.hpp>
|
||||
|
||||
|
||||
bool ege::physics::shape::Box::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "half-extents:", 13) == 0) {
|
||||
sscanf(&_line[13], "%f %f %f", &m_size.m_floats[0], &m_size.m_floats[1], &m_size.m_floats[2] );
|
||||
EGE_VERBOSE(" halfSize=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
46
ege/physics/shape/Box.hpp
Normal file
46
ege/physics/shape/Box.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Box : public ege::physics::Shape {
|
||||
public:
|
||||
Box() {};
|
||||
virtual ~Box() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::box;
|
||||
};
|
||||
private:
|
||||
vec3 m_size; // Box size property in X, Y and Z
|
||||
public:
|
||||
const vec3& getSize() const {
|
||||
return m_size;
|
||||
};
|
||||
void setSize(const vec3& _size) {
|
||||
m_size = _size;
|
||||
}
|
||||
public:
|
||||
virtual const ege::physics::shape::Box* toBox() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::physics::shape::Box* toBox() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
ege/physics/shape/Capsule.cpp
Normal file
26
ege/physics/shape/Capsule.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Capsule.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::physics::shape::Capsule::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "size:", 5) == 0) {
|
||||
sscanf(&_line[5], "%f", &m_size );
|
||||
EGE_VERBOSE(" height=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
58
ege/physics/shape/Capsule.hpp
Normal file
58
ege/physics/shape/Capsule.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Capsule : public ege::physics::Shape {
|
||||
public:
|
||||
Capsule() :
|
||||
m_radius(1.0f),
|
||||
m_size(1.0f) {};
|
||||
virtual ~Capsule() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::capsule;
|
||||
}
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
}
|
||||
void setRadius(float _radius) {
|
||||
m_radius = _radius;
|
||||
}
|
||||
private:
|
||||
float m_size;
|
||||
public:
|
||||
float getSize() const {
|
||||
return m_size;
|
||||
}
|
||||
void setSize(float _size) {
|
||||
m_size = _size;
|
||||
}
|
||||
public:
|
||||
virtual const ege::physics::shape::Capsule* toCapsule() const {
|
||||
return this;
|
||||
}
|
||||
virtual ege::physics::shape::Capsule* toCapsule() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
ege/physics/shape/Concave.cpp
Normal file
16
ege/physics/shape/Concave.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Concave.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::physics::shape::Concave::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
70
ege/physics/shape/Concave.hpp
Normal file
70
ege/physics/shape/Concave.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Concave : public ege::physics::Shape {
|
||||
public:
|
||||
Concave() {};
|
||||
virtual ~Concave() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::concave;
|
||||
}
|
||||
public:
|
||||
virtual const ege::physics::shape::Concave* toConcave() const {
|
||||
return this;
|
||||
}
|
||||
virtual ege::physics::shape::Concave* toConcave() {
|
||||
return this;
|
||||
}
|
||||
private:
|
||||
etk::Vector<vec3> m_listVertex;
|
||||
etk::Vector<uint32_t> m_indices;
|
||||
public:
|
||||
void clear() {
|
||||
m_listVertex.clear();
|
||||
m_indices.clear();
|
||||
}
|
||||
void setListOfVertex(const etk::Vector<vec3>& _listVertex) {
|
||||
m_listVertex = _listVertex;
|
||||
}
|
||||
void addTriangle(const etk::Vector<uint32_t>& _index) {
|
||||
/*
|
||||
if (m_indices.size() == 0) {
|
||||
m_indices = _index;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
if (_index.size()%3 != 0 ) {
|
||||
EGE_ERROR("wrong number of faces : " << _index.size() << " ==> not a multiple of 3");
|
||||
return;
|
||||
}
|
||||
for (auto &it: _index) {
|
||||
m_indices.pushBack(it);
|
||||
}
|
||||
}
|
||||
const etk::Vector<vec3>& getVertex() const {
|
||||
return m_listVertex;
|
||||
}
|
||||
const etk::Vector<uint32_t>& getIndices() const {
|
||||
return m_indices;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
ege/physics/shape/Cone.cpp
Normal file
26
ege/physics/shape/Cone.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Cone.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::physics::shape::Cone::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "size:", 5) == 0) {
|
||||
sscanf(&_line[5], "%f", &m_size );
|
||||
EGE_VERBOSE(" size=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
54
ege/physics/shape/Cone.hpp
Normal file
54
ege/physics/shape/Cone.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Cone : public ege::physics::Shape {
|
||||
public:
|
||||
Cone() {};
|
||||
virtual ~Cone() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::cone;
|
||||
};
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
}
|
||||
void setRadius(float _radius) {
|
||||
m_radius = _radius;
|
||||
}
|
||||
private:
|
||||
float m_size;
|
||||
public:
|
||||
float getSize() const {
|
||||
return m_size;
|
||||
}
|
||||
void setSize(float _size) {
|
||||
m_size = _size;
|
||||
}
|
||||
public:
|
||||
virtual const ege::physics::shape::Cone* toCone() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::physics::shape::Cone* toCone() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,41 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsConvexHull.hpp>
|
||||
#include <ege/physics/shape/ConvexHull.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::PhysicsConvexHull::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
bool ege::physics::shape::ConvexHull::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "points : ", 8) == 0) {
|
||||
if(strncmp(_line, "points:", 6) == 0) {
|
||||
//EGE_DEBUG("convex hull point parsing " << _line);
|
||||
char* base = (char*)(&_line[8]);
|
||||
char* base = (char*)(&_line[6]);
|
||||
char* tmp= strchr(base, '|');
|
||||
vec3 pos(0,0,0);
|
||||
while (tmp != nullptr) {
|
||||
while (tmp != null) {
|
||||
*tmp = '\0';
|
||||
sscanf(base, "%f %f %f", &pos.m_floats[0], &pos.m_floats[1], &pos.m_floats[2] );
|
||||
m_points.push_back(pos);
|
||||
m_points.pushBack(pos);
|
||||
base = tmp+1;
|
||||
tmp= strchr(base, '|');
|
||||
}
|
||||
sscanf(base, "%f %f %f", &pos.m_floats[0], &pos.m_floats[1], &pos.m_floats[2] );
|
||||
m_points.push_back(pos);
|
||||
m_points.pushBack(pos);
|
||||
/*
|
||||
for (int32_t iii=0; iii<m_points.size(); iii++) {
|
||||
EGE_VERBOSE(" parsed " << m_points[iii]);
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "scale : ", 8) == 0) {
|
||||
sscanf(&_line[8], "%f %f %f", &m_scale.m_floats[0], &m_scale.m_floats[1], &m_scale.m_floats[2] );
|
||||
if(strncmp(_line, "scale:", 6) == 0) {
|
||||
sscanf(&_line[6], "%f %f %f", &m_scale.m_floats[0], &m_scale.m_floats[1], &m_scale.m_floats[2] );
|
||||
EGE_VERBOSE(" scale=" << m_scale);
|
||||
return true;
|
||||
}
|
48
ege/physics/shape/ConvexHull.hpp
Normal file
48
ege/physics/shape/ConvexHull.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class ConvexHull : public ege::physics::Shape {
|
||||
public:
|
||||
ConvexHull() {};
|
||||
virtual ~ConvexHull() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::convexHull;
|
||||
};
|
||||
private:
|
||||
vec3 m_scale;
|
||||
public:
|
||||
vec3 getScale() const {
|
||||
return m_scale;
|
||||
};
|
||||
private:
|
||||
etk::Vector<vec3> m_points;
|
||||
public:
|
||||
const etk::Vector<vec3>& getPointList() const {
|
||||
return m_points;
|
||||
};
|
||||
public:
|
||||
virtual const ege::physics::shape::ConvexHull* toConvexHull() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::physics::shape::ConvexHull* toConvexHull() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
ege/physics/shape/Cylinder.cpp
Normal file
25
ege/physics/shape/Cylinder.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Cylinder.hpp>
|
||||
|
||||
|
||||
bool ege::physics::shape::Cylinder::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "size:", 5) == 0) {
|
||||
sscanf(&_line[5], "%f", &m_size );
|
||||
EGE_VERBOSE(" size=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
58
ege/physics/shape/Cylinder.hpp
Normal file
58
ege/physics/shape/Cylinder.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Cylinder : public ege::physics::Shape {
|
||||
public:
|
||||
Cylinder() :
|
||||
m_radius(1.0f),
|
||||
m_size(1.0f) {};
|
||||
virtual ~Cylinder() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::cylinder;
|
||||
};
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
}
|
||||
void setRadius(float _radius) {
|
||||
m_radius = _radius;
|
||||
}
|
||||
private:
|
||||
float m_size;
|
||||
public:
|
||||
float getSize() const {
|
||||
return m_size;
|
||||
}
|
||||
void setSize(float _size) {
|
||||
m_size = _size;
|
||||
}
|
||||
public:
|
||||
virtual const ege::physics::shape::Cylinder* toCylinder() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::physics::shape::Cylinder* toCylinder() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
63
ege/physics/shape/Shape.cpp
Normal file
63
ege/physics/shape/Shape.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
#include <ege/physics/shape/Box.hpp>
|
||||
#include <ege/physics/shape/Capsule.hpp>
|
||||
#include <ege/physics/shape/Cone.hpp>
|
||||
#include <ege/physics/shape/ConvexHull.hpp>
|
||||
#include <ege/physics/shape/Cylinder.hpp>
|
||||
#include <ege/physics/shape/Sphere.hpp>
|
||||
#include <ege/physics/shape/Concave.hpp>
|
||||
|
||||
|
||||
ememory::SharedPtr<ege::physics::Shape> ege::physics::Shape::create(const etk::String& _name) {
|
||||
ememory::SharedPtr<ege::physics::Shape> tmpp = null;
|
||||
etk::String name = etk::toLower(_name);
|
||||
if (name == "box") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Box>();
|
||||
} else if (name == "sphere") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Sphere>();
|
||||
} else if (name == "cone") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Cone>();
|
||||
} else if (name == "cylinder") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Cylinder>();
|
||||
} else if (name == "capsule") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Capsule>();
|
||||
} else if (name == "convexhull") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::ConvexHull>();
|
||||
} else if (name == "autoconcave") {
|
||||
tmpp = ememory::makeShared<ege::physics::shape::Concave>();
|
||||
} else {
|
||||
EGE_ERROR("Create an unknow element : '" << _name << "' availlable : [BOX,SPHERE,CONE,CYLINDER,CAPSULE,CONVEXHULL,autoConcave]");
|
||||
return null;
|
||||
}
|
||||
if (tmpp == null) {
|
||||
EGE_ERROR("Allocation error for physical element : '" << _name << "'");
|
||||
}
|
||||
return tmpp;
|
||||
}
|
||||
|
||||
|
||||
bool ege::physics::Shape::parse(const char* _line) {
|
||||
if(strncmp(_line, "origin:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f %f %f", &m_origin.m_floats[0], &m_origin.m_floats[1], &m_origin.m_floats[2] );
|
||||
EGE_VERBOSE(" Origin=" << m_origin);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "rotate:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f %f %f %f", &m_quaternion.m_floats[0], &m_quaternion.m_floats[1], &m_quaternion.m_floats[2], &m_quaternion.m_floats[3] );
|
||||
EGE_VERBOSE(" rotate=" << m_quaternion);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "mass:", 5) == 0) {
|
||||
sscanf(&_line[5], "%f", &m_mass );
|
||||
EGE_VERBOSE(" mass=" << m_mass);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
153
ege/physics/shape/Shape.hpp
Normal file
153
ege/physics/shape/Shape.hpp
Normal file
@ -0,0 +1,153 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector4D.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <etk/math/Quaternion.hpp>
|
||||
#include <ememory/memory.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Box;
|
||||
class Cylinder;
|
||||
class Capsule;
|
||||
class Cone;
|
||||
class ConvexHull;
|
||||
class Sphere;
|
||||
class Concave;
|
||||
}
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
static ememory::SharedPtr<ege::physics::Shape> create(const etk::String& _name);
|
||||
public:
|
||||
enum class type {
|
||||
unknow,
|
||||
box,
|
||||
capsule,
|
||||
cone,
|
||||
convexHull,
|
||||
cylinder,
|
||||
sphere,
|
||||
concave
|
||||
};
|
||||
public:
|
||||
Shape() :
|
||||
m_quaternion(0,0,0,1),
|
||||
m_origin(0,0,0),
|
||||
m_mass(1) { // by default set mass at 1g
|
||||
|
||||
}
|
||||
virtual ~Shape() = default;
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::unknow;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {
|
||||
|
||||
}
|
||||
private:
|
||||
etk::Quaternion m_quaternion;
|
||||
public:
|
||||
etk::Quaternion getOrientation() const {
|
||||
return etk::Quaternion(m_quaternion.x(), m_quaternion.y(), m_quaternion.z(), m_quaternion.w());
|
||||
}
|
||||
private:
|
||||
vec3 m_origin;
|
||||
public:
|
||||
const vec3& getOrigin() const {
|
||||
return m_origin;
|
||||
};
|
||||
private:
|
||||
float m_mass; //!< element mass in "g" then 1000 for 1kg
|
||||
public:
|
||||
float getMass() const {
|
||||
return m_mass;
|
||||
}
|
||||
void setMass(float _mass) {
|
||||
m_mass = _mass;
|
||||
}
|
||||
public:
|
||||
bool isBox() {
|
||||
return getType() == ege::physics::Shape::type::box;
|
||||
};
|
||||
bool isCylinder() {
|
||||
return getType() == ege::physics::Shape::type::cylinder;
|
||||
};
|
||||
bool isCapsule() {
|
||||
return getType() == ege::physics::Shape::type::capsule;
|
||||
};
|
||||
bool isCone() {
|
||||
return getType() == ege::physics::Shape::type::cone;
|
||||
};
|
||||
bool isConvexHull() {
|
||||
return getType() == ege::physics::Shape::type::convexHull;
|
||||
};
|
||||
bool isSphere() {
|
||||
return getType() == ege::physics::Shape::type::sphere;
|
||||
};
|
||||
bool isConcave() {
|
||||
return getType() == ege::physics::Shape::type::concave;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::Box* toBox() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Box* toBox() {
|
||||
return null;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::Cylinder* toCylinder() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Cylinder* toCylinder() {
|
||||
return null;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::Capsule* toCapsule() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Capsule* toCapsule() {
|
||||
return null;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::Cone* toCone() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Cone* toCone() {
|
||||
return null;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::ConvexHull* toConvexHull() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::ConvexHull* toConvexHull() {
|
||||
return null;
|
||||
};
|
||||
|
||||
virtual const ege::physics::shape::Sphere* toSphere() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Sphere* toSphere() {
|
||||
return null;
|
||||
};
|
||||
virtual const ege::physics::shape::Concave* toConcave() const {
|
||||
return null;
|
||||
};
|
||||
virtual ege::physics::shape::Concave* toConcave() {
|
||||
return null;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
23
ege/physics/shape/Sphere.cpp
Normal file
23
ege/physics/shape/Sphere.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physics/shape/Sphere.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::physics::shape::Sphere::parse(const char* _line) {
|
||||
if (ege::physics::Shape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius:", 7) == 0) {
|
||||
sscanf(&_line[7], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
47
ege/physics/shape/Sphere.hpp
Normal file
47
ege/physics/shape/Sphere.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physics/shape/Shape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
namespace physics {
|
||||
namespace shape {
|
||||
class Sphere : public ege::physics::Shape {
|
||||
public:
|
||||
Sphere() {};
|
||||
virtual ~Sphere() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::physics::Shape::type getType() const {
|
||||
return ege::physics::Shape::type::sphere;
|
||||
};
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
};
|
||||
void setRadius(float _radius) {
|
||||
m_radius = _radius;
|
||||
};
|
||||
private:
|
||||
virtual const ege::physics::shape::Sphere* toSphere() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::physics::shape::Sphere* toSphere() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsBox.hpp>
|
||||
|
||||
|
||||
bool ege::PhysicsBox::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "half-extents : ", 15) == 0) {
|
||||
sscanf(&_line[15], "%f %f %f", &m_size.m_floats[0], &m_size.m_floats[1], &m_size.m_floats[2] );
|
||||
EGE_VERBOSE(" halfSize=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
namespace ege {
|
||||
class PhysicsBox : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsBox() {};
|
||||
virtual ~PhysicsBox() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::box;
|
||||
};
|
||||
private:
|
||||
vec3 m_size; // Box size property in X, Y and Z
|
||||
public:
|
||||
const vec3& getSize() const {
|
||||
return m_size;
|
||||
};
|
||||
void setSize(const vec3& _size) {
|
||||
m_size = _size;
|
||||
}
|
||||
public:
|
||||
virtual const ege::PhysicsBox* toBox() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsBox* toBox() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsCapsule.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::PhysicsCapsule::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "height : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f", &m_height );
|
||||
EGE_VERBOSE(" height=" << m_height);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class PhysicsCapsule : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsCapsule() {};
|
||||
virtual ~PhysicsCapsule() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::capsule;
|
||||
};
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
};
|
||||
private:
|
||||
float m_height;
|
||||
public:
|
||||
float getHeight() const {
|
||||
return m_height;
|
||||
};
|
||||
public:
|
||||
virtual const ege::PhysicsCapsule* toCapsule() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsCapsule* toCapsule() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsCone.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::PhysicsCone::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "height : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f", &m_height );
|
||||
EGE_VERBOSE(" height=" << m_height);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
namespace ege {
|
||||
class PhysicsCone : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsCone() {};
|
||||
virtual ~PhysicsCone() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::cone;
|
||||
};
|
||||
private:
|
||||
float m_radius;
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
};
|
||||
private:
|
||||
float m_height;
|
||||
public:
|
||||
float getHeight() const {
|
||||
return m_height;
|
||||
};
|
||||
public:
|
||||
virtual const ege::PhysicsCone* toCone() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsCone* toCone() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
namespace ege {
|
||||
class PhysicsConvexHull : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsConvexHull() {};
|
||||
virtual ~PhysicsConvexHull() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::convexHull;
|
||||
};
|
||||
private:
|
||||
vec3 m_scale;
|
||||
public:
|
||||
vec3 getScale() const {
|
||||
return m_scale;
|
||||
};
|
||||
private:
|
||||
std::vector<vec3> m_points;
|
||||
public:
|
||||
const std::vector<vec3>& getPointList() const {
|
||||
return m_points;
|
||||
};
|
||||
public:
|
||||
virtual const ege::PhysicsConvexHull* toConvexHull() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsConvexHull* toConvexHull() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsCylinder.hpp>
|
||||
|
||||
|
||||
bool ege::PhysicsCylinder::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "half-extents : ", 15) == 0) {
|
||||
sscanf(&_line[15], "%f %f %f", &m_size.m_floats[0], &m_size.m_floats[1], &m_size.m_floats[2] );
|
||||
EGE_VERBOSE(" halfSize=" << m_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class PhysicsCylinder : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsCylinder() {};
|
||||
virtual ~PhysicsCylinder() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::cylinder;
|
||||
};
|
||||
private:
|
||||
vec3 m_size;
|
||||
public:
|
||||
vec3 getSize() const {
|
||||
return m_size;
|
||||
};
|
||||
public:
|
||||
virtual const ege::PhysicsCylinder* toCylinder() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsCylinder* toCylinder() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
#include <ege/physicsShape/PhysicsBox.hpp>
|
||||
#include <ege/physicsShape/PhysicsCapsule.hpp>
|
||||
#include <ege/physicsShape/PhysicsCone.hpp>
|
||||
#include <ege/physicsShape/PhysicsConvexHull.hpp>
|
||||
#include <ege/physicsShape/PhysicsCylinder.hpp>
|
||||
#include <ege/physicsShape/PhysicsSphere.hpp>
|
||||
|
||||
|
||||
ememory::SharedPtr<ege::PhysicsShape> ege::PhysicsShape::create(const std::string& _name) {
|
||||
ememory::SharedPtr<ege::PhysicsShape> tmpp = nullptr;
|
||||
std::string name = etk::tolower(_name);
|
||||
if (name == "box") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsBox>();
|
||||
} else if (name == "sphere") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsSphere>();
|
||||
} else if (name == "cone") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsCone>();
|
||||
} else if (name == "cylinder") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsCylinder>();
|
||||
} else if (name == "capsule") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsCapsule>();
|
||||
} else if (name == "convexhull") {
|
||||
tmpp = ememory::makeShared<ege::PhysicsConvexHull>();
|
||||
} else {
|
||||
EGE_ERROR("Create an unknow element : '" << _name << "' availlable : [BOX,SPHERE,CONE,CYLINDER,CAPSULE,CONVEXHULL]");
|
||||
return nullptr;
|
||||
}
|
||||
if (tmpp == nullptr) {
|
||||
EGE_ERROR("Allocation error for physical element : '" << _name << "'");
|
||||
}
|
||||
return tmpp;
|
||||
}
|
||||
|
||||
|
||||
bool ege::PhysicsShape::parse(const char* _line) {
|
||||
if(strncmp(_line, "origin : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f %f %f", &m_origin.m_floats[0], &m_origin.m_floats[1], &m_origin.m_floats[2] );
|
||||
EGE_VERBOSE(" Origin=" << m_origin);
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "rotate : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f %f %f %f", &m_quaternion.m_floats[0], &m_quaternion.m_floats[1], &m_quaternion.m_floats[2], &m_quaternion.m_floats[3] );
|
||||
EGE_VERBOSE(" rotate=" << m_quaternion);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,129 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/math/Vector4D.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
#include <ememory/memory.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class PhysicsBox;
|
||||
class PhysicsCylinder;
|
||||
class PhysicsCapsule;
|
||||
class PhysicsCone;
|
||||
class PhysicsConvexHull;
|
||||
class PhysicsSphere;
|
||||
|
||||
class PhysicsShape {
|
||||
public:
|
||||
static ememory::SharedPtr<ege::PhysicsShape> create(const std::string& _name);
|
||||
public:
|
||||
enum type {
|
||||
unknow,
|
||||
box,
|
||||
capsule,
|
||||
cone,
|
||||
convexHull,
|
||||
cylinder,
|
||||
sphere
|
||||
};
|
||||
public:
|
||||
PhysicsShape() :
|
||||
m_quaternion(1,0,0,0),
|
||||
m_origin(0,0,0) {
|
||||
|
||||
};
|
||||
virtual ~PhysicsShape() {
|
||||
|
||||
};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::unknow;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {
|
||||
|
||||
};
|
||||
private:
|
||||
vec4 m_quaternion;
|
||||
public:
|
||||
const vec4& getQuaternion() const {
|
||||
return m_quaternion;
|
||||
};
|
||||
private:
|
||||
vec3 m_origin;
|
||||
public:
|
||||
const vec3& getOrigin() const {
|
||||
return m_origin;
|
||||
};
|
||||
public:
|
||||
bool isBox() {
|
||||
return getType() == ege::PhysicsShape::box;
|
||||
};
|
||||
bool isCylinder() {
|
||||
return getType() == ege::PhysicsShape::cylinder;
|
||||
};
|
||||
bool isCapsule() {
|
||||
return getType() == ege::PhysicsShape::capsule;
|
||||
};
|
||||
bool isCone() {
|
||||
return getType() == ege::PhysicsShape::cone;
|
||||
};
|
||||
bool isConvexHull() {
|
||||
return getType() == ege::PhysicsShape::convexHull;
|
||||
};
|
||||
bool isSphere() {
|
||||
return getType() == ege::PhysicsShape::sphere;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsBox* toBox() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsBox* toBox() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsCylinder* toCylinder() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsCylinder* toCylinder() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsCapsule* toCapsule() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsCapsule* toCapsule() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsCone* toCone() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsCone* toCone() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsConvexHull* toConvexHull() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsConvexHull* toConvexHull() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
virtual const ege::PhysicsSphere* toSphere() const {
|
||||
return nullptr;
|
||||
};
|
||||
virtual ege::PhysicsSphere* toSphere() {
|
||||
return nullptr;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/debug.hpp>
|
||||
#include <ege/physicsShape/PhysicsSphere.hpp>
|
||||
|
||||
|
||||
|
||||
bool ege::PhysicsSphere::parse(const char* _line) {
|
||||
if (ege::PhysicsShape::parse(_line) == true) {
|
||||
return true;
|
||||
}
|
||||
if(strncmp(_line, "radius : ", 9) == 0) {
|
||||
sscanf(&_line[9], "%f", &m_radius );
|
||||
EGE_VERBOSE(" radius=" << m_radius);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <ege/physicsShape/PhysicsShape.hpp>
|
||||
|
||||
|
||||
namespace ege {
|
||||
class PhysicsSphere : public ege::PhysicsShape {
|
||||
public:
|
||||
PhysicsSphere() {};
|
||||
virtual ~PhysicsSphere() {};
|
||||
public:
|
||||
virtual bool parse(const char* _line);
|
||||
virtual void display() {};
|
||||
public:
|
||||
virtual enum ege::PhysicsShape::type getType() const {
|
||||
return ege::PhysicsShape::sphere;
|
||||
};
|
||||
private:
|
||||
float m_radius; // props["radius"] = obj.scale.x
|
||||
public:
|
||||
float getRadius() const {
|
||||
return m_radius;
|
||||
};
|
||||
void setRadius(float _radius) {
|
||||
m_radius = _radius;
|
||||
};
|
||||
private:
|
||||
virtual const ege::PhysicsSphere* toSphere() const {
|
||||
return this;
|
||||
};
|
||||
virtual ege::PhysicsSphere* toSphere() {
|
||||
return this;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
42
ege/position/Component.cpp
Normal file
42
ege/position/Component.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#include <ege/position/Component.hpp>
|
||||
|
||||
const etk::String& ege::position::Component::getType() const {
|
||||
static etk::String tmp("position");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
ege::position::Component::Component(const etk::Transform3D& _transform):
|
||||
m_transform(_transform) {
|
||||
|
||||
}
|
||||
|
||||
ege::position::Component::Component():
|
||||
m_transform(etk::Transform3D::identity()) {
|
||||
|
||||
}
|
||||
|
||||
void ege::position::Component::setTransform(const etk::Transform3D& _transform) {
|
||||
if (_transform == m_transform) {
|
||||
return;
|
||||
}
|
||||
m_transform = _transform;
|
||||
signalPosition.emit(m_transform);
|
||||
}
|
||||
|
||||
const etk::Transform3D& ege::position::Component::getTransform() const {
|
||||
return m_transform;
|
||||
}
|
||||
|
||||
|
||||
void ege::position::Component::addFriendComponent(const ememory::SharedPtr<ege::Component>& _component) {
|
||||
if (_component->getType() == "physics") {
|
||||
EGE_ERROR("Can not add a 'physic' component and a 'position' component ... ==> incompatible");
|
||||
}
|
||||
}
|
||||
|
46
ege/position/Component.hpp
Normal file
46
ege/position/Component.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ege/debug.hpp>
|
||||
|
||||
#include <ege/Component.hpp>
|
||||
#include <etk/math/Transform3D.hpp>
|
||||
#include <esignal/Signal.hpp>
|
||||
|
||||
namespace ege {
|
||||
namespace position {
|
||||
class Component : public ege::Component {
|
||||
public:
|
||||
esignal::Signal<etk::Transform3D> signalPosition;
|
||||
protected:
|
||||
etk::Transform3D m_transform;
|
||||
public:
|
||||
/**
|
||||
* @brief Create a basic position component (no orientation and position (0,0,0))
|
||||
*/
|
||||
Component();
|
||||
/**
|
||||
* @brief Create a basic position component
|
||||
* @param[in] _transform transformation of the position
|
||||
*/
|
||||
Component(const etk::Transform3D& _transform);
|
||||
/**
|
||||
* @brief set a new transformation
|
||||
* @param[in] _transform transformation of the position
|
||||
*/
|
||||
void setTransform(const etk::Transform3D& _transform);
|
||||
/**
|
||||
* @brief set a new transformation
|
||||
* @return Transformation of the position
|
||||
*/
|
||||
const etk::Transform3D& getTransform() const;
|
||||
public:
|
||||
const etk::String& getType() const override;
|
||||
void addFriendComponent(const ememory::SharedPtr<ege::Component>& _component) override;
|
||||
};
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user