mirror of
https://github.com/MapMakersAndProgrammers/alternativa3d-archive.git
synced 2025-10-26 01:49:05 -07:00
more versions added
This commit is contained in:
BIN
Alternativa3D2/.DS_Store
vendored
Normal file
BIN
Alternativa3D2/.DS_Store
vendored
Normal file
Binary file not shown.
31
Alternativa3D2/2.0/.actionScriptProperties
Normal file
31
Alternativa3D2/2.0/.actionScriptProperties
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<actionScriptProperties mainApplicationPath="Engine3DLibrary.as" version="3">
|
||||||
|
<compiler additionalCompilerArguments="-debug=true -as3=true -es=false" copyDependentFiles="false" enableModuleDebug="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersion="9.0.0" htmlPlayerVersionCheck="true" outputFolderPath="" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">
|
||||||
|
<compilerSourcePath/>
|
||||||
|
<libraryPath defaultLinkType="1">
|
||||||
|
<libraryPathEntry kind="4" path="">
|
||||||
|
<modifiedEntries>
|
||||||
|
<libraryPathEntry kind="3" linkType="2" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
|
||||||
|
</modifiedEntries>
|
||||||
|
<excludedEntries>
|
||||||
|
<libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
|
||||||
|
</excludedEntries>
|
||||||
|
</libraryPathEntry>
|
||||||
|
<libraryPathEntry kind="3" linkType="2" path="/Main/Main.swc" useDefaultLinkType="false"/>
|
||||||
|
</libraryPath>
|
||||||
|
<sourceAttachmentPath/>
|
||||||
|
</compiler>
|
||||||
|
<applications>
|
||||||
|
<application path="Engine3DLibrary.as"/>
|
||||||
|
</applications>
|
||||||
|
<modules/>
|
||||||
|
<buildCSSFiles/>
|
||||||
|
</actionScriptProperties>
|
||||||
11
Alternativa3D2/2.0/.externalToolBuilders/.svn/all-wcprops
Normal file
11
Alternativa3D2/2.0/.externalToolBuilders/.svn/all-wcprops
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 93
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.externalToolBuilders
|
||||||
|
END
|
||||||
|
com.adobe.flexbuilder.project.flexbuilder.launch
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 142
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.externalToolBuilders/com.adobe.flexbuilder.project.flexbuilder.launch
|
||||||
|
END
|
||||||
40
Alternativa3D2/2.0/.externalToolBuilders/.svn/entries
Normal file
40
Alternativa3D2/2.0/.externalToolBuilders/.svn/entries
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.externalToolBuilders
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
com.adobe.flexbuilder.project.flexbuilder.launch
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
88b0af30379398314ff40d0e89fa27bb
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
1
Alternativa3D2/2.0/.externalToolBuilders/.svn/format
Normal file
1
Alternativa3D2/2.0/.externalToolBuilders/.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||||
|
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="com.adobe.flexbuilder.project.flexbuilder"/>
|
||||||
|
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
|
||||||
|
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||||
|
</launchConfiguration>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||||
|
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="com.adobe.flexbuilder.project.flexbuilder"/>
|
||||||
|
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
|
||||||
|
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||||
|
</launchConfiguration>
|
||||||
56
Alternativa3D2/2.0/.flexLibProperties
Normal file
56
Alternativa3D2/2.0/.flexLibProperties
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<flexLibProperties version="1">
|
||||||
|
<includeClasses>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Event3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Math3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Matrix3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.View3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.engine3d"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.FillMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.HelperMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.Hit"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.Material"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.ObjectMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.PolygonMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.SpriteMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.SpritePhase"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.TextureMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.WireMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Dummy3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.HelperObject3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Object3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.SkinObject3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Sprite3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Ambient3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Direct3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Light3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Omni3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Mesh3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Point3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.PolyMesh3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Polygroup3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.FillPolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.Polygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.TexturePolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.WirePolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Box3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.GeoPlane"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Geosphere"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Plane"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Sphere"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Triangle"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.DirectSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.DummySkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.FillSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.HelperSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.ObjectSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.OmniSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.PolygonSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.Skin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.SpriteSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.TextureSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.WireSkin"/>
|
||||||
|
</includeClasses>
|
||||||
|
<includeResources/>
|
||||||
|
<namespaceManifests/>
|
||||||
|
</flexLibProperties>
|
||||||
24
Alternativa3D2/2.0/.project
Normal file
24
Alternativa3D2/2.0/.project
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Alternativa3D</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
<project>Main</project>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/com.adobe.flexbuilder.project.flexbuilder.launch</value>
|
||||||
|
</dictionary>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
|
||||||
|
<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
23
Alternativa3D2/2.0/.settings/.svn/all-wcprops
Normal file
23
Alternativa3D2/2.0/.settings/.svn/all-wcprops
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 81
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.settings
|
||||||
|
END
|
||||||
|
org.eclipse.core.resources.prefs
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 114
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.settings/org.eclipse.core.resources.prefs
|
||||||
|
END
|
||||||
|
org.eclipse.mylar.tasklist.prefs
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 114
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.settings/org.eclipse.mylar.tasklist.prefs
|
||||||
|
END
|
||||||
|
org.eclipse.ltk.core.refactoring.prefs
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 120
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.settings/org.eclipse.ltk.core.refactoring.prefs
|
||||||
|
END
|
||||||
64
Alternativa3D2/2.0/.settings/.svn/entries
Normal file
64
Alternativa3D2/2.0/.settings/.svn/entries
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.settings
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
org.eclipse.core.resources.prefs
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
e5ce8e3ade27a1368dc20af891aa246c
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
org.eclipse.mylar.tasklist.prefs
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
aa1291d1b9c380e23390326903bc21d9
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
org.eclipse.ltk.core.refactoring.prefs
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
021b230823c12d7ddab35aaa658f281d
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
1
Alternativa3D2/2.0/.settings/.svn/format
Normal file
1
Alternativa3D2/2.0/.settings/.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#Fri Nov 17 12:29:06 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=utf-8
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#Tue Dec 26 13:08:01 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#Fri Nov 17 12:30:03 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
project.repository.kind=jira
|
||||||
|
project.repository.url=http\://bugs.grtov.ru
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#Fri Nov 17 12:29:06 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=utf-8
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#Tue Dec 26 13:08:01 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#Fri Nov 17 12:30:03 YEKT 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
project.repository.kind=jira
|
||||||
|
project.repository.url=http\://bugs.grtov.ru
|
||||||
29
Alternativa3D2/2.0/.svn/all-wcprops
Normal file
29
Alternativa3D2/2.0/.svn/all-wcprops
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 71
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0
|
||||||
|
END
|
||||||
|
.flexLibProperties
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 90
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.flexLibProperties
|
||||||
|
END
|
||||||
|
.project
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 80
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.project
|
||||||
|
END
|
||||||
|
.actionScriptProperties
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 95
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/.actionScriptProperties
|
||||||
|
END
|
||||||
|
build.xml
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 81
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/build.xml
|
||||||
|
END
|
||||||
85
Alternativa3D2/2.0/.svn/entries
Normal file
85
Alternativa3D2/2.0/.svn/entries
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
.flexLibProperties
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
4fe6dee7f1bdbb5a1e5194ee7aebe60b
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
.project
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
9457539afd155fd30e12990ba61fc463
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
.externalToolBuilders
|
||||||
|
dir
|
||||||
|
|
||||||
|
.actionScriptProperties
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
7a1a021a8c4e28aebdde0a6869688e2e
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
.settings
|
||||||
|
dir
|
||||||
|
|
||||||
|
com
|
||||||
|
dir
|
||||||
|
|
||||||
|
build.xml
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
47f4682d51f5cc6d221f595ffd67d21d
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
1
Alternativa3D2/2.0/.svn/format
Normal file
1
Alternativa3D2/2.0/.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<actionScriptProperties mainApplicationPath="Engine3DLibrary.as" version="3">
|
||||||
|
<compiler additionalCompilerArguments="-debug=true -as3=true -es=false" copyDependentFiles="false" enableModuleDebug="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersion="9.0.0" htmlPlayerVersionCheck="true" outputFolderPath="" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">
|
||||||
|
<compilerSourcePath/>
|
||||||
|
<libraryPath defaultLinkType="1">
|
||||||
|
<libraryPathEntry kind="4" path="">
|
||||||
|
<modifiedEntries>
|
||||||
|
<libraryPathEntry kind="3" linkType="2" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
|
||||||
|
</modifiedEntries>
|
||||||
|
<excludedEntries>
|
||||||
|
<libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
|
||||||
|
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
|
||||||
|
</excludedEntries>
|
||||||
|
</libraryPathEntry>
|
||||||
|
<libraryPathEntry kind="3" linkType="2" path="/Main/Main.swc" useDefaultLinkType="false"/>
|
||||||
|
</libraryPath>
|
||||||
|
<sourceAttachmentPath/>
|
||||||
|
</compiler>
|
||||||
|
<applications>
|
||||||
|
<application path="Engine3DLibrary.as"/>
|
||||||
|
</applications>
|
||||||
|
<modules/>
|
||||||
|
<buildCSSFiles/>
|
||||||
|
</actionScriptProperties>
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<flexLibProperties version="1">
|
||||||
|
<includeClasses>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Event3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Math3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.Matrix3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.View3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.engine3d"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.FillMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.HelperMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.Hit"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.Material"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.ObjectMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.PolygonMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.SpriteMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.SpritePhase"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.TextureMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.material.WireMaterial"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Dummy3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.HelperObject3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Object3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.SkinObject3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.Sprite3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Ambient3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Direct3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Light3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.light.Omni3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Mesh3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Point3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.PolyMesh3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.Polygroup3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.FillPolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.Polygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.TexturePolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.polygon.WirePolygon3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Box3D"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.GeoPlane"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Geosphere"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Plane"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Sphere"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.object.mesh.primitive.Triangle"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.DirectSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.DummySkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.FillSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.HelperSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.ObjectSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.OmniSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.PolygonSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.Skin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.SpriteSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.TextureSkin"/>
|
||||||
|
<classEntry path="com.alternativagame.engine3d.skin.WireSkin"/>
|
||||||
|
</includeClasses>
|
||||||
|
<includeResources/>
|
||||||
|
<namespaceManifests/>
|
||||||
|
</flexLibProperties>
|
||||||
24
Alternativa3D2/2.0/.svn/text-base/.project.svn-base
Normal file
24
Alternativa3D2/2.0/.svn/text-base/.project.svn-base
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Alternativa3D</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
<project>Main</project>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/com.adobe.flexbuilder.project.flexbuilder.launch</value>
|
||||||
|
</dictionary>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
|
||||||
|
<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
21
Alternativa3D2/2.0/.svn/text-base/build.xml.svn-base
Normal file
21
Alternativa3D2/2.0/.svn/text-base/build.xml.svn-base
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<project name="Publisher" default="clear" basedir=".">
|
||||||
|
|
||||||
|
<property name="project" value="Engine3D"/>
|
||||||
|
|
||||||
|
<target name="uncompress">
|
||||||
|
<unzip src="${project}.swc" dest="swc" />
|
||||||
|
<move file="swc/library.swf" tofile="swc/${project}.swf"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="publish" depends="uncompress">
|
||||||
|
<scp file="swc/${project}.swf"
|
||||||
|
passphrase="${com.alternativagame.publish.passphrase}"
|
||||||
|
keyfile="${com.alternativagame.publish.key}"
|
||||||
|
todir="${com.alternativagame.publish.user}@${com.alternativagame.publish.server}.${com.alternativagame.publish.host}:${com.alternativagame.publish.server}_server/${com.alternativagame.publish.path}" trust="true"></scp>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="clear" depends="publish">
|
||||||
|
<delete dir="swc" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
||||||
21
Alternativa3D2/2.0/build.xml
Normal file
21
Alternativa3D2/2.0/build.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<project name="Publisher" default="clear" basedir=".">
|
||||||
|
|
||||||
|
<property name="project" value="Engine3D"/>
|
||||||
|
|
||||||
|
<target name="uncompress">
|
||||||
|
<unzip src="${project}.swc" dest="swc" />
|
||||||
|
<move file="swc/library.swf" tofile="swc/${project}.swf"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="publish" depends="uncompress">
|
||||||
|
<scp file="swc/${project}.swf"
|
||||||
|
passphrase="${com.alternativagame.publish.passphrase}"
|
||||||
|
keyfile="${com.alternativagame.publish.key}"
|
||||||
|
todir="${com.alternativagame.publish.user}@${com.alternativagame.publish.server}.${com.alternativagame.publish.host}:${com.alternativagame.publish.server}_server/${com.alternativagame.publish.path}" trust="true"></scp>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="clear" depends="publish">
|
||||||
|
<delete dir="swc" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
||||||
5
Alternativa3D2/2.0/com/.svn/all-wcprops
Normal file
5
Alternativa3D2/2.0/com/.svn/all-wcprops
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 75
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com
|
||||||
|
END
|
||||||
31
Alternativa3D2/2.0/com/.svn/entries
Normal file
31
Alternativa3D2/2.0/com/.svn/entries
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
alternativagame
|
||||||
|
dir
|
||||||
|
|
||||||
1
Alternativa3D2/2.0/com/.svn/format
Normal file
1
Alternativa3D2/2.0/com/.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
5
Alternativa3D2/2.0/com/alternativagame/.svn/all-wcprops
Normal file
5
Alternativa3D2/2.0/com/alternativagame/.svn/all-wcprops
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 91
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame
|
||||||
|
END
|
||||||
31
Alternativa3D2/2.0/com/alternativagame/.svn/entries
Normal file
31
Alternativa3D2/2.0/com/alternativagame/.svn/entries
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
engine3d
|
||||||
|
dir
|
||||||
|
|
||||||
1
Alternativa3D2/2.0/com/alternativagame/.svn/format
Normal file
1
Alternativa3D2/2.0/com/alternativagame/.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 100
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d
|
||||||
|
END
|
||||||
|
Math3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 110
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/Math3D.as
|
||||||
|
END
|
||||||
|
View3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 110
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/View3D.as
|
||||||
|
END
|
||||||
|
Event3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 111
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/Event3D.as
|
||||||
|
END
|
||||||
|
Matrix3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 112
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/Matrix3D.as
|
||||||
|
END
|
||||||
|
engine3d.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 112
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/engine3d.as
|
||||||
|
END
|
||||||
97
Alternativa3D2/2.0/com/alternativagame/engine3d/.svn/entries
Normal file
97
Alternativa3D2/2.0/com/alternativagame/engine3d/.svn/entries
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
Math3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
7b81e7bcd08cebc0d483c53ea55cbb6f
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
View3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
3c867db97e9fbab444ab6b579de77a89
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
skin
|
||||||
|
dir
|
||||||
|
|
||||||
|
object
|
||||||
|
dir
|
||||||
|
|
||||||
|
Event3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
29f87e4a8a5f848f343fabc78a4ebd0a
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Matrix3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
3b9a466fda6c17b149c999dae3d61a62
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
material
|
||||||
|
dir
|
||||||
|
|
||||||
|
engine3d.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
67fa545736dc205f081fe3157a9fe28c
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import flash.events.Event;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.Polygon3D;
|
||||||
|
|
||||||
|
public class Event3D extends Event {
|
||||||
|
|
||||||
|
static public const DOWN:String = "3DDown";
|
||||||
|
static public const UP:String = "3DUp";
|
||||||
|
static public const CLICK:String = "3DClick";
|
||||||
|
|
||||||
|
public var ctrlKey:Boolean;
|
||||||
|
public var altKey:Boolean;
|
||||||
|
public var shiftKey:Boolean;
|
||||||
|
|
||||||
|
public var object:Object3D;
|
||||||
|
public var polygon:Polygon3D;
|
||||||
|
public var material:Material;
|
||||||
|
public var canvasCoords:Vector;
|
||||||
|
public var objectCoords:Vector;
|
||||||
|
public var currentObjectCoords:Vector;
|
||||||
|
|
||||||
|
public function Event3D(type:String, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, object:Object3D = null, polygon:Polygon3D = null, material:Material = null, canvasCoords:Vector = null, objectCoords:Vector = null, currentObjectCoords:Vector = null) {
|
||||||
|
super(type);
|
||||||
|
|
||||||
|
this.ctrlKey = ctrlKey;
|
||||||
|
this.altKey = altKey;
|
||||||
|
this.shiftKey = shiftKey;
|
||||||
|
|
||||||
|
this.object = object;
|
||||||
|
this.polygon = polygon;
|
||||||
|
this.material = material;
|
||||||
|
this.canvasCoords = canvasCoords;
|
||||||
|
this.objectCoords = objectCoords;
|
||||||
|
this.currentObjectCoords = currentObjectCoords;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,447 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import flash.geom.Point;
|
||||||
|
|
||||||
|
public final class Math3D {
|
||||||
|
static private var toRad:Number = Math.PI/180;
|
||||||
|
static private var toDeg:Number = 180/Math.PI;
|
||||||
|
|
||||||
|
// Перевести в радианы
|
||||||
|
static public function toRadian(n:Number):Number {
|
||||||
|
return n*toRad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перевести в градусы
|
||||||
|
static public function toDegree(n:Number):Number {
|
||||||
|
return n*toDeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перевести значение градуса в пределы -180..180
|
||||||
|
static public function limitAngle(n:Number):Number {
|
||||||
|
var res:Number = n % 360;
|
||||||
|
res = (res > 0) ? ((res > 180) ? (res - 360) : res) : ((res < -180) ? (res + 360) : res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Кратчайшая разница углов (углы должны быть лимитированы)
|
||||||
|
static public function deltaAngle(a:Number, b:Number):Number {
|
||||||
|
var delta:Number = b - a;
|
||||||
|
if (delta > 180) {
|
||||||
|
return delta - 360;
|
||||||
|
} else {
|
||||||
|
if (delta < -180) {
|
||||||
|
return delta + 360;
|
||||||
|
} else {
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function random(... args):Number {
|
||||||
|
if (args.length == 0) {
|
||||||
|
return Math.random();
|
||||||
|
} else {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Math.random()*args[0];
|
||||||
|
} else {
|
||||||
|
return Math.random()*(args[1]-args[0])+args[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Длина вектора
|
||||||
|
static public function vectorLength(v:Vector):Number {
|
||||||
|
return Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Длина вектора
|
||||||
|
static public function vectorLengthSquare(v:Vector):Number {
|
||||||
|
return v.x*v.x + v.y*v.y + v.z*v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нормализовать вектор
|
||||||
|
static public function normalize(v:Vector):void {
|
||||||
|
var n:Number = vectorLength(v);
|
||||||
|
if (n !== 0) {
|
||||||
|
v.x /= n;
|
||||||
|
v.y /= n;
|
||||||
|
v.z /= n;
|
||||||
|
} else {
|
||||||
|
v.x = 0;
|
||||||
|
v.y = 0;
|
||||||
|
v.z = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сложение векторов
|
||||||
|
static public function vectorAdd(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вычитание векторов
|
||||||
|
static public function vectorSub(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Умножить вектор на скаляр
|
||||||
|
static public function vectorMultiply(v:Vector, n:Number):Vector {
|
||||||
|
return new Vector(v.x*n, v.y*n, v.z*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Скалярное произведение векторов
|
||||||
|
static public function vectorDot(v1:Vector, v2:Vector):Number {
|
||||||
|
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Векторное произведение векторов
|
||||||
|
static public function vectorCross(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Угол между векторами
|
||||||
|
static public function vectorAngle(v1:Vector, v2:Vector):Number {
|
||||||
|
var len:Number = vectorLength(v1)*vectorLength(v2);
|
||||||
|
// Если один из векторов нулевой, угол - 0 градусов
|
||||||
|
var cos:Number = (len != 0) ? (vectorDot(v1, v2) / len) : 1;
|
||||||
|
return Math.acos(cos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Угол между векторами (работает только если векторы нормализованы)
|
||||||
|
static public function vectorAngleFast(v1:Vector, v2:Vector):Number {
|
||||||
|
return Math.acos(vectorDot(v1, v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отбрасывает дробную часть у координат вектора
|
||||||
|
static public function vectorFloor(v:Vector):Vector {
|
||||||
|
return new Vector(Math.floor(v.x), Math.floor(v.y), Math.floor(v.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сравнение векторов с погрешностью
|
||||||
|
static public function vectorEquals(v1:Vector, v2:Vector, delta:Number = 0):Boolean {
|
||||||
|
var d:Vector = vectorSub(v1, v2);
|
||||||
|
return (Math.abs(d.x) <= delta) && (Math.abs(d.y) <= delta) && (Math.abs(d.z) <= delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нахождение нормали грани
|
||||||
|
static public function normal(points:Array):Vector {
|
||||||
|
var v1:Vector = new Vector(points[1].x - points[0].x, points[1].y - points[0].y, points[1].z - points[0].z);
|
||||||
|
var v2:Vector = new Vector(points[1].x - points[2].x, points[1].y - points[2].y, points[1].z - points[2].z);
|
||||||
|
var res:Vector = vectorCross(v1, v2);
|
||||||
|
normalize(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перенос матрицы
|
||||||
|
static public function translateMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
m.d += x;
|
||||||
|
m.h += y;
|
||||||
|
m.l += z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы
|
||||||
|
static public function scaleMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
m.a *= x;
|
||||||
|
m.b *= x;
|
||||||
|
m.c *= x;
|
||||||
|
m.d *= x;
|
||||||
|
m.e *= y;
|
||||||
|
m.f *= y;
|
||||||
|
m.g *= y;
|
||||||
|
m.h *= y;
|
||||||
|
m.i *= z;
|
||||||
|
m.j *= z;
|
||||||
|
m.k *= z;
|
||||||
|
m.l *= z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по X
|
||||||
|
static public function scaleXMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.a *= value;
|
||||||
|
m.b *= value;
|
||||||
|
m.c *= value;
|
||||||
|
m.d *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по Y
|
||||||
|
static public function scaleYMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.e *= value;
|
||||||
|
m.f *= value;
|
||||||
|
m.g *= value;
|
||||||
|
m.h *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по Z
|
||||||
|
static public function scaleZMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.i *= value;
|
||||||
|
m.j *= value;
|
||||||
|
m.k *= value;
|
||||||
|
m.l *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы
|
||||||
|
static public function rotateMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
var xRadian:Number = Math3D.toRadian(x);
|
||||||
|
var yRadian:Number = Math3D.toRadian(y);
|
||||||
|
var zRadian:Number = Math3D.toRadian(z);
|
||||||
|
var cosX:Number = Math.cos(xRadian);
|
||||||
|
var sinX:Number = Math.sin(xRadian);
|
||||||
|
var cosY:Number = Math.cos(yRadian);
|
||||||
|
var sinY:Number = Math.sin(yRadian);
|
||||||
|
var cosZ:Number = Math.cos(zRadian);
|
||||||
|
var sinZ:Number = Math.sin(zRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
var cosZsinY:Number = cosZ*sinY;
|
||||||
|
var sinZsinY:Number = sinZ*sinY;
|
||||||
|
|
||||||
|
var ra:Number = cosZ*cosY;
|
||||||
|
var rb:Number = cosZsinY*sinX - sinZ*cosX;
|
||||||
|
var rc:Number = cosZsinY*cosX + sinZ*sinX;
|
||||||
|
|
||||||
|
var re:Number = sinZ*cosY;
|
||||||
|
var rf:Number = sinZsinY*sinX + cosZ*cosX;
|
||||||
|
var rg:Number = sinZsinY*cosX - cosZ*sinX;
|
||||||
|
|
||||||
|
var ri:Number = -sinY;
|
||||||
|
var rj:Number = cosY*sinX;
|
||||||
|
var rk:Number = cosY*cosX;
|
||||||
|
|
||||||
|
m.a = ra*a + rb*e + rc*i;
|
||||||
|
m.b = ra*b + rb*f + rc*j;
|
||||||
|
m.c = ra*c + rb*g + rc*k;
|
||||||
|
m.d = ra*d + rb*h + rc*l;
|
||||||
|
|
||||||
|
m.e = re*a + rf*e + rg*i;
|
||||||
|
m.f = re*b + rf*f + rg*j;
|
||||||
|
m.g = re*c + rf*g + rg*k;
|
||||||
|
m.h = re*d + rf*h + rg*l;
|
||||||
|
|
||||||
|
m.i = ri*a + rj*e + rk*i;
|
||||||
|
m.j = ri*b + rj*f + rk*j;
|
||||||
|
m.k = ri*c + rj*g + rk*k;
|
||||||
|
m.l = ri*d + rj*h + rk*l;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль X
|
||||||
|
static public function rotateXMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
m.e = cos*e - sin*i;
|
||||||
|
m.f = cos*f - sin*j;
|
||||||
|
m.g = cos*g - sin*k;
|
||||||
|
m.h = cos*h - sin*l;
|
||||||
|
|
||||||
|
m.i = sin*e + cos*i;
|
||||||
|
m.j = sin*f + cos*j;
|
||||||
|
m.k = sin*g + cos*k;
|
||||||
|
m.l = sin*h + cos*l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль Y
|
||||||
|
static public function rotateYMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
m.a = cos*a + sin*i;
|
||||||
|
m.b = cos*b + sin*j;
|
||||||
|
m.c = cos*c + sin*k;
|
||||||
|
m.d = cos*d + sin*l;
|
||||||
|
|
||||||
|
m.i = -sin*a + cos*i;
|
||||||
|
m.j = -sin*b + cos*j;
|
||||||
|
m.k = -sin*c + cos*k;
|
||||||
|
m.l = -sin*d + cos*l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль Z
|
||||||
|
static public function rotateZMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
|
||||||
|
m.a = cos*a - sin*e;
|
||||||
|
m.b = cos*b - sin*f;
|
||||||
|
m.c = cos*c - sin*g;
|
||||||
|
m.d = cos*d - sin*h;
|
||||||
|
|
||||||
|
m.e = sin*a + cos*e;
|
||||||
|
m.f = sin*b + cos*f;
|
||||||
|
m.g = sin*c + cos*g;
|
||||||
|
m.h = sin*d + cos*h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Умножение матриц
|
||||||
|
static public function combineMatrix(m1:Matrix3D, m2:Matrix3D):Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
|
||||||
|
res.a = m1.a*m2.a + m1.b*m2.e + m1.c*m2.i;
|
||||||
|
res.b = m1.a*m2.b + m1.b*m2.f + m1.c*m2.j;
|
||||||
|
res.c = m1.a*m2.c + m1.b*m2.g + m1.c*m2.k;
|
||||||
|
res.d = m1.a*m2.d + m1.b*m2.h + m1.c*m2.l + m1.d;
|
||||||
|
|
||||||
|
res.e = m1.e*m2.a + m1.f*m2.e + m1.g*m2.i;
|
||||||
|
res.f = m1.e*m2.b + m1.f*m2.f + m1.g*m2.j;
|
||||||
|
res.g = m1.e*m2.c + m1.f*m2.g + m1.g*m2.k;
|
||||||
|
res.h = m1.e*m2.d + m1.f*m2.h + m1.g*m2.l + m1.h;
|
||||||
|
|
||||||
|
res.i = m1.i*m2.a + m1.j*m2.e + m1.k*m2.i;
|
||||||
|
res.j = m1.i*m2.b + m1.j*m2.f + m1.k*m2.j;
|
||||||
|
res.k = m1.i*m2.c + m1.j*m2.g + m1.k*m2.k;
|
||||||
|
res.l = m1.i*m2.d + m1.j*m2.h + m1.k*m2.l + m1.l;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Трансформация вектора через матрицу
|
||||||
|
static public function vectorTransform(v:Vector, m:Matrix3D):Vector {
|
||||||
|
var res:Vector = new Vector();
|
||||||
|
res.x = m.a*v.x + m.b*v.y + m.c*v.z + m.d;
|
||||||
|
res.y = m.e*v.x + m.f*v.y + m.g*v.z + m.h;
|
||||||
|
res.z = m.i*v.x + m.j*v.y + m.k*v.z + m.l;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на пересечение луча с заданным треугольником
|
||||||
|
static public function tryangleIntersection(a:Vector, b:Vector, c:Vector, n:Vector, v1:Vector, v2:Vector): Vector {
|
||||||
|
var res:Vector;
|
||||||
|
|
||||||
|
var d:Number = -n.x*a.x - n.y*a.y - n.z*a.z;
|
||||||
|
var v:Vector = new Vector(v2.x-v1.x, v2.y-v1.y, v2.z-v1.z);
|
||||||
|
var nv:Number = (n.x*v.x + n.y*v.y + n.z*v.z);
|
||||||
|
if (nv != 0) {
|
||||||
|
//нахождение точки пересечения луча с плоскостью полигона
|
||||||
|
var t:Number = -(d + n.x*v1.x + n.y*v1.y + n.z*v1.z)/nv;
|
||||||
|
res = new Vector(v1.x + t*v.x,v1.y + t*v.y,v1.z + t*v.z);
|
||||||
|
//проверка на попадание точки пересечения в заданный треугольник
|
||||||
|
var uu:Number = ((res.x - a.x)*(c.y - a.y)-(c.x - a.x)*(res.y - a.y))/((b.x - a.x)*(c.y - a.y)-(c.x - a.x)*(b.y - a.y));
|
||||||
|
var vv:Number = (res.y - a.y - uu*(b.y - a.y))/(c.y - a.y);
|
||||||
|
if (!(uu > 0 && vv > 0 && (1-uu-vv) > 0)) {
|
||||||
|
//точка не лежит в треугольнике
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//луч параллелен плоскости
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//проверка на прохождение луча (v1, v2) через сферу с центром (c) заданного радиуса (r)
|
||||||
|
static public function sphereIntersection(c:Vector, r:Number, v1:Vector, v2:Vector):Vector {
|
||||||
|
var res: Vector;
|
||||||
|
|
||||||
|
var v: Vector = new Vector(v2.x-v1.x, v2.y-v1.y, v2.z-v1.z);
|
||||||
|
var n: Vector = new Vector(-v.x,-v.y,-v.z);
|
||||||
|
|
||||||
|
var d: Number = -n.x*c.x - n.y*c.y - n.z*c.z;
|
||||||
|
var nv: Number = (n.x*v.x + n.y*v.y + n.z*v.z);
|
||||||
|
// нахождение точки пересечения луча с плоскостью перпендикулярной лучу,
|
||||||
|
// проходящей через центр сферы
|
||||||
|
var t: Number = -(d + n.x*v1.x + n.y*v1.y + n.z*v1.z)/nv;
|
||||||
|
res = new Vector(v1.x + t*v.x,v1.y + t*v.y,v1.z + t*v.z);
|
||||||
|
//определение длины перпендикуляра
|
||||||
|
var l: Number = Math.sqrt((res.x-c.x)*(res.x-c.x) + (res.y-c.y)*(res.y-c.y) + (res.z-c.z)*(res.z-c.z));
|
||||||
|
if (l > r) {
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нахождение перпендикуляра к отрезку(v1, v2) из произвольной точки(c)
|
||||||
|
static public function perpendicularToSegment(c:Vector, v1:Vector, v2:Vector):Vector {
|
||||||
|
var res:Vector;
|
||||||
|
|
||||||
|
var v:Vector = vectorSub(v2, v1);
|
||||||
|
var n:Vector = new Vector(-v.x, -v.y, -v.z);
|
||||||
|
|
||||||
|
var d:Number = -vectorDot(n, c);
|
||||||
|
var nv:Number = vectorDot(n, v);
|
||||||
|
|
||||||
|
var t:Number = -(d + vectorDot(n, v1))/nv;
|
||||||
|
res = vectorAdd(v1, vectorMultiply(v, t));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расстояние от точки до ребра в плоскости камеры
|
||||||
|
static public function segmentDistance(first:Point, second:Point, point:Point):Number {
|
||||||
|
// Вектор ребра
|
||||||
|
var dx:Number = second.x - first.x;
|
||||||
|
var dy:Number = second.y - first.y;
|
||||||
|
|
||||||
|
// Вектор точки
|
||||||
|
var px:Number = point.x - first.x;
|
||||||
|
var py:Number = point.y - first.y;
|
||||||
|
|
||||||
|
// Векторное произведение (площадь параллелограмма) поделить на длину ребра
|
||||||
|
return (dx*py - dy*px)/Math.sqrt(dx*dx + dy*dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Попадает ли точка в 2D-треугольник
|
||||||
|
static public function tryangleHasPoint(a:Point, b:Point, c:Point, point:Point):Boolean {
|
||||||
|
if (vectorCross2D(c.subtract(a), point.subtract(a)) <= 0) {
|
||||||
|
if (vectorCross2D(b.subtract(c), point.subtract(c)) <= 0) {
|
||||||
|
if (vectorCross2D(a.subtract(b), point.subtract(b)) <= 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function vectorCross2D(a:Point, b:Point):Number {
|
||||||
|
return a.x*b.y - a.y*b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
public final class Matrix3D {
|
||||||
|
public var a:Number = 1;
|
||||||
|
public var b:Number = 0;
|
||||||
|
public var c:Number = 0;
|
||||||
|
public var d:Number = 0;
|
||||||
|
public var e:Number = 0;
|
||||||
|
public var f:Number = 1;
|
||||||
|
public var g:Number = 0;
|
||||||
|
public var h:Number = 0;
|
||||||
|
public var i:Number = 0;
|
||||||
|
public var j:Number = 0;
|
||||||
|
public var k:Number = 1;
|
||||||
|
public var l:Number = 0;
|
||||||
|
|
||||||
|
public function Matrix3D(x:Number = 0, y:Number = 0, z:Number = 0, rotX:Number = 0, rotY:Number = 0, rotZ:Number = 0, scaleX:Number = 1, scaleY:Number = 1, scaleZ:Number = 1) {
|
||||||
|
// Если указано масштабирование
|
||||||
|
if (arguments.length > 6) {
|
||||||
|
Math3D.scaleMatrix(this, scaleX, scaleY, scaleZ);
|
||||||
|
}
|
||||||
|
// Если указан поворот
|
||||||
|
if (arguments.length > 3) {
|
||||||
|
Math3D.rotateMatrix(this, rotX, rotY, rotZ);
|
||||||
|
}
|
||||||
|
// Если указано смещение
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
Math3D.translateMatrix(this, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clone():Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
res.a = a;
|
||||||
|
res.b = b;
|
||||||
|
res.c = c;
|
||||||
|
res.d = d;
|
||||||
|
res.e = e;
|
||||||
|
res.f = f;
|
||||||
|
res.g = g;
|
||||||
|
res.h = h;
|
||||||
|
res.i = i;
|
||||||
|
res.j = j;
|
||||||
|
res.k = k;
|
||||||
|
res.l = l;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toString():String {
|
||||||
|
return "Matrix:\r" + a.toFixed(3) + "\t" + b.toFixed(3) + "\t" + c.toFixed(3) + "\t" + d.toFixed(3) + "\r" + e.toFixed(3) + "\t" + f.toFixed(3) + "\t" + g.toFixed(3) + "\t" + h.toFixed(3) + "\r" + i.toFixed(3) + "\t" + j.toFixed(3) + "\t" + k.toFixed(3) + "\t" + l.toFixed(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,540 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import flash.display.DisplayObjectContainer;
|
||||||
|
import flash.display.Shape;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import flash.geom.ColorTransform;
|
||||||
|
import flash.geom.Point;
|
||||||
|
import flash.geom.Rectangle;
|
||||||
|
import flash.utils.clearTimeout;
|
||||||
|
import flash.utils.setTimeout;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class View3D extends Sprite {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Корневой объект
|
||||||
|
private var _object:Object3D = null;
|
||||||
|
|
||||||
|
// Область отрисовки спрайтов
|
||||||
|
private var canvas:Sprite;
|
||||||
|
private var canvasCoords:Vector;
|
||||||
|
|
||||||
|
// Список скинов на изменение глубины
|
||||||
|
private var skinsToDepth:Array;
|
||||||
|
// Список скинов на перепозиционирование
|
||||||
|
private var skinsToPosition:Set;
|
||||||
|
// Список скинов на отрисовку
|
||||||
|
private var skinsToDraw:Set;
|
||||||
|
// Список скинов на освещение
|
||||||
|
private var skinsToLight:Set;
|
||||||
|
|
||||||
|
// Размеры окна камеры
|
||||||
|
private var _width:uint;
|
||||||
|
private var _height:uint;
|
||||||
|
|
||||||
|
// Флаг ограничения окна камеры
|
||||||
|
private var _crop:Boolean = false;
|
||||||
|
|
||||||
|
// Координаты камеры относительно начала координат
|
||||||
|
private var _targetX:Number = 0;
|
||||||
|
private var _targetY:Number = 0;
|
||||||
|
private var _targetZ:Number = 0;
|
||||||
|
|
||||||
|
// Повороты камеры
|
||||||
|
private var _pitch:Number = 0;
|
||||||
|
private var _roll:Number = 0;
|
||||||
|
private var _yaw:Number = 0;
|
||||||
|
|
||||||
|
// Степень увеличения объектов
|
||||||
|
private var _zoom:Number = 1;
|
||||||
|
|
||||||
|
// Трансформация камеры
|
||||||
|
engine3d var transformation:Matrix3D;
|
||||||
|
engine3d var inverseTransformation:Matrix3D;
|
||||||
|
|
||||||
|
// Изменилась точка обзора камеры
|
||||||
|
engine3d var positionChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменился угол обзора или масштаб
|
||||||
|
engine3d var geometryChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Флаг заморозки камеры
|
||||||
|
private var _hold:Boolean = false;
|
||||||
|
|
||||||
|
// Текущий нажатый объект
|
||||||
|
private var pressedObject:Object3D;
|
||||||
|
|
||||||
|
public function View3D(width:uint, height:uint) {
|
||||||
|
|
||||||
|
hitArea = new Sprite();
|
||||||
|
hitArea.mouseEnabled = false;
|
||||||
|
hitArea.visible = false;
|
||||||
|
with (hitArea.graphics) {
|
||||||
|
beginFill(0);
|
||||||
|
drawRect(0, 0, 100, 100);
|
||||||
|
}
|
||||||
|
addChild(hitArea);
|
||||||
|
|
||||||
|
canvas = new Sprite();
|
||||||
|
canvas.mouseEnabled = false;
|
||||||
|
canvas.mouseChildren = false;
|
||||||
|
addChild(canvas);
|
||||||
|
|
||||||
|
canvasCoords = new Vector();
|
||||||
|
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
skinsToDepth = new Array();
|
||||||
|
skinsToPosition = new Set();
|
||||||
|
skinsToDraw = new Set();
|
||||||
|
skinsToLight = new Set();
|
||||||
|
|
||||||
|
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
|
||||||
|
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onMouseDown(e:MouseEvent):void {
|
||||||
|
dispatchEvent3D(Event3D.DOWN, e.ctrlKey, e.altKey, e.shiftKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onMouseUp(e:MouseEvent):void {
|
||||||
|
dispatchEvent3D(Event3D.UP, e.ctrlKey, e.altKey, e.shiftKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dispatchEvent3D(type:String, ctrlKey:Boolean, altKey:Boolean, shiftKey:Boolean):void {
|
||||||
|
var mouse:Point = new Point(stage.mouseX, stage.mouseY);
|
||||||
|
var skin:Skin = getSkinFromPoint(mouse);
|
||||||
|
|
||||||
|
// Если нажали на интерактивный скин
|
||||||
|
if (skin != null && skin.interactive) {
|
||||||
|
|
||||||
|
// При нажатии сохраняем нажатый объект
|
||||||
|
if (type == Event3D.DOWN) {
|
||||||
|
pressedObject = skin.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
var click:Boolean = (type == Event3D.UP && pressedObject == skin.object);
|
||||||
|
|
||||||
|
// Получаем пересечение вектора мыши со скином
|
||||||
|
var canvasCoords:Vector = skin.getIntersectionCoords(canvas.globalToLocal(mouse));
|
||||||
|
|
||||||
|
// Формируем ветку объектов
|
||||||
|
var objectList:Array = skin.object.getBranch();
|
||||||
|
|
||||||
|
// Перевести точку в мировые координаты
|
||||||
|
var worldCoords:Vector = Math3D.vectorTransform(canvasCoords, inverseTransformation);
|
||||||
|
|
||||||
|
// Рассчитываем точку в координатах каждого из родительских объектах и формируем список
|
||||||
|
var coordsList:Array = new Array();
|
||||||
|
|
||||||
|
var objectMatrix:Matrix3D;
|
||||||
|
var objectCoords:Vector = worldCoords.clone();
|
||||||
|
var currentObject:Object3D;
|
||||||
|
|
||||||
|
// Перебираем список объектов с конца (с корневого объекта)
|
||||||
|
var i:int;
|
||||||
|
for (i = objectList.length - 1; i >= 0; i--) {
|
||||||
|
currentObject = objectList[i];
|
||||||
|
// Трансформируем точку через матрицу в локальные координаты текущего объекта
|
||||||
|
objectCoords = Math3D.vectorTransform(objectCoords, currentObject.inverseTransform);
|
||||||
|
coordsList[i] = objectCoords.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рассылаем события от объектов
|
||||||
|
for (i = 0; i < objectList.length; i++) {
|
||||||
|
currentObject = objectList[i];
|
||||||
|
currentObject.dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, coordsList[i]));
|
||||||
|
// Если отжали на нажатом объекте, то отправить ещё и клик
|
||||||
|
if (click) {
|
||||||
|
currentObject.dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, coordsList[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отослать событие от камеры
|
||||||
|
dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, worldCoords));
|
||||||
|
|
||||||
|
// Если отжали на нажатом объекте, то отправить ещё и клик
|
||||||
|
if (click) {
|
||||||
|
dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, worldCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// При нажатии на пустое место сбрасываем нажатый объект
|
||||||
|
if (type == Event3D.DOWN) {
|
||||||
|
pressedObject = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рассылаем пустое событие
|
||||||
|
dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey));
|
||||||
|
|
||||||
|
// Если нажатый объект также был пуст, то отправить клик на пустое место
|
||||||
|
if (type == Event3D.UP && pressedObject == null) {
|
||||||
|
dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить скин по заданным координатам
|
||||||
|
public function getSkinFromPoint(point:Point):Skin {
|
||||||
|
// Получаем список объектов под координатой
|
||||||
|
var objectList:Array = getObjectsUnderPoint(point);
|
||||||
|
|
||||||
|
// Оставить в списке только скины
|
||||||
|
var skinList:Array = new Array();
|
||||||
|
var len:uint = objectList.length;
|
||||||
|
for (var i:uint = 0; i < len; i++) {
|
||||||
|
if (objectList[i] is Skin) {
|
||||||
|
skinList.push(objectList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортируем их по глубине
|
||||||
|
skinList.sortOn("sortDepth", Array.NUMERIC);
|
||||||
|
|
||||||
|
// Возвращаем самый близкий
|
||||||
|
return skinList[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Заморозить изображение камеры
|
||||||
|
public function hold():void {
|
||||||
|
_hold = true;
|
||||||
|
canvas.cacheAsBitmap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Заморозить изображение камеры
|
||||||
|
public function unhold():void {
|
||||||
|
_hold = false;
|
||||||
|
canvas.cacheAsBitmap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перерисовать объекты в камере
|
||||||
|
public function draw():void {
|
||||||
|
if (object != null) {
|
||||||
|
|
||||||
|
// Если изменилась геометрия
|
||||||
|
if (geometryChanged) {
|
||||||
|
|
||||||
|
// Пересчитать трансформацию
|
||||||
|
transformation = new Matrix3D();
|
||||||
|
Math3D.rotateZMatrix(transformation, -_yaw);
|
||||||
|
Math3D.rotateYMatrix(transformation, -_roll);
|
||||||
|
Math3D.rotateXMatrix(transformation, -_pitch);
|
||||||
|
Math3D.scaleMatrix(transformation, _zoom, _zoom, _zoom);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если изменилась позиция
|
||||||
|
if (geometryChanged || positionChanged) {
|
||||||
|
|
||||||
|
// Передвигаем всю область скинов
|
||||||
|
canvasCoords = Math3D.vectorTransform(new Vector(-_targetX, -_targetY, -_targetZ), transformation);
|
||||||
|
|
||||||
|
// Пересчитать инверсную трансформацию
|
||||||
|
var inv:Matrix3D = new Matrix3D(_targetX, _targetY, _targetZ, _pitch, _roll, _yaw, 1/_zoom, 1/_zoom, 1/_zoom);
|
||||||
|
inv.d += inv.a*canvasCoords.x + inv.b*canvasCoords.y + inv.c*canvasCoords.z;
|
||||||
|
inv.h += inv.e*canvasCoords.x + inv.f*canvasCoords.y + inv.g*canvasCoords.z;
|
||||||
|
inv.l += inv.i*canvasCoords.x + inv.j*canvasCoords.y + inv.k*canvasCoords.z;
|
||||||
|
inverseTransformation = inv;
|
||||||
|
|
||||||
|
canvas.x = width/2 + canvasCoords.x;
|
||||||
|
canvas.y = height/2 - canvasCoords.z;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
geometryChanged = false;
|
||||||
|
positionChanged = false;
|
||||||
|
|
||||||
|
// Если камера не заморожена
|
||||||
|
if (!_hold) {
|
||||||
|
// Расчитываем трансформацию дерева объектов
|
||||||
|
object.calculateTransform();
|
||||||
|
|
||||||
|
// Расчитать освещение дерева объектов
|
||||||
|
object.calculateLight();
|
||||||
|
|
||||||
|
|
||||||
|
if (skinsToDepth.length > 0 || skinsToPosition.length > 0 || skinsToDraw.length > 0 || skinsToLight.length > 0) {
|
||||||
|
trace(skinsToDepth.length, skinsToDraw.length, skinsToPosition.length, skinsToLight.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Сортируем глубины
|
||||||
|
sortDepths();
|
||||||
|
|
||||||
|
var skin:Skin;
|
||||||
|
// Позиционируем скины
|
||||||
|
for each (skin in skinsToPosition) {
|
||||||
|
skin.position();
|
||||||
|
}
|
||||||
|
skinsToPosition = new Set();
|
||||||
|
|
||||||
|
// Отрисовываем скины
|
||||||
|
for each (skin in skinsToDraw) {
|
||||||
|
skin.draw();
|
||||||
|
}
|
||||||
|
skinsToDraw = new Set();
|
||||||
|
|
||||||
|
// Освещаем скины
|
||||||
|
for each (skin in skinsToLight) {
|
||||||
|
skin.light();
|
||||||
|
}
|
||||||
|
skinsToLight = new Set();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запуск стирания скина
|
||||||
|
private function clearSkin(skin:Skin, index:int, arr:Array):void {
|
||||||
|
canvas.removeChild(DisplayObject(skin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортировка глубин скинов
|
||||||
|
private function sortDepths():void {
|
||||||
|
|
||||||
|
// Убираем скины из списка
|
||||||
|
skinsToDepth.forEach(clearSkin);
|
||||||
|
|
||||||
|
// Сортируем скины по глубине
|
||||||
|
skinsToDepth.sortOn("sortDepth", Array.NUMERIC | Array.DESCENDING);
|
||||||
|
|
||||||
|
// Вставляем скины на нужные глубины
|
||||||
|
var ma:int = -1;
|
||||||
|
var mb:int = (canvas.numChildren > 0) ? canvas.numChildren : 0;
|
||||||
|
|
||||||
|
var side:Boolean = false;
|
||||||
|
var skin:Skin;
|
||||||
|
var a:int;
|
||||||
|
var b:int;
|
||||||
|
var c:int;
|
||||||
|
var len:uint = skinsToDepth.length;
|
||||||
|
|
||||||
|
for (var i:uint = 0; i < len; i++) {
|
||||||
|
skin = (side) ? skinsToDepth.pop() : skinsToDepth.shift();
|
||||||
|
a = ma;
|
||||||
|
b = mb;
|
||||||
|
while (a < b - 1) {
|
||||||
|
c = (a + b) >>> 1;
|
||||||
|
(skin.sortDepth >= (canvas.getChildAt(c) as Skin).sortDepth) ? (b = c) : (a = c);
|
||||||
|
}
|
||||||
|
canvas.addChildAt(DisplayObject(skin), b);
|
||||||
|
(side) ? (mb = b) : (ma = b);
|
||||||
|
mb++;
|
||||||
|
side = !side;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список изменения глубин
|
||||||
|
engine3d function addToDepth(skin:Skin):void {
|
||||||
|
if (skinsToDepth.indexOf(skin) < 0) skinsToDepth.push(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список репозиционированных в следующий раз
|
||||||
|
engine3d function addToPosition(skin:Skin):void {
|
||||||
|
skinsToPosition.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список отрисовываемых в следующий раз
|
||||||
|
engine3d function addToDraw(skin:Skin):void {
|
||||||
|
skinsToDraw.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список освещаемых в следующий раз
|
||||||
|
engine3d function addToLight(skin:Skin):void {
|
||||||
|
skinsToLight.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин
|
||||||
|
engine3d function addSkin(skin:Skin):void {
|
||||||
|
canvas.addChild(DisplayObject(skin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Убрать скин
|
||||||
|
engine3d function removeSkin(skin:Skin):void {
|
||||||
|
// Удаляем скин из камеры
|
||||||
|
canvas.removeChild(DisplayObject(skin));
|
||||||
|
// Удаляем из списка на сортировку
|
||||||
|
var i:int = skinsToDepth.indexOf(skin);
|
||||||
|
if (i>=0) skinsToDepth.splice(i,1);
|
||||||
|
// Удаляем из список на отрисовку, позиционирование и освещение
|
||||||
|
skinsToPosition.remove(skin);
|
||||||
|
skinsToDraw.remove(skin);
|
||||||
|
skinsToLight.remove(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Указать корневой объект
|
||||||
|
public function set object(value:Object3D):void {
|
||||||
|
// Если есть текущий объект
|
||||||
|
if (object != null) {
|
||||||
|
// Снимаем у него камеру
|
||||||
|
object.setView(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если устанавливаем не пустой объект
|
||||||
|
if (value != null) {
|
||||||
|
// Если объект был в другой камере и был там корневым
|
||||||
|
if (value.view != null && value === value.view.object) {
|
||||||
|
// Снимаем у той камеры объект
|
||||||
|
value.view.object = null;
|
||||||
|
} else {
|
||||||
|
// Если объект был в другом объекте
|
||||||
|
if (value.parent != null) {
|
||||||
|
// Удалить его оттуда
|
||||||
|
value.parent.detach(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Указываем объектам камеру
|
||||||
|
value.setView(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_object = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get object():Object3D {
|
||||||
|
return _object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetX():Number {
|
||||||
|
return _targetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetY():Number {
|
||||||
|
return _targetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetZ():Number {
|
||||||
|
return _targetZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get zoom():Number {
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pitch():Number {
|
||||||
|
return _pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get roll():Number {
|
||||||
|
return _roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get yaw():Number {
|
||||||
|
return _yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetX(value:Number):void {
|
||||||
|
_targetX = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetY(value:Number):void {
|
||||||
|
_targetY = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetZ(value:Number):void {
|
||||||
|
_targetZ = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set pitch(value:Number):void {
|
||||||
|
_pitch = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set roll(value:Number):void {
|
||||||
|
_roll = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set yaw(value:Number):void {
|
||||||
|
_yaw = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set zoom(value:Number):void {
|
||||||
|
_zoom = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setGeometryChanged():void {
|
||||||
|
// Изменить геометрию у объекта и его потомков
|
||||||
|
if (!geometryChanged && object != null) {
|
||||||
|
object.setGeometryChanged();
|
||||||
|
geometryChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set width(value:Number):void {
|
||||||
|
_width = value;
|
||||||
|
hitArea.width = _width;
|
||||||
|
canvas.x = _width/2 + canvasCoords.x;
|
||||||
|
if (crop) {
|
||||||
|
scrollRect = new Rectangle(0, 0, _width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function get width():Number {
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set height(value:Number):void {
|
||||||
|
_height = value;
|
||||||
|
hitArea.height = _height;
|
||||||
|
canvas.y = _height/2 - canvasCoords.z;
|
||||||
|
if (crop) {
|
||||||
|
scrollRect = new Rectangle(0, 0, width, _height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function get height():Number {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set crop(value:Boolean):void {
|
||||||
|
_crop = value;
|
||||||
|
if (value) {
|
||||||
|
scrollRect = new Rectangle(0, 0, width, height);
|
||||||
|
} else {
|
||||||
|
scrollRect = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get crop():Boolean {
|
||||||
|
return _crop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get mouseCanvasCoords():Point {
|
||||||
|
var res:Point = null;
|
||||||
|
if (stage != null) {
|
||||||
|
res = canvas.globalToLocal(new Point(stage.mouseX, stage.mouseY));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canvasToView(coords:Vector):Vector {
|
||||||
|
return Math3D.vectorAdd(coords, canvasCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewToCanvas(coords:Vector):Vector {
|
||||||
|
return Math3D.vectorSub(coords, canvasCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
public namespace engine3d;
|
||||||
|
}
|
||||||
42
Alternativa3D2/2.0/com/alternativagame/engine3d/Event3D.as
Normal file
42
Alternativa3D2/2.0/com/alternativagame/engine3d/Event3D.as
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import flash.events.Event;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.Polygon3D;
|
||||||
|
|
||||||
|
public class Event3D extends Event {
|
||||||
|
|
||||||
|
static public const DOWN:String = "3DDown";
|
||||||
|
static public const UP:String = "3DUp";
|
||||||
|
static public const CLICK:String = "3DClick";
|
||||||
|
|
||||||
|
public var ctrlKey:Boolean;
|
||||||
|
public var altKey:Boolean;
|
||||||
|
public var shiftKey:Boolean;
|
||||||
|
|
||||||
|
public var object:Object3D;
|
||||||
|
public var polygon:Polygon3D;
|
||||||
|
public var material:Material;
|
||||||
|
public var canvasCoords:Vector;
|
||||||
|
public var objectCoords:Vector;
|
||||||
|
public var currentObjectCoords:Vector;
|
||||||
|
|
||||||
|
public function Event3D(type:String, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, object:Object3D = null, polygon:Polygon3D = null, material:Material = null, canvasCoords:Vector = null, objectCoords:Vector = null, currentObjectCoords:Vector = null) {
|
||||||
|
super(type);
|
||||||
|
|
||||||
|
this.ctrlKey = ctrlKey;
|
||||||
|
this.altKey = altKey;
|
||||||
|
this.shiftKey = shiftKey;
|
||||||
|
|
||||||
|
this.object = object;
|
||||||
|
this.polygon = polygon;
|
||||||
|
this.material = material;
|
||||||
|
this.canvasCoords = canvasCoords;
|
||||||
|
this.objectCoords = objectCoords;
|
||||||
|
this.currentObjectCoords = currentObjectCoords;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
447
Alternativa3D2/2.0/com/alternativagame/engine3d/Math3D.as
Normal file
447
Alternativa3D2/2.0/com/alternativagame/engine3d/Math3D.as
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import flash.geom.Point;
|
||||||
|
|
||||||
|
public final class Math3D {
|
||||||
|
static private var toRad:Number = Math.PI/180;
|
||||||
|
static private var toDeg:Number = 180/Math.PI;
|
||||||
|
|
||||||
|
// Перевести в радианы
|
||||||
|
static public function toRadian(n:Number):Number {
|
||||||
|
return n*toRad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перевести в градусы
|
||||||
|
static public function toDegree(n:Number):Number {
|
||||||
|
return n*toDeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перевести значение градуса в пределы -180..180
|
||||||
|
static public function limitAngle(n:Number):Number {
|
||||||
|
var res:Number = n % 360;
|
||||||
|
res = (res > 0) ? ((res > 180) ? (res - 360) : res) : ((res < -180) ? (res + 360) : res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Кратчайшая разница углов (углы должны быть лимитированы)
|
||||||
|
static public function deltaAngle(a:Number, b:Number):Number {
|
||||||
|
var delta:Number = b - a;
|
||||||
|
if (delta > 180) {
|
||||||
|
return delta - 360;
|
||||||
|
} else {
|
||||||
|
if (delta < -180) {
|
||||||
|
return delta + 360;
|
||||||
|
} else {
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function random(... args):Number {
|
||||||
|
if (args.length == 0) {
|
||||||
|
return Math.random();
|
||||||
|
} else {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Math.random()*args[0];
|
||||||
|
} else {
|
||||||
|
return Math.random()*(args[1]-args[0])+args[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Длина вектора
|
||||||
|
static public function vectorLength(v:Vector):Number {
|
||||||
|
return Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Длина вектора
|
||||||
|
static public function vectorLengthSquare(v:Vector):Number {
|
||||||
|
return v.x*v.x + v.y*v.y + v.z*v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нормализовать вектор
|
||||||
|
static public function normalize(v:Vector):void {
|
||||||
|
var n:Number = vectorLength(v);
|
||||||
|
if (n !== 0) {
|
||||||
|
v.x /= n;
|
||||||
|
v.y /= n;
|
||||||
|
v.z /= n;
|
||||||
|
} else {
|
||||||
|
v.x = 0;
|
||||||
|
v.y = 0;
|
||||||
|
v.z = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сложение векторов
|
||||||
|
static public function vectorAdd(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вычитание векторов
|
||||||
|
static public function vectorSub(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Умножить вектор на скаляр
|
||||||
|
static public function vectorMultiply(v:Vector, n:Number):Vector {
|
||||||
|
return new Vector(v.x*n, v.y*n, v.z*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Скалярное произведение векторов
|
||||||
|
static public function vectorDot(v1:Vector, v2:Vector):Number {
|
||||||
|
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Векторное произведение векторов
|
||||||
|
static public function vectorCross(v1:Vector, v2:Vector):Vector {
|
||||||
|
return new Vector(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Угол между векторами
|
||||||
|
static public function vectorAngle(v1:Vector, v2:Vector):Number {
|
||||||
|
var len:Number = vectorLength(v1)*vectorLength(v2);
|
||||||
|
// Если один из векторов нулевой, угол - 0 градусов
|
||||||
|
var cos:Number = (len != 0) ? (vectorDot(v1, v2) / len) : 1;
|
||||||
|
return Math.acos(cos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Угол между векторами (работает только если векторы нормализованы)
|
||||||
|
static public function vectorAngleFast(v1:Vector, v2:Vector):Number {
|
||||||
|
return Math.acos(vectorDot(v1, v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отбрасывает дробную часть у координат вектора
|
||||||
|
static public function vectorFloor(v:Vector):Vector {
|
||||||
|
return new Vector(Math.floor(v.x), Math.floor(v.y), Math.floor(v.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сравнение векторов с погрешностью
|
||||||
|
static public function vectorEquals(v1:Vector, v2:Vector, delta:Number = 0):Boolean {
|
||||||
|
var d:Vector = vectorSub(v1, v2);
|
||||||
|
return (Math.abs(d.x) <= delta) && (Math.abs(d.y) <= delta) && (Math.abs(d.z) <= delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нахождение нормали грани
|
||||||
|
static public function normal(points:Array):Vector {
|
||||||
|
var v1:Vector = new Vector(points[1].x - points[0].x, points[1].y - points[0].y, points[1].z - points[0].z);
|
||||||
|
var v2:Vector = new Vector(points[1].x - points[2].x, points[1].y - points[2].y, points[1].z - points[2].z);
|
||||||
|
var res:Vector = vectorCross(v1, v2);
|
||||||
|
normalize(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перенос матрицы
|
||||||
|
static public function translateMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
m.d += x;
|
||||||
|
m.h += y;
|
||||||
|
m.l += z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы
|
||||||
|
static public function scaleMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
m.a *= x;
|
||||||
|
m.b *= x;
|
||||||
|
m.c *= x;
|
||||||
|
m.d *= x;
|
||||||
|
m.e *= y;
|
||||||
|
m.f *= y;
|
||||||
|
m.g *= y;
|
||||||
|
m.h *= y;
|
||||||
|
m.i *= z;
|
||||||
|
m.j *= z;
|
||||||
|
m.k *= z;
|
||||||
|
m.l *= z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по X
|
||||||
|
static public function scaleXMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.a *= value;
|
||||||
|
m.b *= value;
|
||||||
|
m.c *= value;
|
||||||
|
m.d *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по Y
|
||||||
|
static public function scaleYMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.e *= value;
|
||||||
|
m.f *= value;
|
||||||
|
m.g *= value;
|
||||||
|
m.h *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Масштабирование матрицы по Z
|
||||||
|
static public function scaleZMatrix(m:Matrix3D, value:Number):void {
|
||||||
|
m.i *= value;
|
||||||
|
m.j *= value;
|
||||||
|
m.k *= value;
|
||||||
|
m.l *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы
|
||||||
|
static public function rotateMatrix(m:Matrix3D, x:Number, y:Number, z:Number):void {
|
||||||
|
var xRadian:Number = Math3D.toRadian(x);
|
||||||
|
var yRadian:Number = Math3D.toRadian(y);
|
||||||
|
var zRadian:Number = Math3D.toRadian(z);
|
||||||
|
var cosX:Number = Math.cos(xRadian);
|
||||||
|
var sinX:Number = Math.sin(xRadian);
|
||||||
|
var cosY:Number = Math.cos(yRadian);
|
||||||
|
var sinY:Number = Math.sin(yRadian);
|
||||||
|
var cosZ:Number = Math.cos(zRadian);
|
||||||
|
var sinZ:Number = Math.sin(zRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
var cosZsinY:Number = cosZ*sinY;
|
||||||
|
var sinZsinY:Number = sinZ*sinY;
|
||||||
|
|
||||||
|
var ra:Number = cosZ*cosY;
|
||||||
|
var rb:Number = cosZsinY*sinX - sinZ*cosX;
|
||||||
|
var rc:Number = cosZsinY*cosX + sinZ*sinX;
|
||||||
|
|
||||||
|
var re:Number = sinZ*cosY;
|
||||||
|
var rf:Number = sinZsinY*sinX + cosZ*cosX;
|
||||||
|
var rg:Number = sinZsinY*cosX - cosZ*sinX;
|
||||||
|
|
||||||
|
var ri:Number = -sinY;
|
||||||
|
var rj:Number = cosY*sinX;
|
||||||
|
var rk:Number = cosY*cosX;
|
||||||
|
|
||||||
|
m.a = ra*a + rb*e + rc*i;
|
||||||
|
m.b = ra*b + rb*f + rc*j;
|
||||||
|
m.c = ra*c + rb*g + rc*k;
|
||||||
|
m.d = ra*d + rb*h + rc*l;
|
||||||
|
|
||||||
|
m.e = re*a + rf*e + rg*i;
|
||||||
|
m.f = re*b + rf*f + rg*j;
|
||||||
|
m.g = re*c + rf*g + rg*k;
|
||||||
|
m.h = re*d + rf*h + rg*l;
|
||||||
|
|
||||||
|
m.i = ri*a + rj*e + rk*i;
|
||||||
|
m.j = ri*b + rj*f + rk*j;
|
||||||
|
m.k = ri*c + rj*g + rk*k;
|
||||||
|
m.l = ri*d + rj*h + rk*l;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль X
|
||||||
|
static public function rotateXMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
m.e = cos*e - sin*i;
|
||||||
|
m.f = cos*f - sin*j;
|
||||||
|
m.g = cos*g - sin*k;
|
||||||
|
m.h = cos*h - sin*l;
|
||||||
|
|
||||||
|
m.i = sin*e + cos*i;
|
||||||
|
m.j = sin*f + cos*j;
|
||||||
|
m.k = sin*g + cos*k;
|
||||||
|
m.l = sin*h + cos*l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль Y
|
||||||
|
static public function rotateYMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var i:Number = m.i;
|
||||||
|
var j:Number = m.j;
|
||||||
|
var k:Number = m.k;
|
||||||
|
var l:Number = m.l;
|
||||||
|
|
||||||
|
m.a = cos*a + sin*i;
|
||||||
|
m.b = cos*b + sin*j;
|
||||||
|
m.c = cos*c + sin*k;
|
||||||
|
m.d = cos*d + sin*l;
|
||||||
|
|
||||||
|
m.i = -sin*a + cos*i;
|
||||||
|
m.j = -sin*b + cos*j;
|
||||||
|
m.k = -sin*c + cos*k;
|
||||||
|
m.l = -sin*d + cos*l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поворот матрицы вдоль Z
|
||||||
|
static public function rotateZMatrix(m:Matrix3D, angle:Number):void {
|
||||||
|
var angleRadian:Number = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angleRadian);
|
||||||
|
var cos:Number = Math.cos(angleRadian);
|
||||||
|
|
||||||
|
var a:Number = m.a;
|
||||||
|
var b:Number = m.b;
|
||||||
|
var c:Number = m.c;
|
||||||
|
var d:Number = m.d;
|
||||||
|
var e:Number = m.e;
|
||||||
|
var f:Number = m.f;
|
||||||
|
var g:Number = m.g;
|
||||||
|
var h:Number = m.h;
|
||||||
|
|
||||||
|
m.a = cos*a - sin*e;
|
||||||
|
m.b = cos*b - sin*f;
|
||||||
|
m.c = cos*c - sin*g;
|
||||||
|
m.d = cos*d - sin*h;
|
||||||
|
|
||||||
|
m.e = sin*a + cos*e;
|
||||||
|
m.f = sin*b + cos*f;
|
||||||
|
m.g = sin*c + cos*g;
|
||||||
|
m.h = sin*d + cos*h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Умножение матриц
|
||||||
|
static public function combineMatrix(m1:Matrix3D, m2:Matrix3D):Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
|
||||||
|
res.a = m1.a*m2.a + m1.b*m2.e + m1.c*m2.i;
|
||||||
|
res.b = m1.a*m2.b + m1.b*m2.f + m1.c*m2.j;
|
||||||
|
res.c = m1.a*m2.c + m1.b*m2.g + m1.c*m2.k;
|
||||||
|
res.d = m1.a*m2.d + m1.b*m2.h + m1.c*m2.l + m1.d;
|
||||||
|
|
||||||
|
res.e = m1.e*m2.a + m1.f*m2.e + m1.g*m2.i;
|
||||||
|
res.f = m1.e*m2.b + m1.f*m2.f + m1.g*m2.j;
|
||||||
|
res.g = m1.e*m2.c + m1.f*m2.g + m1.g*m2.k;
|
||||||
|
res.h = m1.e*m2.d + m1.f*m2.h + m1.g*m2.l + m1.h;
|
||||||
|
|
||||||
|
res.i = m1.i*m2.a + m1.j*m2.e + m1.k*m2.i;
|
||||||
|
res.j = m1.i*m2.b + m1.j*m2.f + m1.k*m2.j;
|
||||||
|
res.k = m1.i*m2.c + m1.j*m2.g + m1.k*m2.k;
|
||||||
|
res.l = m1.i*m2.d + m1.j*m2.h + m1.k*m2.l + m1.l;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Трансформация вектора через матрицу
|
||||||
|
static public function vectorTransform(v:Vector, m:Matrix3D):Vector {
|
||||||
|
var res:Vector = new Vector();
|
||||||
|
res.x = m.a*v.x + m.b*v.y + m.c*v.z + m.d;
|
||||||
|
res.y = m.e*v.x + m.f*v.y + m.g*v.z + m.h;
|
||||||
|
res.z = m.i*v.x + m.j*v.y + m.k*v.z + m.l;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на пересечение луча с заданным треугольником
|
||||||
|
static public function tryangleIntersection(a:Vector, b:Vector, c:Vector, n:Vector, v1:Vector, v2:Vector): Vector {
|
||||||
|
var res:Vector;
|
||||||
|
|
||||||
|
var d:Number = -n.x*a.x - n.y*a.y - n.z*a.z;
|
||||||
|
var v:Vector = new Vector(v2.x-v1.x, v2.y-v1.y, v2.z-v1.z);
|
||||||
|
var nv:Number = (n.x*v.x + n.y*v.y + n.z*v.z);
|
||||||
|
if (nv != 0) {
|
||||||
|
//нахождение точки пересечения луча с плоскостью полигона
|
||||||
|
var t:Number = -(d + n.x*v1.x + n.y*v1.y + n.z*v1.z)/nv;
|
||||||
|
res = new Vector(v1.x + t*v.x,v1.y + t*v.y,v1.z + t*v.z);
|
||||||
|
//проверка на попадание точки пересечения в заданный треугольник
|
||||||
|
var uu:Number = ((res.x - a.x)*(c.y - a.y)-(c.x - a.x)*(res.y - a.y))/((b.x - a.x)*(c.y - a.y)-(c.x - a.x)*(b.y - a.y));
|
||||||
|
var vv:Number = (res.y - a.y - uu*(b.y - a.y))/(c.y - a.y);
|
||||||
|
if (!(uu > 0 && vv > 0 && (1-uu-vv) > 0)) {
|
||||||
|
//точка не лежит в треугольнике
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//луч параллелен плоскости
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//проверка на прохождение луча (v1, v2) через сферу с центром (c) заданного радиуса (r)
|
||||||
|
static public function sphereIntersection(c:Vector, r:Number, v1:Vector, v2:Vector):Vector {
|
||||||
|
var res: Vector;
|
||||||
|
|
||||||
|
var v: Vector = new Vector(v2.x-v1.x, v2.y-v1.y, v2.z-v1.z);
|
||||||
|
var n: Vector = new Vector(-v.x,-v.y,-v.z);
|
||||||
|
|
||||||
|
var d: Number = -n.x*c.x - n.y*c.y - n.z*c.z;
|
||||||
|
var nv: Number = (n.x*v.x + n.y*v.y + n.z*v.z);
|
||||||
|
// нахождение точки пересечения луча с плоскостью перпендикулярной лучу,
|
||||||
|
// проходящей через центр сферы
|
||||||
|
var t: Number = -(d + n.x*v1.x + n.y*v1.y + n.z*v1.z)/nv;
|
||||||
|
res = new Vector(v1.x + t*v.x,v1.y + t*v.y,v1.z + t*v.z);
|
||||||
|
//определение длины перпендикуляра
|
||||||
|
var l: Number = Math.sqrt((res.x-c.x)*(res.x-c.x) + (res.y-c.y)*(res.y-c.y) + (res.z-c.z)*(res.z-c.z));
|
||||||
|
if (l > r) {
|
||||||
|
res = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нахождение перпендикуляра к отрезку(v1, v2) из произвольной точки(c)
|
||||||
|
static public function perpendicularToSegment(c:Vector, v1:Vector, v2:Vector):Vector {
|
||||||
|
var res:Vector;
|
||||||
|
|
||||||
|
var v:Vector = vectorSub(v2, v1);
|
||||||
|
var n:Vector = new Vector(-v.x, -v.y, -v.z);
|
||||||
|
|
||||||
|
var d:Number = -vectorDot(n, c);
|
||||||
|
var nv:Number = vectorDot(n, v);
|
||||||
|
|
||||||
|
var t:Number = -(d + vectorDot(n, v1))/nv;
|
||||||
|
res = vectorAdd(v1, vectorMultiply(v, t));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расстояние от точки до ребра в плоскости камеры
|
||||||
|
static public function segmentDistance(first:Point, second:Point, point:Point):Number {
|
||||||
|
// Вектор ребра
|
||||||
|
var dx:Number = second.x - first.x;
|
||||||
|
var dy:Number = second.y - first.y;
|
||||||
|
|
||||||
|
// Вектор точки
|
||||||
|
var px:Number = point.x - first.x;
|
||||||
|
var py:Number = point.y - first.y;
|
||||||
|
|
||||||
|
// Векторное произведение (площадь параллелограмма) поделить на длину ребра
|
||||||
|
return (dx*py - dy*px)/Math.sqrt(dx*dx + dy*dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Попадает ли точка в 2D-треугольник
|
||||||
|
static public function tryangleHasPoint(a:Point, b:Point, c:Point, point:Point):Boolean {
|
||||||
|
if (vectorCross2D(c.subtract(a), point.subtract(a)) <= 0) {
|
||||||
|
if (vectorCross2D(b.subtract(c), point.subtract(c)) <= 0) {
|
||||||
|
if (vectorCross2D(a.subtract(b), point.subtract(b)) <= 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function vectorCross2D(a:Point, b:Point):Number {
|
||||||
|
return a.x*b.y - a.y*b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
52
Alternativa3D2/2.0/com/alternativagame/engine3d/Matrix3D.as
Normal file
52
Alternativa3D2/2.0/com/alternativagame/engine3d/Matrix3D.as
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
public final class Matrix3D {
|
||||||
|
public var a:Number = 1;
|
||||||
|
public var b:Number = 0;
|
||||||
|
public var c:Number = 0;
|
||||||
|
public var d:Number = 0;
|
||||||
|
public var e:Number = 0;
|
||||||
|
public var f:Number = 1;
|
||||||
|
public var g:Number = 0;
|
||||||
|
public var h:Number = 0;
|
||||||
|
public var i:Number = 0;
|
||||||
|
public var j:Number = 0;
|
||||||
|
public var k:Number = 1;
|
||||||
|
public var l:Number = 0;
|
||||||
|
|
||||||
|
public function Matrix3D(x:Number = 0, y:Number = 0, z:Number = 0, rotX:Number = 0, rotY:Number = 0, rotZ:Number = 0, scaleX:Number = 1, scaleY:Number = 1, scaleZ:Number = 1) {
|
||||||
|
// Если указано масштабирование
|
||||||
|
if (arguments.length > 6) {
|
||||||
|
Math3D.scaleMatrix(this, scaleX, scaleY, scaleZ);
|
||||||
|
}
|
||||||
|
// Если указан поворот
|
||||||
|
if (arguments.length > 3) {
|
||||||
|
Math3D.rotateMatrix(this, rotX, rotY, rotZ);
|
||||||
|
}
|
||||||
|
// Если указано смещение
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
Math3D.translateMatrix(this, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clone():Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
res.a = a;
|
||||||
|
res.b = b;
|
||||||
|
res.c = c;
|
||||||
|
res.d = d;
|
||||||
|
res.e = e;
|
||||||
|
res.f = f;
|
||||||
|
res.g = g;
|
||||||
|
res.h = h;
|
||||||
|
res.i = i;
|
||||||
|
res.j = j;
|
||||||
|
res.k = k;
|
||||||
|
res.l = l;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toString():String {
|
||||||
|
return "Matrix:\r" + a.toFixed(3) + "\t" + b.toFixed(3) + "\t" + c.toFixed(3) + "\t" + d.toFixed(3) + "\r" + e.toFixed(3) + "\t" + f.toFixed(3) + "\t" + g.toFixed(3) + "\t" + h.toFixed(3) + "\r" + i.toFixed(3) + "\t" + j.toFixed(3) + "\t" + k.toFixed(3) + "\t" + l.toFixed(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
540
Alternativa3D2/2.0/com/alternativagame/engine3d/View3D.as
Normal file
540
Alternativa3D2/2.0/com/alternativagame/engine3d/View3D.as
Normal file
@@ -0,0 +1,540 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import flash.display.DisplayObjectContainer;
|
||||||
|
import flash.display.Shape;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import flash.geom.ColorTransform;
|
||||||
|
import flash.geom.Point;
|
||||||
|
import flash.geom.Rectangle;
|
||||||
|
import flash.utils.clearTimeout;
|
||||||
|
import flash.utils.setTimeout;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class View3D extends Sprite {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Корневой объект
|
||||||
|
private var _object:Object3D = null;
|
||||||
|
|
||||||
|
// Область отрисовки спрайтов
|
||||||
|
private var canvas:Sprite;
|
||||||
|
private var canvasCoords:Vector;
|
||||||
|
|
||||||
|
// Список скинов на изменение глубины
|
||||||
|
private var skinsToDepth:Array;
|
||||||
|
// Список скинов на перепозиционирование
|
||||||
|
private var skinsToPosition:Set;
|
||||||
|
// Список скинов на отрисовку
|
||||||
|
private var skinsToDraw:Set;
|
||||||
|
// Список скинов на освещение
|
||||||
|
private var skinsToLight:Set;
|
||||||
|
|
||||||
|
// Размеры окна камеры
|
||||||
|
private var _width:uint;
|
||||||
|
private var _height:uint;
|
||||||
|
|
||||||
|
// Флаг ограничения окна камеры
|
||||||
|
private var _crop:Boolean = false;
|
||||||
|
|
||||||
|
// Координаты камеры относительно начала координат
|
||||||
|
private var _targetX:Number = 0;
|
||||||
|
private var _targetY:Number = 0;
|
||||||
|
private var _targetZ:Number = 0;
|
||||||
|
|
||||||
|
// Повороты камеры
|
||||||
|
private var _pitch:Number = 0;
|
||||||
|
private var _roll:Number = 0;
|
||||||
|
private var _yaw:Number = 0;
|
||||||
|
|
||||||
|
// Степень увеличения объектов
|
||||||
|
private var _zoom:Number = 1;
|
||||||
|
|
||||||
|
// Трансформация камеры
|
||||||
|
engine3d var transformation:Matrix3D;
|
||||||
|
engine3d var inverseTransformation:Matrix3D;
|
||||||
|
|
||||||
|
// Изменилась точка обзора камеры
|
||||||
|
engine3d var positionChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменился угол обзора или масштаб
|
||||||
|
engine3d var geometryChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Флаг заморозки камеры
|
||||||
|
private var _hold:Boolean = false;
|
||||||
|
|
||||||
|
// Текущий нажатый объект
|
||||||
|
private var pressedObject:Object3D;
|
||||||
|
|
||||||
|
public function View3D(width:uint, height:uint) {
|
||||||
|
|
||||||
|
hitArea = new Sprite();
|
||||||
|
hitArea.mouseEnabled = false;
|
||||||
|
hitArea.visible = false;
|
||||||
|
with (hitArea.graphics) {
|
||||||
|
beginFill(0);
|
||||||
|
drawRect(0, 0, 100, 100);
|
||||||
|
}
|
||||||
|
addChild(hitArea);
|
||||||
|
|
||||||
|
canvas = new Sprite();
|
||||||
|
canvas.mouseEnabled = false;
|
||||||
|
canvas.mouseChildren = false;
|
||||||
|
addChild(canvas);
|
||||||
|
|
||||||
|
canvasCoords = new Vector();
|
||||||
|
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
skinsToDepth = new Array();
|
||||||
|
skinsToPosition = new Set();
|
||||||
|
skinsToDraw = new Set();
|
||||||
|
skinsToLight = new Set();
|
||||||
|
|
||||||
|
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
|
||||||
|
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onMouseDown(e:MouseEvent):void {
|
||||||
|
dispatchEvent3D(Event3D.DOWN, e.ctrlKey, e.altKey, e.shiftKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onMouseUp(e:MouseEvent):void {
|
||||||
|
dispatchEvent3D(Event3D.UP, e.ctrlKey, e.altKey, e.shiftKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dispatchEvent3D(type:String, ctrlKey:Boolean, altKey:Boolean, shiftKey:Boolean):void {
|
||||||
|
var mouse:Point = new Point(stage.mouseX, stage.mouseY);
|
||||||
|
var skin:Skin = getSkinFromPoint(mouse);
|
||||||
|
|
||||||
|
// Если нажали на интерактивный скин
|
||||||
|
if (skin != null && skin.interactive) {
|
||||||
|
|
||||||
|
// При нажатии сохраняем нажатый объект
|
||||||
|
if (type == Event3D.DOWN) {
|
||||||
|
pressedObject = skin.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
var click:Boolean = (type == Event3D.UP && pressedObject == skin.object);
|
||||||
|
|
||||||
|
// Получаем пересечение вектора мыши со скином
|
||||||
|
var canvasCoords:Vector = skin.getIntersectionCoords(canvas.globalToLocal(mouse));
|
||||||
|
|
||||||
|
// Формируем ветку объектов
|
||||||
|
var objectList:Array = skin.object.getBranch();
|
||||||
|
|
||||||
|
// Перевести точку в мировые координаты
|
||||||
|
var worldCoords:Vector = Math3D.vectorTransform(canvasCoords, inverseTransformation);
|
||||||
|
|
||||||
|
// Рассчитываем точку в координатах каждого из родительских объектах и формируем список
|
||||||
|
var coordsList:Array = new Array();
|
||||||
|
|
||||||
|
var objectMatrix:Matrix3D;
|
||||||
|
var objectCoords:Vector = worldCoords.clone();
|
||||||
|
var currentObject:Object3D;
|
||||||
|
|
||||||
|
// Перебираем список объектов с конца (с корневого объекта)
|
||||||
|
var i:int;
|
||||||
|
for (i = objectList.length - 1; i >= 0; i--) {
|
||||||
|
currentObject = objectList[i];
|
||||||
|
// Трансформируем точку через матрицу в локальные координаты текущего объекта
|
||||||
|
objectCoords = Math3D.vectorTransform(objectCoords, currentObject.inverseTransform);
|
||||||
|
coordsList[i] = objectCoords.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рассылаем события от объектов
|
||||||
|
for (i = 0; i < objectList.length; i++) {
|
||||||
|
currentObject = objectList[i];
|
||||||
|
currentObject.dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, coordsList[i]));
|
||||||
|
// Если отжали на нажатом объекте, то отправить ещё и клик
|
||||||
|
if (click) {
|
||||||
|
currentObject.dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, coordsList[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отослать событие от камеры
|
||||||
|
dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, worldCoords));
|
||||||
|
|
||||||
|
// Если отжали на нажатом объекте, то отправить ещё и клик
|
||||||
|
if (click) {
|
||||||
|
dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey, skin.object, skin.polygon, skin.material, canvasCoords, objectCoords, worldCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// При нажатии на пустое место сбрасываем нажатый объект
|
||||||
|
if (type == Event3D.DOWN) {
|
||||||
|
pressedObject = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рассылаем пустое событие
|
||||||
|
dispatchEvent(new Event3D(type, ctrlKey, altKey, shiftKey));
|
||||||
|
|
||||||
|
// Если нажатый объект также был пуст, то отправить клик на пустое место
|
||||||
|
if (type == Event3D.UP && pressedObject == null) {
|
||||||
|
dispatchEvent(new Event3D(Event3D.CLICK, ctrlKey, altKey, shiftKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить скин по заданным координатам
|
||||||
|
public function getSkinFromPoint(point:Point):Skin {
|
||||||
|
// Получаем список объектов под координатой
|
||||||
|
var objectList:Array = getObjectsUnderPoint(point);
|
||||||
|
|
||||||
|
// Оставить в списке только скины
|
||||||
|
var skinList:Array = new Array();
|
||||||
|
var len:uint = objectList.length;
|
||||||
|
for (var i:uint = 0; i < len; i++) {
|
||||||
|
if (objectList[i] is Skin) {
|
||||||
|
skinList.push(objectList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортируем их по глубине
|
||||||
|
skinList.sortOn("sortDepth", Array.NUMERIC);
|
||||||
|
|
||||||
|
// Возвращаем самый близкий
|
||||||
|
return skinList[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Заморозить изображение камеры
|
||||||
|
public function hold():void {
|
||||||
|
_hold = true;
|
||||||
|
canvas.cacheAsBitmap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Заморозить изображение камеры
|
||||||
|
public function unhold():void {
|
||||||
|
_hold = false;
|
||||||
|
canvas.cacheAsBitmap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перерисовать объекты в камере
|
||||||
|
public function draw():void {
|
||||||
|
if (object != null) {
|
||||||
|
|
||||||
|
// Если изменилась геометрия
|
||||||
|
if (geometryChanged) {
|
||||||
|
|
||||||
|
// Пересчитать трансформацию
|
||||||
|
transformation = new Matrix3D();
|
||||||
|
Math3D.rotateZMatrix(transformation, -_yaw);
|
||||||
|
Math3D.rotateYMatrix(transformation, -_roll);
|
||||||
|
Math3D.rotateXMatrix(transformation, -_pitch);
|
||||||
|
Math3D.scaleMatrix(transformation, _zoom, _zoom, _zoom);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если изменилась позиция
|
||||||
|
if (geometryChanged || positionChanged) {
|
||||||
|
|
||||||
|
// Передвигаем всю область скинов
|
||||||
|
canvasCoords = Math3D.vectorTransform(new Vector(-_targetX, -_targetY, -_targetZ), transformation);
|
||||||
|
|
||||||
|
// Пересчитать инверсную трансформацию
|
||||||
|
var inv:Matrix3D = new Matrix3D(_targetX, _targetY, _targetZ, _pitch, _roll, _yaw, 1/_zoom, 1/_zoom, 1/_zoom);
|
||||||
|
inv.d += inv.a*canvasCoords.x + inv.b*canvasCoords.y + inv.c*canvasCoords.z;
|
||||||
|
inv.h += inv.e*canvasCoords.x + inv.f*canvasCoords.y + inv.g*canvasCoords.z;
|
||||||
|
inv.l += inv.i*canvasCoords.x + inv.j*canvasCoords.y + inv.k*canvasCoords.z;
|
||||||
|
inverseTransformation = inv;
|
||||||
|
|
||||||
|
canvas.x = width/2 + canvasCoords.x;
|
||||||
|
canvas.y = height/2 - canvasCoords.z;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
geometryChanged = false;
|
||||||
|
positionChanged = false;
|
||||||
|
|
||||||
|
// Если камера не заморожена
|
||||||
|
if (!_hold) {
|
||||||
|
// Расчитываем трансформацию дерева объектов
|
||||||
|
object.calculateTransform();
|
||||||
|
|
||||||
|
// Расчитать освещение дерева объектов
|
||||||
|
object.calculateLight();
|
||||||
|
|
||||||
|
|
||||||
|
if (skinsToDepth.length > 0 || skinsToPosition.length > 0 || skinsToDraw.length > 0 || skinsToLight.length > 0) {
|
||||||
|
trace(skinsToDepth.length, skinsToDraw.length, skinsToPosition.length, skinsToLight.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Сортируем глубины
|
||||||
|
sortDepths();
|
||||||
|
|
||||||
|
var skin:Skin;
|
||||||
|
// Позиционируем скины
|
||||||
|
for each (skin in skinsToPosition) {
|
||||||
|
skin.position();
|
||||||
|
}
|
||||||
|
skinsToPosition = new Set();
|
||||||
|
|
||||||
|
// Отрисовываем скины
|
||||||
|
for each (skin in skinsToDraw) {
|
||||||
|
skin.draw();
|
||||||
|
}
|
||||||
|
skinsToDraw = new Set();
|
||||||
|
|
||||||
|
// Освещаем скины
|
||||||
|
for each (skin in skinsToLight) {
|
||||||
|
skin.light();
|
||||||
|
}
|
||||||
|
skinsToLight = new Set();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запуск стирания скина
|
||||||
|
private function clearSkin(skin:Skin, index:int, arr:Array):void {
|
||||||
|
canvas.removeChild(DisplayObject(skin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортировка глубин скинов
|
||||||
|
private function sortDepths():void {
|
||||||
|
|
||||||
|
// Убираем скины из списка
|
||||||
|
skinsToDepth.forEach(clearSkin);
|
||||||
|
|
||||||
|
// Сортируем скины по глубине
|
||||||
|
skinsToDepth.sortOn("sortDepth", Array.NUMERIC | Array.DESCENDING);
|
||||||
|
|
||||||
|
// Вставляем скины на нужные глубины
|
||||||
|
var ma:int = -1;
|
||||||
|
var mb:int = (canvas.numChildren > 0) ? canvas.numChildren : 0;
|
||||||
|
|
||||||
|
var side:Boolean = false;
|
||||||
|
var skin:Skin;
|
||||||
|
var a:int;
|
||||||
|
var b:int;
|
||||||
|
var c:int;
|
||||||
|
var len:uint = skinsToDepth.length;
|
||||||
|
|
||||||
|
for (var i:uint = 0; i < len; i++) {
|
||||||
|
skin = (side) ? skinsToDepth.pop() : skinsToDepth.shift();
|
||||||
|
a = ma;
|
||||||
|
b = mb;
|
||||||
|
while (a < b - 1) {
|
||||||
|
c = (a + b) >>> 1;
|
||||||
|
(skin.sortDepth >= (canvas.getChildAt(c) as Skin).sortDepth) ? (b = c) : (a = c);
|
||||||
|
}
|
||||||
|
canvas.addChildAt(DisplayObject(skin), b);
|
||||||
|
(side) ? (mb = b) : (ma = b);
|
||||||
|
mb++;
|
||||||
|
side = !side;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список изменения глубин
|
||||||
|
engine3d function addToDepth(skin:Skin):void {
|
||||||
|
if (skinsToDepth.indexOf(skin) < 0) skinsToDepth.push(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список репозиционированных в следующий раз
|
||||||
|
engine3d function addToPosition(skin:Skin):void {
|
||||||
|
skinsToPosition.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список отрисовываемых в следующий раз
|
||||||
|
engine3d function addToDraw(skin:Skin):void {
|
||||||
|
skinsToDraw.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин в список освещаемых в следующий раз
|
||||||
|
engine3d function addToLight(skin:Skin):void {
|
||||||
|
skinsToLight.add(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить скин
|
||||||
|
engine3d function addSkin(skin:Skin):void {
|
||||||
|
canvas.addChild(DisplayObject(skin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Убрать скин
|
||||||
|
engine3d function removeSkin(skin:Skin):void {
|
||||||
|
// Удаляем скин из камеры
|
||||||
|
canvas.removeChild(DisplayObject(skin));
|
||||||
|
// Удаляем из списка на сортировку
|
||||||
|
var i:int = skinsToDepth.indexOf(skin);
|
||||||
|
if (i>=0) skinsToDepth.splice(i,1);
|
||||||
|
// Удаляем из список на отрисовку, позиционирование и освещение
|
||||||
|
skinsToPosition.remove(skin);
|
||||||
|
skinsToDraw.remove(skin);
|
||||||
|
skinsToLight.remove(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Указать корневой объект
|
||||||
|
public function set object(value:Object3D):void {
|
||||||
|
// Если есть текущий объект
|
||||||
|
if (object != null) {
|
||||||
|
// Снимаем у него камеру
|
||||||
|
object.setView(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если устанавливаем не пустой объект
|
||||||
|
if (value != null) {
|
||||||
|
// Если объект был в другой камере и был там корневым
|
||||||
|
if (value.view != null && value === value.view.object) {
|
||||||
|
// Снимаем у той камеры объект
|
||||||
|
value.view.object = null;
|
||||||
|
} else {
|
||||||
|
// Если объект был в другом объекте
|
||||||
|
if (value.parent != null) {
|
||||||
|
// Удалить его оттуда
|
||||||
|
value.parent.detach(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Указываем объектам камеру
|
||||||
|
value.setView(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_object = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get object():Object3D {
|
||||||
|
return _object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetX():Number {
|
||||||
|
return _targetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetY():Number {
|
||||||
|
return _targetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get targetZ():Number {
|
||||||
|
return _targetZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get zoom():Number {
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pitch():Number {
|
||||||
|
return _pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get roll():Number {
|
||||||
|
return _roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get yaw():Number {
|
||||||
|
return _yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetX(value:Number):void {
|
||||||
|
_targetX = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetY(value:Number):void {
|
||||||
|
_targetY = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set targetZ(value:Number):void {
|
||||||
|
_targetZ = value;
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set pitch(value:Number):void {
|
||||||
|
_pitch = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set roll(value:Number):void {
|
||||||
|
_roll = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set yaw(value:Number):void {
|
||||||
|
_yaw = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set zoom(value:Number):void {
|
||||||
|
_zoom = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setGeometryChanged():void {
|
||||||
|
// Изменить геометрию у объекта и его потомков
|
||||||
|
if (!geometryChanged && object != null) {
|
||||||
|
object.setGeometryChanged();
|
||||||
|
geometryChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set width(value:Number):void {
|
||||||
|
_width = value;
|
||||||
|
hitArea.width = _width;
|
||||||
|
canvas.x = _width/2 + canvasCoords.x;
|
||||||
|
if (crop) {
|
||||||
|
scrollRect = new Rectangle(0, 0, _width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function get width():Number {
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set height(value:Number):void {
|
||||||
|
_height = value;
|
||||||
|
hitArea.height = _height;
|
||||||
|
canvas.y = _height/2 - canvasCoords.z;
|
||||||
|
if (crop) {
|
||||||
|
scrollRect = new Rectangle(0, 0, width, _height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function get height():Number {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set crop(value:Boolean):void {
|
||||||
|
_crop = value;
|
||||||
|
if (value) {
|
||||||
|
scrollRect = new Rectangle(0, 0, width, height);
|
||||||
|
} else {
|
||||||
|
scrollRect = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get crop():Boolean {
|
||||||
|
return _crop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get mouseCanvasCoords():Point {
|
||||||
|
var res:Point = null;
|
||||||
|
if (stage != null) {
|
||||||
|
res = canvas.globalToLocal(new Point(stage.mouseX, stage.mouseY));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canvasToView(coords:Vector):Vector {
|
||||||
|
return Math3D.vectorAdd(coords, canvasCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewToCanvas(coords:Vector):Vector {
|
||||||
|
return Math3D.vectorSub(coords, canvasCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.alternativagame.engine3d {
|
||||||
|
public namespace engine3d;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 109
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material
|
||||||
|
END
|
||||||
|
HelperMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 127
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/HelperMaterial.as
|
||||||
|
END
|
||||||
|
Material.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 121
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/Material.as
|
||||||
|
END
|
||||||
|
TextureMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 128
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/TextureMaterial.as
|
||||||
|
END
|
||||||
|
Hit.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 116
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/Hit.as
|
||||||
|
END
|
||||||
|
FillMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 125
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/FillMaterial.as
|
||||||
|
END
|
||||||
|
ObjectMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 127
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/ObjectMaterial.as
|
||||||
|
END
|
||||||
|
SpriteMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 127
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/SpriteMaterial.as
|
||||||
|
END
|
||||||
|
WireMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 125
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/WireMaterial.as
|
||||||
|
END
|
||||||
|
PolygonMaterial.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 128
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/PolygonMaterial.as
|
||||||
|
END
|
||||||
|
SpritePhase.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 124
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material/SpritePhase.as
|
||||||
|
END
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/material
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
HelperMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
d7d8be858db9e57e34b271b088279ff1
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Material.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
c9d48a2cc61f6b802a0d8119e4a43e3e
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
TextureMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
db1c1757075341b32fa63173f97714f7
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Hit.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
2b42963f326ef68c0aa3fe1fb6de5fa0
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
FillMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
c89150d47576ca2c7478ae0200b12215
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
ObjectMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
14d5f2b73bc1c620499cf213edf2d6c2
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
SpriteMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
23b7814c94cf9a6a92e522c0d1dc60d9
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
WireMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
25a8f37607fb392bceb3c84d533279c7
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
PolygonMaterial.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
a95823ced8c29dac440bc000593c517d
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
SpritePhase.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
db52856a883993329978d783c1c820d7
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class FillMaterial extends PolygonMaterial {
|
||||||
|
|
||||||
|
// Цвет при отсутствии текстуры
|
||||||
|
public var color:RGB;
|
||||||
|
|
||||||
|
// Цвет самосвечения материала
|
||||||
|
public var selfIllumination:RGB = new RGB();
|
||||||
|
|
||||||
|
public function FillMaterial(color:RGB = null, twoSided:Boolean = false) {
|
||||||
|
this.color = (color == null) ? new RGB(0x7F7F7F) : color;
|
||||||
|
this.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:FillMaterial = new FillMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:FillMaterial = FillMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.color = color.clone();
|
||||||
|
mat.selfIllumination = selfIllumination.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class HelperMaterial extends ObjectMaterial {
|
||||||
|
|
||||||
|
// Показывать подпись
|
||||||
|
public var text:Boolean;
|
||||||
|
|
||||||
|
// Цвет подписи
|
||||||
|
public var textColor:RGB = new RGB(0xFFFFFF);
|
||||||
|
|
||||||
|
// Показывать связь с родителем
|
||||||
|
public var link:Boolean;
|
||||||
|
|
||||||
|
// Показывать тело объекта
|
||||||
|
public var body:Boolean;
|
||||||
|
|
||||||
|
// Показывать вспомогательную графику объекта
|
||||||
|
public var gizmo:Boolean;
|
||||||
|
|
||||||
|
// Цвет тела объекта
|
||||||
|
public var bodyColor:RGB = new RGB(0xCCCCCC);
|
||||||
|
|
||||||
|
|
||||||
|
public function HelperMaterial(text:Boolean = true, link:Boolean = true, gizmo:Boolean = true, body:Boolean = true) {
|
||||||
|
this.text = text;
|
||||||
|
this.link = link;
|
||||||
|
this.gizmo = gizmo;
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:HelperMaterial = new HelperMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:HelperMaterial = HelperMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.text = text;
|
||||||
|
mat.textColor = textColor.clone();
|
||||||
|
mat.body = body;
|
||||||
|
mat.gizmo = gizmo;
|
||||||
|
mat.bodyColor = bodyColor.clone();
|
||||||
|
mat.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import flash.geom.Point;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
|
||||||
|
public final class Hit {
|
||||||
|
|
||||||
|
static public function ngon(n:uint, radiusX:Number, radiusY:Number = -1, offsetX:Number = 0, offsetY:Number = 0, angle:Number = 0):Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
n = (n < 3) ? 3 : n;
|
||||||
|
radiusY = (radiusY < 0) ? radiusX : radiusY;
|
||||||
|
angle = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angle);
|
||||||
|
var cos:Number = Math.cos(angle);
|
||||||
|
|
||||||
|
var a:Number = (Math.PI+Math.PI) / n;
|
||||||
|
for (var i:uint = 0; i < n; i++) {
|
||||||
|
var x:Number = offsetX + Math.sin(a*i)*radiusX;
|
||||||
|
var y:Number = offsetY - Math.cos(a*i)*radiusY;
|
||||||
|
|
||||||
|
var cx:Number = x*cos - y*sin;
|
||||||
|
var cy:Number = y*cos + x*sin;
|
||||||
|
|
||||||
|
res.push(new Point(cx, cy));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function rectangle(width:Number, height:Number, offsetX:Number = 0, offsetY:Number = 0):Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
var hw:Number = width/2;
|
||||||
|
var hh:Number = height/2;
|
||||||
|
res.push(new Point(offsetX - hw, offsetY - hh));
|
||||||
|
res.push(new Point(offsetX + hw, offsetY - hh));
|
||||||
|
res.push(new Point(offsetX + hw, offsetY + hh));
|
||||||
|
res.push(new Point(offsetX - hw, offsetY + hh));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
|
||||||
|
public class Material {
|
||||||
|
|
||||||
|
// Прозрачность материала
|
||||||
|
public var alpha:Number = 1;
|
||||||
|
|
||||||
|
// Метод наложения
|
||||||
|
public var blendMode:String = "normal";
|
||||||
|
|
||||||
|
// Смещение глубины
|
||||||
|
public var depthOffset:Number = 0;
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
public function clone():Material {
|
||||||
|
var res:Material = new Material();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
protected function cloneParams(material:*):void {
|
||||||
|
var mat:Material = Material(material);
|
||||||
|
mat.alpha = alpha;
|
||||||
|
mat.blendMode = blendMode;
|
||||||
|
mat.depthOffset = depthOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
public class ObjectMaterial extends Material {
|
||||||
|
|
||||||
|
// Массив точек хит-области
|
||||||
|
public var hit:Array = new Array();
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:ObjectMaterial = new ObjectMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:ObjectMaterial = ObjectMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.hit = hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
public class PolygonMaterial extends Material {
|
||||||
|
|
||||||
|
// Двусторонний материал
|
||||||
|
public var twoSided:Boolean;
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:PolygonMaterial = new PolygonMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:PolygonMaterial = PolygonMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import flash.geom.Point;
|
||||||
|
|
||||||
|
public class SpriteMaterial extends ObjectMaterial {
|
||||||
|
|
||||||
|
// Массив фаз
|
||||||
|
private var states:Array = new Array();
|
||||||
|
|
||||||
|
// Сглаженность
|
||||||
|
public var smoothing:Boolean;
|
||||||
|
|
||||||
|
// Цвет самосвечения материала
|
||||||
|
public var selfIllumination:RGB = new RGB();
|
||||||
|
|
||||||
|
// Флаги искажения спрайта
|
||||||
|
public var scale:Boolean;
|
||||||
|
public var rotate:Boolean;
|
||||||
|
|
||||||
|
public function SpriteMaterial(smoothing:Boolean = false, scale:Boolean = false, rotate:Boolean = false) {
|
||||||
|
this.smoothing = smoothing;
|
||||||
|
this.scale = scale;
|
||||||
|
this.rotate = rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPhase(bitmapData:BitmapData, pivot:Point = null, state:String = "default", pitch:Number = 0, yaw:Number = 0):void {
|
||||||
|
|
||||||
|
// Добавляем состояние, если надо
|
||||||
|
if (states[state] == undefined) {
|
||||||
|
states[state] = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
states[state].push(new SpritePhase(bitmapData, pivot, pitch, yaw));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращает фазу
|
||||||
|
public function getPhase(state:String = "default", pitch:Number = 0, yaw:Number = 0):SpritePhase {
|
||||||
|
var res:SpritePhase = null;
|
||||||
|
|
||||||
|
// Проверка на наличие состояние
|
||||||
|
if (states[state] != undefined) {
|
||||||
|
var phases:Array = states[state];
|
||||||
|
var num:uint = phases.length;
|
||||||
|
|
||||||
|
var i:uint;
|
||||||
|
var phase:SpritePhase;
|
||||||
|
var resPitch:Number;
|
||||||
|
var currentDiff:Number;
|
||||||
|
|
||||||
|
// Находим ближайший pitch
|
||||||
|
var minDiff:Number = Number.MAX_VALUE;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
phase = phases[i];
|
||||||
|
currentDiff = Math.abs(phase.pitch - pitch);
|
||||||
|
if (currentDiff < minDiff) {
|
||||||
|
minDiff = currentDiff;
|
||||||
|
resPitch = phase.pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Находим ближайший yaw и сохраняем результат
|
||||||
|
minDiff = Number.MAX_VALUE;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
phase = phases[i];
|
||||||
|
if (phase.pitch == resPitch) {
|
||||||
|
currentDiff = Math.abs(Math3D.deltaAngle(phase.yaw, yaw));
|
||||||
|
if (currentDiff < minDiff) {
|
||||||
|
minDiff = currentDiff;
|
||||||
|
res = phase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:SpriteMaterial = new SpriteMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:SpriteMaterial = SpriteMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.smoothing = smoothing;
|
||||||
|
mat.selfIllumination = selfIllumination.clone();
|
||||||
|
mat.scale = scale;
|
||||||
|
mat.rotate = rotate;
|
||||||
|
for (var state:String in states) {
|
||||||
|
for (var i:uint = 0; i < states[state].length; i++) {
|
||||||
|
var phase:SpritePhase = states[state][i];
|
||||||
|
mat.setPhase(phase.bitmapData, phase.pivot.clone(), state, phase.pitch, phase.yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import flash.geom.Point;
|
||||||
|
import com.alternativagame.engine3d.Matrix3D;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
|
||||||
|
public class SpritePhase {
|
||||||
|
|
||||||
|
// Битмапа фазы
|
||||||
|
public var bitmapData:BitmapData;
|
||||||
|
|
||||||
|
// Точка привязки битмапы
|
||||||
|
private var _pivot:Point;
|
||||||
|
|
||||||
|
private var _transform:Matrix3D;
|
||||||
|
|
||||||
|
private var _pitch:Number;
|
||||||
|
private var _yaw:Number;
|
||||||
|
|
||||||
|
public function SpritePhase(bitmapData:BitmapData, pivot:Point, pitch:Number, yaw:Number) {
|
||||||
|
this.bitmapData = bitmapData;
|
||||||
|
_pivot = (pivot == null) ? new Point(bitmapData.width / 2, bitmapData.height / 2) : pivot;
|
||||||
|
|
||||||
|
// Проверка углов
|
||||||
|
pitch = Math3D.limitAngle(pitch);
|
||||||
|
if (pitch < 0) {
|
||||||
|
if (pitch < -90) {
|
||||||
|
pitch = -180 - pitch;
|
||||||
|
yaw += 180;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pitch > 90) {
|
||||||
|
pitch = 180 - pitch;
|
||||||
|
yaw += 180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yaw = Math3D.limitAngle(yaw);
|
||||||
|
|
||||||
|
// Сохраняем углы
|
||||||
|
_pitch = pitch;
|
||||||
|
_yaw = yaw;
|
||||||
|
|
||||||
|
// Формируем матрицу трансформации фазы
|
||||||
|
_transform = new Matrix3D();
|
||||||
|
Math3D.translateMatrix(_transform, -_pivot.x, 0, _pivot.y);
|
||||||
|
|
||||||
|
Math3D.rotateXMatrix(_transform, -_pitch);
|
||||||
|
Math3D.rotateZMatrix(_transform, -_yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get transform():Matrix3D {
|
||||||
|
return _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pitch():Number {
|
||||||
|
return _pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get yaw():Number {
|
||||||
|
return _yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pivot():Point {
|
||||||
|
return _pivot;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
|
||||||
|
public final class TextureMaterial extends FillMaterial {
|
||||||
|
|
||||||
|
// Текстура
|
||||||
|
public var texture:BitmapData = null;
|
||||||
|
|
||||||
|
// Сглаженность
|
||||||
|
public var smoothing:Boolean;
|
||||||
|
|
||||||
|
public function TextureMaterial(texture:BitmapData = null, smoothing:Boolean = true, color:RGB = null, twoSided:Boolean = false) {
|
||||||
|
super(color, twoSided);
|
||||||
|
this.texture = texture;
|
||||||
|
this.smoothing = smoothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:TextureMaterial = new TextureMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:TextureMaterial = TextureMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.texture = texture;
|
||||||
|
mat.smoothing = smoothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class WireMaterial extends PolygonMaterial {
|
||||||
|
|
||||||
|
// Цвет рёбер
|
||||||
|
public var color:RGB;
|
||||||
|
|
||||||
|
// Толщина рёбер
|
||||||
|
public var thickness:Number;
|
||||||
|
|
||||||
|
public function WireMaterial(color:RGB = null, thickness:Number = 1, twoSided:Boolean = false) {
|
||||||
|
this.color = (color == null) ? new RGB(0xFFFFFF) : color;
|
||||||
|
this.thickness = thickness;
|
||||||
|
this.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:WireMaterial = new WireMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:WireMaterial = WireMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.color = color.clone();
|
||||||
|
mat.thickness = thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class FillMaterial extends PolygonMaterial {
|
||||||
|
|
||||||
|
// Цвет при отсутствии текстуры
|
||||||
|
public var color:RGB;
|
||||||
|
|
||||||
|
// Цвет самосвечения материала
|
||||||
|
public var selfIllumination:RGB = new RGB();
|
||||||
|
|
||||||
|
public function FillMaterial(color:RGB = null, twoSided:Boolean = false) {
|
||||||
|
this.color = (color == null) ? new RGB(0x7F7F7F) : color;
|
||||||
|
this.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:FillMaterial = new FillMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:FillMaterial = FillMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.color = color.clone();
|
||||||
|
mat.selfIllumination = selfIllumination.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class HelperMaterial extends ObjectMaterial {
|
||||||
|
|
||||||
|
// Показывать подпись
|
||||||
|
public var text:Boolean;
|
||||||
|
|
||||||
|
// Цвет подписи
|
||||||
|
public var textColor:RGB = new RGB(0xFFFFFF);
|
||||||
|
|
||||||
|
// Показывать связь с родителем
|
||||||
|
public var link:Boolean;
|
||||||
|
|
||||||
|
// Показывать тело объекта
|
||||||
|
public var body:Boolean;
|
||||||
|
|
||||||
|
// Показывать вспомогательную графику объекта
|
||||||
|
public var gizmo:Boolean;
|
||||||
|
|
||||||
|
// Цвет тела объекта
|
||||||
|
public var bodyColor:RGB = new RGB(0xCCCCCC);
|
||||||
|
|
||||||
|
|
||||||
|
public function HelperMaterial(text:Boolean = true, link:Boolean = true, gizmo:Boolean = true, body:Boolean = true) {
|
||||||
|
this.text = text;
|
||||||
|
this.link = link;
|
||||||
|
this.gizmo = gizmo;
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:HelperMaterial = new HelperMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:HelperMaterial = HelperMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.text = text;
|
||||||
|
mat.textColor = textColor.clone();
|
||||||
|
mat.body = body;
|
||||||
|
mat.gizmo = gizmo;
|
||||||
|
mat.bodyColor = bodyColor.clone();
|
||||||
|
mat.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import flash.geom.Point;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
|
||||||
|
public final class Hit {
|
||||||
|
|
||||||
|
static public function ngon(n:uint, radiusX:Number, radiusY:Number = -1, offsetX:Number = 0, offsetY:Number = 0, angle:Number = 0):Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
n = (n < 3) ? 3 : n;
|
||||||
|
radiusY = (radiusY < 0) ? radiusX : radiusY;
|
||||||
|
angle = Math3D.toRadian(angle);
|
||||||
|
var sin:Number = Math.sin(angle);
|
||||||
|
var cos:Number = Math.cos(angle);
|
||||||
|
|
||||||
|
var a:Number = (Math.PI+Math.PI) / n;
|
||||||
|
for (var i:uint = 0; i < n; i++) {
|
||||||
|
var x:Number = offsetX + Math.sin(a*i)*radiusX;
|
||||||
|
var y:Number = offsetY - Math.cos(a*i)*radiusY;
|
||||||
|
|
||||||
|
var cx:Number = x*cos - y*sin;
|
||||||
|
var cy:Number = y*cos + x*sin;
|
||||||
|
|
||||||
|
res.push(new Point(cx, cy));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function rectangle(width:Number, height:Number, offsetX:Number = 0, offsetY:Number = 0):Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
var hw:Number = width/2;
|
||||||
|
var hh:Number = height/2;
|
||||||
|
res.push(new Point(offsetX - hw, offsetY - hh));
|
||||||
|
res.push(new Point(offsetX + hw, offsetY - hh));
|
||||||
|
res.push(new Point(offsetX + hw, offsetY + hh));
|
||||||
|
res.push(new Point(offsetX - hw, offsetY + hh));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
|
||||||
|
public class Material {
|
||||||
|
|
||||||
|
// Прозрачность материала
|
||||||
|
public var alpha:Number = 1;
|
||||||
|
|
||||||
|
// Метод наложения
|
||||||
|
public var blendMode:String = "normal";
|
||||||
|
|
||||||
|
// Смещение глубины
|
||||||
|
public var depthOffset:Number = 0;
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
public function clone():Material {
|
||||||
|
var res:Material = new Material();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
protected function cloneParams(material:*):void {
|
||||||
|
var mat:Material = Material(material);
|
||||||
|
mat.alpha = alpha;
|
||||||
|
mat.blendMode = blendMode;
|
||||||
|
mat.depthOffset = depthOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
public class ObjectMaterial extends Material {
|
||||||
|
|
||||||
|
// Массив точек хит-области
|
||||||
|
public var hit:Array = new Array();
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:ObjectMaterial = new ObjectMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:ObjectMaterial = ObjectMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.hit = hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
public class PolygonMaterial extends Material {
|
||||||
|
|
||||||
|
// Двусторонний материал
|
||||||
|
public var twoSided:Boolean;
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:PolygonMaterial = new PolygonMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:PolygonMaterial = PolygonMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import flash.geom.Point;
|
||||||
|
|
||||||
|
public class SpriteMaterial extends ObjectMaterial {
|
||||||
|
|
||||||
|
// Массив фаз
|
||||||
|
private var states:Array = new Array();
|
||||||
|
|
||||||
|
// Сглаженность
|
||||||
|
public var smoothing:Boolean;
|
||||||
|
|
||||||
|
// Цвет самосвечения материала
|
||||||
|
public var selfIllumination:RGB = new RGB();
|
||||||
|
|
||||||
|
// Флаги искажения спрайта
|
||||||
|
public var scale:Boolean;
|
||||||
|
public var rotate:Boolean;
|
||||||
|
|
||||||
|
public function SpriteMaterial(smoothing:Boolean = false, scale:Boolean = false, rotate:Boolean = false) {
|
||||||
|
this.smoothing = smoothing;
|
||||||
|
this.scale = scale;
|
||||||
|
this.rotate = rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPhase(bitmapData:BitmapData, pivot:Point = null, state:String = "default", pitch:Number = 0, yaw:Number = 0):void {
|
||||||
|
|
||||||
|
// Добавляем состояние, если надо
|
||||||
|
if (states[state] == undefined) {
|
||||||
|
states[state] = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
states[state].push(new SpritePhase(bitmapData, pivot, pitch, yaw));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращает фазу
|
||||||
|
public function getPhase(state:String = "default", pitch:Number = 0, yaw:Number = 0):SpritePhase {
|
||||||
|
var res:SpritePhase = null;
|
||||||
|
|
||||||
|
// Проверка на наличие состояние
|
||||||
|
if (states[state] != undefined) {
|
||||||
|
var phases:Array = states[state];
|
||||||
|
var num:uint = phases.length;
|
||||||
|
|
||||||
|
var i:uint;
|
||||||
|
var phase:SpritePhase;
|
||||||
|
var resPitch:Number;
|
||||||
|
var currentDiff:Number;
|
||||||
|
|
||||||
|
// Находим ближайший pitch
|
||||||
|
var minDiff:Number = Number.MAX_VALUE;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
phase = phases[i];
|
||||||
|
currentDiff = Math.abs(phase.pitch - pitch);
|
||||||
|
if (currentDiff < minDiff) {
|
||||||
|
minDiff = currentDiff;
|
||||||
|
resPitch = phase.pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Находим ближайший yaw и сохраняем результат
|
||||||
|
minDiff = Number.MAX_VALUE;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
phase = phases[i];
|
||||||
|
if (phase.pitch == resPitch) {
|
||||||
|
currentDiff = Math.abs(Math3D.deltaAngle(phase.yaw, yaw));
|
||||||
|
if (currentDiff < minDiff) {
|
||||||
|
minDiff = currentDiff;
|
||||||
|
res = phase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:SpriteMaterial = new SpriteMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:SpriteMaterial = SpriteMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.smoothing = smoothing;
|
||||||
|
mat.selfIllumination = selfIllumination.clone();
|
||||||
|
mat.scale = scale;
|
||||||
|
mat.rotate = rotate;
|
||||||
|
for (var state:String in states) {
|
||||||
|
for (var i:uint = 0; i < states[state].length; i++) {
|
||||||
|
var phase:SpritePhase = states[state][i];
|
||||||
|
mat.setPhase(phase.bitmapData, phase.pivot.clone(), state, phase.pitch, phase.yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import flash.geom.Point;
|
||||||
|
import com.alternativagame.engine3d.Matrix3D;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
|
||||||
|
public class SpritePhase {
|
||||||
|
|
||||||
|
// Битмапа фазы
|
||||||
|
public var bitmapData:BitmapData;
|
||||||
|
|
||||||
|
// Точка привязки битмапы
|
||||||
|
private var _pivot:Point;
|
||||||
|
|
||||||
|
private var _transform:Matrix3D;
|
||||||
|
|
||||||
|
private var _pitch:Number;
|
||||||
|
private var _yaw:Number;
|
||||||
|
|
||||||
|
public function SpritePhase(bitmapData:BitmapData, pivot:Point, pitch:Number, yaw:Number) {
|
||||||
|
this.bitmapData = bitmapData;
|
||||||
|
_pivot = (pivot == null) ? new Point(bitmapData.width / 2, bitmapData.height / 2) : pivot;
|
||||||
|
|
||||||
|
// Проверка углов
|
||||||
|
pitch = Math3D.limitAngle(pitch);
|
||||||
|
if (pitch < 0) {
|
||||||
|
if (pitch < -90) {
|
||||||
|
pitch = -180 - pitch;
|
||||||
|
yaw += 180;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pitch > 90) {
|
||||||
|
pitch = 180 - pitch;
|
||||||
|
yaw += 180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yaw = Math3D.limitAngle(yaw);
|
||||||
|
|
||||||
|
// Сохраняем углы
|
||||||
|
_pitch = pitch;
|
||||||
|
_yaw = yaw;
|
||||||
|
|
||||||
|
// Формируем матрицу трансформации фазы
|
||||||
|
_transform = new Matrix3D();
|
||||||
|
Math3D.translateMatrix(_transform, -_pivot.x, 0, _pivot.y);
|
||||||
|
|
||||||
|
Math3D.rotateXMatrix(_transform, -_pitch);
|
||||||
|
Math3D.rotateZMatrix(_transform, -_yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get transform():Matrix3D {
|
||||||
|
return _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pitch():Number {
|
||||||
|
return _pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get yaw():Number {
|
||||||
|
return _yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get pivot():Point {
|
||||||
|
return _pivot;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
|
||||||
|
public final class TextureMaterial extends FillMaterial {
|
||||||
|
|
||||||
|
// Текстура
|
||||||
|
public var texture:BitmapData = null;
|
||||||
|
|
||||||
|
// Сглаженность
|
||||||
|
public var smoothing:Boolean;
|
||||||
|
|
||||||
|
public function TextureMaterial(texture:BitmapData = null, smoothing:Boolean = true, color:RGB = null, twoSided:Boolean = false) {
|
||||||
|
super(color, twoSided);
|
||||||
|
this.texture = texture;
|
||||||
|
this.smoothing = smoothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:TextureMaterial = new TextureMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:TextureMaterial = TextureMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.texture = texture;
|
||||||
|
mat.smoothing = smoothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.alternativagame.engine3d.material {
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
|
||||||
|
public class WireMaterial extends PolygonMaterial {
|
||||||
|
|
||||||
|
// Цвет рёбер
|
||||||
|
public var color:RGB;
|
||||||
|
|
||||||
|
// Толщина рёбер
|
||||||
|
public var thickness:Number;
|
||||||
|
|
||||||
|
public function WireMaterial(color:RGB = null, thickness:Number = 1, twoSided:Boolean = false) {
|
||||||
|
this.color = (color == null) ? new RGB(0xFFFFFF) : color;
|
||||||
|
this.thickness = thickness;
|
||||||
|
this.twoSided = twoSided;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Material {
|
||||||
|
var res:WireMaterial = new WireMaterial();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(material:*):void {
|
||||||
|
var mat:WireMaterial = WireMaterial(material);
|
||||||
|
super.cloneParams(mat);
|
||||||
|
mat.color = color.clone();
|
||||||
|
mat.thickness = thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 107
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object
|
||||||
|
END
|
||||||
|
HelperObject3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 125
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/HelperObject3D.as
|
||||||
|
END
|
||||||
|
Object3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 119
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/Object3D.as
|
||||||
|
END
|
||||||
|
Sprite3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 119
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/Sprite3D.as
|
||||||
|
END
|
||||||
|
Dummy3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 118
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/Dummy3D.as
|
||||||
|
END
|
||||||
|
SkinObject3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 123
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/SkinObject3D.as
|
||||||
|
END
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
HelperObject3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
0d1f419a8b4b72a77ad2a1beb154eb21
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Object3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
c1a4c2771383a746c1c06e687cc73348
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Sprite3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
3f959db2e81fb19804d87d5d62ca78a5
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Dummy3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
0f11ca7a5b7013cc8e9b9cf4a79f3a24
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
SkinObject3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
c1420538a40cfd6a2f6f10767522b574
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
light
|
||||||
|
dir
|
||||||
|
|
||||||
|
mesh
|
||||||
|
dir
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.skin.DummySkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
|
||||||
|
public class Dummy3D extends HelperObject3D {
|
||||||
|
|
||||||
|
public function Dummy3D(material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new DummySkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Dummy3D = new Dummy3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
|
||||||
|
public class HelperObject3D extends SkinObject3D {
|
||||||
|
|
||||||
|
public function HelperObject3D(material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set name(value:String):void {
|
||||||
|
super.name = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:HelperObject3D = new HelperObject3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.Matrix3D;
|
||||||
|
import com.alternativagame.engine3d.View3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.light.Light3D;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.events.EventDispatcher;
|
||||||
|
import flash.geom.Matrix;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Object3D extends EventDispatcher {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Название
|
||||||
|
private var _name:String;
|
||||||
|
|
||||||
|
// Инкремент количества объектов
|
||||||
|
private static var num:uint = 0;
|
||||||
|
|
||||||
|
// Флаг сплошного объекта
|
||||||
|
private var _solid:Boolean = false;
|
||||||
|
|
||||||
|
// Все объекты внутри солида
|
||||||
|
engine3d var solidObjects:Set;
|
||||||
|
|
||||||
|
// Все источники света внутри солида
|
||||||
|
engine3d var solidLights:Set;
|
||||||
|
|
||||||
|
// Вершина солида
|
||||||
|
engine3d var solidParent:Object3D;
|
||||||
|
|
||||||
|
// Ссылка на родителя
|
||||||
|
engine3d var parent:Object3D = null;
|
||||||
|
|
||||||
|
// Ссылка на камеру
|
||||||
|
engine3d var view:View3D = null;
|
||||||
|
|
||||||
|
// Флаг интерактивности
|
||||||
|
private var _interactive:Boolean = false;
|
||||||
|
|
||||||
|
// Смещение объекта относительно родителя
|
||||||
|
private var _x:Number = 0;
|
||||||
|
private var _y:Number = 0;
|
||||||
|
private var _z:Number = 0;
|
||||||
|
|
||||||
|
// Поворот объекта относительно родителя
|
||||||
|
private var _rotX:Number = 0;
|
||||||
|
private var _rotY:Number = 0;
|
||||||
|
private var _rotZ:Number = 0;
|
||||||
|
|
||||||
|
// Мастшаб объекта относительно родителя
|
||||||
|
private var _scaleX:Number = 1;
|
||||||
|
private var _scaleY:Number = 1;
|
||||||
|
private var _scaleZ:Number = 1;
|
||||||
|
|
||||||
|
// Списки дочерних объектов
|
||||||
|
private var _objects:Set;
|
||||||
|
|
||||||
|
// Глобальная трансформация
|
||||||
|
engine3d var transform:Matrix3D;
|
||||||
|
|
||||||
|
// Изменилась позиция объекта
|
||||||
|
engine3d var positionChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменилась геометрия объекта (поворот, масштаб, параметры)
|
||||||
|
engine3d var geometryChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменилось освещение объекта
|
||||||
|
engine3d var lightChanged:Set = new Set();
|
||||||
|
|
||||||
|
public function Object3D() {
|
||||||
|
_objects = new Set();
|
||||||
|
|
||||||
|
transform = new Matrix3D();
|
||||||
|
|
||||||
|
solidObjects = new Set();
|
||||||
|
solidLights = new Set();
|
||||||
|
|
||||||
|
solidParent = this;
|
||||||
|
solidObjects.add(this);
|
||||||
|
|
||||||
|
num++;
|
||||||
|
_name = "Object" + num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать трансформацию объекта и его детей
|
||||||
|
engine3d function calculateTransform():void {
|
||||||
|
if (geometryChanged || positionChanged) { // Если позиция или геометрия изменилась
|
||||||
|
var topTransform:Matrix3D = (this === view.object) ? view.transformation : parent.transform;
|
||||||
|
// Если изменилась геометрия - Пересчитать трансформацию
|
||||||
|
if (geometryChanged) {
|
||||||
|
transform = Math3D.combineMatrix(topTransform, new Matrix3D(x, y, z, rotX, rotY, rotZ, scaleX, scaleY, scaleZ));
|
||||||
|
// Если изменилась только позиция - Скорректировать трансформацию
|
||||||
|
} else {
|
||||||
|
transform.d = topTransform.a*x + topTransform.b*y + topTransform.c*z + topTransform.d;
|
||||||
|
transform.h = topTransform.e*x + topTransform.f*y + topTransform.g*z + topTransform.h;
|
||||||
|
transform.l = topTransform.i*x + topTransform.j*y + topTransform.k*z + topTransform.l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновить скины
|
||||||
|
updateTransform();
|
||||||
|
|
||||||
|
// Сбрасываем флаги изменений
|
||||||
|
positionChanged = false;
|
||||||
|
geometryChanged = false;
|
||||||
|
}
|
||||||
|
// Расчитать трансформацию у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.calculateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать освещение объекта и его детей
|
||||||
|
engine3d function calculateLight():void {
|
||||||
|
|
||||||
|
// Обновить освещение
|
||||||
|
updateLight();
|
||||||
|
|
||||||
|
// Удалить источники света
|
||||||
|
clearLightChanged();
|
||||||
|
|
||||||
|
// Расчитать освещение у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.calculateLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
protected function updateTransform():void {}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
protected function updateLight():void {}
|
||||||
|
|
||||||
|
// Добавить дочерний объект
|
||||||
|
public function attach(object:Object3D):void {
|
||||||
|
// Если объект был в другом объекте
|
||||||
|
if (object.parent != null) {
|
||||||
|
// Удалить его оттуда
|
||||||
|
object.parent.detach(object);
|
||||||
|
}
|
||||||
|
// Добавляем в список
|
||||||
|
objects.add(object);
|
||||||
|
// Указываем себя как родителя
|
||||||
|
object.setParent(this);
|
||||||
|
// Указываем камеру
|
||||||
|
object.setView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить дочерний объект
|
||||||
|
public function detach(object:Object3D):void {
|
||||||
|
// Проверяем, есть ли у нас этот объект
|
||||||
|
if (objects.has(object)) {
|
||||||
|
// Убираем из списка
|
||||||
|
objects.remove(object);
|
||||||
|
// Удаляем ссылку на родителя
|
||||||
|
object.setParent(null);
|
||||||
|
// Удаляем ссылку на камеру
|
||||||
|
object.setView(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить дочерний объект по имени
|
||||||
|
public function getObjectByName(name:String):Object3D {
|
||||||
|
var res:Object3D = null;
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
if (object.name == name) {
|
||||||
|
res = object;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить освещение
|
||||||
|
protected function updateLightChanged():void {
|
||||||
|
// Собрать все источники внутри солида
|
||||||
|
for each (var light:Light3D in solidParent.solidLights) {
|
||||||
|
addLightChanged(light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set name(value:String):void {
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get name():String {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get x():Number {
|
||||||
|
return _x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get y():Number {
|
||||||
|
return _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get z():Number {
|
||||||
|
return _z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotX():Number {
|
||||||
|
return _rotX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotY():Number {
|
||||||
|
return _rotY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotZ():Number {
|
||||||
|
return _rotZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleX():Number {
|
||||||
|
return _scaleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleY():Number {
|
||||||
|
return _scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleZ():Number {
|
||||||
|
return _scaleZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set x(value:Number):void {
|
||||||
|
_x = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set y(value:Number):void {
|
||||||
|
_y = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set z(value:Number):void {
|
||||||
|
_z = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotX(value:Number):void {
|
||||||
|
_rotX = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotY(value:Number):void {
|
||||||
|
_rotY = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotZ(value:Number):void {
|
||||||
|
_rotZ = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleX(value:Number):void {
|
||||||
|
_scaleX = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleY(value:Number):void {
|
||||||
|
_scaleY = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleZ(value:Number):void {
|
||||||
|
_scaleZ = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get objects():Set {
|
||||||
|
return _objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set solid(value:Boolean):void {
|
||||||
|
// Сохранить солид
|
||||||
|
_solid = value;
|
||||||
|
|
||||||
|
var childSolid:Object3D;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
// Если меня установили солидом, то разослать детям себя
|
||||||
|
childSolid = this;
|
||||||
|
} else {
|
||||||
|
// Если я теперь не солид, то разослать детям своего солидПарента
|
||||||
|
childSolid = solidParent;
|
||||||
|
}
|
||||||
|
// Рассылаем детям нового солидПарента
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setSolidParent(childSolid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать свет
|
||||||
|
clearLightChanged();
|
||||||
|
updateLightChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get solid():Boolean {
|
||||||
|
return _solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
|
||||||
|
// Забрали себя от старого solidParent
|
||||||
|
solidParent.solidObjects.remove(this);
|
||||||
|
|
||||||
|
// Добавили себя к новому solidParent
|
||||||
|
value.solidObjects.add(this);
|
||||||
|
|
||||||
|
// Если я не солид - установить этот солидПарент у дочерних объектов
|
||||||
|
if (!solid) {
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setSolidParent(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
solidParent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установка новой камеры для объекта
|
||||||
|
engine3d function setView(value:View3D):void {
|
||||||
|
view = value;
|
||||||
|
// При снятии камеры сбросить флаги и очистить источники
|
||||||
|
if (value == null) {
|
||||||
|
geometryChanged = false;
|
||||||
|
positionChanged = false;
|
||||||
|
clearLightChanged();
|
||||||
|
// При назначении камеры установить флаги изменения и проверить свет
|
||||||
|
} else {
|
||||||
|
geometryChanged = true;
|
||||||
|
positionChanged = true;
|
||||||
|
updateLightChanged();
|
||||||
|
}
|
||||||
|
// Установить эту камеру у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setView(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setParent(value:Object3D):void {
|
||||||
|
// Если отцепили, то сам себе солидПарент
|
||||||
|
if (value == null) {
|
||||||
|
setSolidParent(this);
|
||||||
|
// Взять парентСолид у парента
|
||||||
|
} else {
|
||||||
|
setSolidParent(value.solid ? value : value.solidParent);
|
||||||
|
}
|
||||||
|
parent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаги геометрии
|
||||||
|
engine3d function setGeometryChanged():void {
|
||||||
|
if (!geometryChanged) {
|
||||||
|
updateLightChanged();
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setGeometryChanged();
|
||||||
|
}
|
||||||
|
geometryChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаги позиции
|
||||||
|
engine3d function setPositionChanged():void {
|
||||||
|
if (!positionChanged) {
|
||||||
|
updateLightChanged();
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setPositionChanged();
|
||||||
|
}
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить источник света
|
||||||
|
engine3d function addLightChanged(value:Light3D):void {
|
||||||
|
lightChanged.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Убрать источники света
|
||||||
|
engine3d function clearLightChanged():void {
|
||||||
|
lightChanged = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаг интерактивности
|
||||||
|
public function set interactive(value:Boolean):void {
|
||||||
|
_interactive = value;
|
||||||
|
}
|
||||||
|
public function get interactive():Boolean {
|
||||||
|
return _interactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Координаты объекта в системе координат камеры
|
||||||
|
engine3d function get canvasCoords():Vector {
|
||||||
|
return (view != null) ? new Vector(transform.d, transform.h, transform.l) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
public function clone():Object3D {
|
||||||
|
var res:Object3D = new Object3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
protected function cloneParams(object:*):void {
|
||||||
|
var obj:Object3D = Object3D(object);
|
||||||
|
obj.x = x;
|
||||||
|
obj.y = y;
|
||||||
|
obj.z = z;
|
||||||
|
obj.rotX = rotX;
|
||||||
|
obj.rotY = rotY;
|
||||||
|
obj.rotZ = rotZ;
|
||||||
|
obj.scaleX = scaleX;
|
||||||
|
obj.scaleY = scaleY;
|
||||||
|
obj.scaleZ = scaleZ;
|
||||||
|
obj.solid = solid;
|
||||||
|
obj.name = name;
|
||||||
|
obj.interactive = interactive;
|
||||||
|
for each (var child:Object3D in objects) {
|
||||||
|
obj.attach(child.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить ветку объектов от текущего до корневого
|
||||||
|
engine3d function getBranch():Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
var object:Object3D = this;
|
||||||
|
while (object != null) {
|
||||||
|
res.push(object);
|
||||||
|
object = object.parent;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить локальные координаты внутри объекта из координат камеры
|
||||||
|
engine3d function canvasToLocal(coords:Vector):Vector {
|
||||||
|
var res:Vector = null;
|
||||||
|
if (view != null) {
|
||||||
|
// Формируем ветку объектов
|
||||||
|
var objectList:Array = getBranch();
|
||||||
|
|
||||||
|
// Перевести точку в мировые координаты
|
||||||
|
res = Math3D.vectorTransform(coords, view.inverseTransformation);
|
||||||
|
|
||||||
|
var object:Object3D;
|
||||||
|
var objectMatrix:Matrix3D;
|
||||||
|
|
||||||
|
// Перебираем список объектов с конца (с корневого объекта)
|
||||||
|
var i:int;
|
||||||
|
for (i = objectList.length - 1; i >= 0; i--) {
|
||||||
|
object = objectList[i];
|
||||||
|
// Трансформируем точку через матрицу в локальные координаты текущего объекта
|
||||||
|
res = Math3D.vectorTransform(res, object.inverseTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт обратной локальной трансформации текущего объекта
|
||||||
|
engine3d function get inverseTransform():Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
Math3D.translateMatrix(res, -_x, -_y, -_z);
|
||||||
|
Math3D.rotateZMatrix(res, -_rotZ);
|
||||||
|
Math3D.rotateYMatrix(res, -_rotY);
|
||||||
|
Math3D.rotateXMatrix(res, -_rotX);
|
||||||
|
Math3D.scaleMatrix(res, 1/_scaleX, 1/_scaleY, 1/_scaleZ);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.View3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.object.light.Light3D;
|
||||||
|
import com.alternativagame.engine3d.skin.DummySkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class SkinObject3D extends Object3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Отображение объекта в камере
|
||||||
|
protected var skin:Skin = null;
|
||||||
|
private var _material:Material;
|
||||||
|
|
||||||
|
// Список цветов источников с учетом силы
|
||||||
|
private var lights:Dictionary;
|
||||||
|
|
||||||
|
// Текущее освещение
|
||||||
|
private var _lightColor:RGB = null;
|
||||||
|
|
||||||
|
// Нормаль всех скин-объектов
|
||||||
|
static private var normal:Vector = new Vector(0, -1, 0);
|
||||||
|
|
||||||
|
public function SkinObject3D(material:Material = null) {
|
||||||
|
super();
|
||||||
|
this.material = material;
|
||||||
|
lights = new Dictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
// Обновить глубину скина и добавить его в список сортировки
|
||||||
|
if (skin != null) {
|
||||||
|
skin.depth = transform.h;
|
||||||
|
view.addToDepth(skin);
|
||||||
|
|
||||||
|
// Если изменилась геометрия
|
||||||
|
if (geometryChanged) {
|
||||||
|
view.addToDraw(skin);
|
||||||
|
} else {
|
||||||
|
if (positionChanged) {
|
||||||
|
// Если изменилась позиция
|
||||||
|
view.addToPosition(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
override protected function updateLight():void {
|
||||||
|
// Флаг на добавление в список освещения
|
||||||
|
var toLight:Boolean = false;
|
||||||
|
|
||||||
|
// Если есть источники на пересчёт, обновляем список
|
||||||
|
if (lightChanged.length > 0) {
|
||||||
|
|
||||||
|
var color:RGB;
|
||||||
|
|
||||||
|
for each (var light:Light3D in lightChanged) {
|
||||||
|
// Расчот производим, только если в одной солид-группе
|
||||||
|
if (light.solidParent == solidParent) {
|
||||||
|
// Мои координаты
|
||||||
|
var coords:Vector = new Vector(transform.d, transform.h, transform.l);
|
||||||
|
|
||||||
|
// Получаем освещение от источника
|
||||||
|
color = light.getLightColor(coords, normal);
|
||||||
|
|
||||||
|
if (color == null) {
|
||||||
|
delete lights[light];
|
||||||
|
} else {
|
||||||
|
lights[light] = color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete lights[light];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт общего света
|
||||||
|
var newLightColor:RGB = new RGB();
|
||||||
|
for each (color in lights) {
|
||||||
|
newLightColor.add(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если свет новый, добавляем на освещение
|
||||||
|
if (lightColor == null || !newLightColor.equals(lightColor)) {
|
||||||
|
_lightColor = newLightColor;
|
||||||
|
toLight = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Если освещения ещё не было, установить по умолчанию и добавить на освещение
|
||||||
|
if (lightColor == null) {
|
||||||
|
_lightColor = new RGB();
|
||||||
|
toLight = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Если добавляем на освещение, есть скин и камера, то отправляем на освещение в камеру
|
||||||
|
if (toLight && skin != null && view != null) {
|
||||||
|
view.addToLight(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setView(value:View3D):void {
|
||||||
|
if (value == null) {
|
||||||
|
if (skin != null) {
|
||||||
|
view.removeSkin(skin);
|
||||||
|
_lightColor = null;
|
||||||
|
skin = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (material != null) {
|
||||||
|
skin = createSkin();
|
||||||
|
if (skin != null) value.addSkin(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setView(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createSkin():Skin {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление скина при смене каких-либо параметров объекта
|
||||||
|
protected function updateSkin():void {
|
||||||
|
if (view != null && skin != null) {
|
||||||
|
view.addToDraw(skin);
|
||||||
|
view.addToLight(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get lightColor():RGB {
|
||||||
|
return _lightColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установить новый материал
|
||||||
|
public function set material(value:Material):void {
|
||||||
|
// Если объект в камере
|
||||||
|
if (view != null) {
|
||||||
|
// Устанавливаем материал
|
||||||
|
if (value != null) {
|
||||||
|
if (skin == null) {
|
||||||
|
skin = createSkin();
|
||||||
|
if (skin != null) view.addSkin(skin);
|
||||||
|
}
|
||||||
|
// Обновляем скин
|
||||||
|
updateSkin();
|
||||||
|
// Сбрасываем материал
|
||||||
|
} else {
|
||||||
|
if (skin != null) {
|
||||||
|
view.removeSkin(skin);
|
||||||
|
skin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Сохраняем значение материала
|
||||||
|
_material = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get material():Material {
|
||||||
|
return _material;
|
||||||
|
}
|
||||||
|
|
||||||
|
// При смене параметров обновляем скин
|
||||||
|
override public function set solid(value:Boolean):void {
|
||||||
|
super.solid = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
super.setSolidParent(value);
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setParent(value:Object3D):void {
|
||||||
|
super.setParent(value);
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set name(value:String):void {
|
||||||
|
super.name = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:SkinObject3D = new SkinObject3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:SkinObject3D = SkinObject3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.material.SpriteMaterial;
|
||||||
|
import com.alternativagame.engine3d.skin.SpriteSkin;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
|
||||||
|
public class Sprite3D extends SkinObject3D {
|
||||||
|
|
||||||
|
private var _state:String = "default";
|
||||||
|
|
||||||
|
public function Sprite3D(material:SpriteMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new SpriteSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set state(value:String):void {
|
||||||
|
if (_state != value) {
|
||||||
|
_state = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get state():String {
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Sprite3D = new Sprite3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Sprite3D = Sprite3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.skin.DummySkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
|
||||||
|
public class Dummy3D extends HelperObject3D {
|
||||||
|
|
||||||
|
public function Dummy3D(material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new DummySkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Dummy3D = new Dummy3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
|
||||||
|
public class HelperObject3D extends SkinObject3D {
|
||||||
|
|
||||||
|
public function HelperObject3D(material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set name(value:String):void {
|
||||||
|
super.name = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:HelperObject3D = new HelperObject3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.Matrix3D;
|
||||||
|
import com.alternativagame.engine3d.View3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.light.Light3D;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.events.EventDispatcher;
|
||||||
|
import flash.geom.Matrix;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Object3D extends EventDispatcher {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Название
|
||||||
|
private var _name:String;
|
||||||
|
|
||||||
|
// Инкремент количества объектов
|
||||||
|
private static var num:uint = 0;
|
||||||
|
|
||||||
|
// Флаг сплошного объекта
|
||||||
|
private var _solid:Boolean = false;
|
||||||
|
|
||||||
|
// Все объекты внутри солида
|
||||||
|
engine3d var solidObjects:Set;
|
||||||
|
|
||||||
|
// Все источники света внутри солида
|
||||||
|
engine3d var solidLights:Set;
|
||||||
|
|
||||||
|
// Вершина солида
|
||||||
|
engine3d var solidParent:Object3D;
|
||||||
|
|
||||||
|
// Ссылка на родителя
|
||||||
|
engine3d var parent:Object3D = null;
|
||||||
|
|
||||||
|
// Ссылка на камеру
|
||||||
|
engine3d var view:View3D = null;
|
||||||
|
|
||||||
|
// Флаг интерактивности
|
||||||
|
private var _interactive:Boolean = false;
|
||||||
|
|
||||||
|
// Смещение объекта относительно родителя
|
||||||
|
private var _x:Number = 0;
|
||||||
|
private var _y:Number = 0;
|
||||||
|
private var _z:Number = 0;
|
||||||
|
|
||||||
|
// Поворот объекта относительно родителя
|
||||||
|
private var _rotX:Number = 0;
|
||||||
|
private var _rotY:Number = 0;
|
||||||
|
private var _rotZ:Number = 0;
|
||||||
|
|
||||||
|
// Мастшаб объекта относительно родителя
|
||||||
|
private var _scaleX:Number = 1;
|
||||||
|
private var _scaleY:Number = 1;
|
||||||
|
private var _scaleZ:Number = 1;
|
||||||
|
|
||||||
|
// Списки дочерних объектов
|
||||||
|
private var _objects:Set;
|
||||||
|
|
||||||
|
// Глобальная трансформация
|
||||||
|
engine3d var transform:Matrix3D;
|
||||||
|
|
||||||
|
// Изменилась позиция объекта
|
||||||
|
engine3d var positionChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменилась геометрия объекта (поворот, масштаб, параметры)
|
||||||
|
engine3d var geometryChanged:Boolean = true;
|
||||||
|
|
||||||
|
// Изменилось освещение объекта
|
||||||
|
engine3d var lightChanged:Set = new Set();
|
||||||
|
|
||||||
|
public function Object3D() {
|
||||||
|
_objects = new Set();
|
||||||
|
|
||||||
|
transform = new Matrix3D();
|
||||||
|
|
||||||
|
solidObjects = new Set();
|
||||||
|
solidLights = new Set();
|
||||||
|
|
||||||
|
solidParent = this;
|
||||||
|
solidObjects.add(this);
|
||||||
|
|
||||||
|
num++;
|
||||||
|
_name = "Object" + num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать трансформацию объекта и его детей
|
||||||
|
engine3d function calculateTransform():void {
|
||||||
|
if (geometryChanged || positionChanged) { // Если позиция или геометрия изменилась
|
||||||
|
var topTransform:Matrix3D = (this === view.object) ? view.transformation : parent.transform;
|
||||||
|
// Если изменилась геометрия - Пересчитать трансформацию
|
||||||
|
if (geometryChanged) {
|
||||||
|
transform = Math3D.combineMatrix(topTransform, new Matrix3D(x, y, z, rotX, rotY, rotZ, scaleX, scaleY, scaleZ));
|
||||||
|
// Если изменилась только позиция - Скорректировать трансформацию
|
||||||
|
} else {
|
||||||
|
transform.d = topTransform.a*x + topTransform.b*y + topTransform.c*z + topTransform.d;
|
||||||
|
transform.h = topTransform.e*x + topTransform.f*y + topTransform.g*z + topTransform.h;
|
||||||
|
transform.l = topTransform.i*x + topTransform.j*y + topTransform.k*z + topTransform.l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновить скины
|
||||||
|
updateTransform();
|
||||||
|
|
||||||
|
// Сбрасываем флаги изменений
|
||||||
|
positionChanged = false;
|
||||||
|
geometryChanged = false;
|
||||||
|
}
|
||||||
|
// Расчитать трансформацию у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.calculateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать освещение объекта и его детей
|
||||||
|
engine3d function calculateLight():void {
|
||||||
|
|
||||||
|
// Обновить освещение
|
||||||
|
updateLight();
|
||||||
|
|
||||||
|
// Удалить источники света
|
||||||
|
clearLightChanged();
|
||||||
|
|
||||||
|
// Расчитать освещение у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.calculateLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
protected function updateTransform():void {}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
protected function updateLight():void {}
|
||||||
|
|
||||||
|
// Добавить дочерний объект
|
||||||
|
public function attach(object:Object3D):void {
|
||||||
|
// Если объект был в другом объекте
|
||||||
|
if (object.parent != null) {
|
||||||
|
// Удалить его оттуда
|
||||||
|
object.parent.detach(object);
|
||||||
|
}
|
||||||
|
// Добавляем в список
|
||||||
|
objects.add(object);
|
||||||
|
// Указываем себя как родителя
|
||||||
|
object.setParent(this);
|
||||||
|
// Указываем камеру
|
||||||
|
object.setView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить дочерний объект
|
||||||
|
public function detach(object:Object3D):void {
|
||||||
|
// Проверяем, есть ли у нас этот объект
|
||||||
|
if (objects.has(object)) {
|
||||||
|
// Убираем из списка
|
||||||
|
objects.remove(object);
|
||||||
|
// Удаляем ссылку на родителя
|
||||||
|
object.setParent(null);
|
||||||
|
// Удаляем ссылку на камеру
|
||||||
|
object.setView(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить дочерний объект по имени
|
||||||
|
public function getObjectByName(name:String):Object3D {
|
||||||
|
var res:Object3D = null;
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
if (object.name == name) {
|
||||||
|
res = object;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить освещение
|
||||||
|
protected function updateLightChanged():void {
|
||||||
|
// Собрать все источники внутри солида
|
||||||
|
for each (var light:Light3D in solidParent.solidLights) {
|
||||||
|
addLightChanged(light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set name(value:String):void {
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get name():String {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get x():Number {
|
||||||
|
return _x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get y():Number {
|
||||||
|
return _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get z():Number {
|
||||||
|
return _z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotX():Number {
|
||||||
|
return _rotX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotY():Number {
|
||||||
|
return _rotY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get rotZ():Number {
|
||||||
|
return _rotZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleX():Number {
|
||||||
|
return _scaleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleY():Number {
|
||||||
|
return _scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get scaleZ():Number {
|
||||||
|
return _scaleZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set x(value:Number):void {
|
||||||
|
_x = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set y(value:Number):void {
|
||||||
|
_y = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set z(value:Number):void {
|
||||||
|
_z = value;
|
||||||
|
setPositionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotX(value:Number):void {
|
||||||
|
_rotX = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotY(value:Number):void {
|
||||||
|
_rotY = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set rotZ(value:Number):void {
|
||||||
|
_rotZ = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleX(value:Number):void {
|
||||||
|
_scaleX = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleY(value:Number):void {
|
||||||
|
_scaleY = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set scaleZ(value:Number):void {
|
||||||
|
_scaleZ = value;
|
||||||
|
setGeometryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get objects():Set {
|
||||||
|
return _objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set solid(value:Boolean):void {
|
||||||
|
// Сохранить солид
|
||||||
|
_solid = value;
|
||||||
|
|
||||||
|
var childSolid:Object3D;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
// Если меня установили солидом, то разослать детям себя
|
||||||
|
childSolid = this;
|
||||||
|
} else {
|
||||||
|
// Если я теперь не солид, то разослать детям своего солидПарента
|
||||||
|
childSolid = solidParent;
|
||||||
|
}
|
||||||
|
// Рассылаем детям нового солидПарента
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setSolidParent(childSolid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересчитать свет
|
||||||
|
clearLightChanged();
|
||||||
|
updateLightChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get solid():Boolean {
|
||||||
|
return _solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
|
||||||
|
// Забрали себя от старого solidParent
|
||||||
|
solidParent.solidObjects.remove(this);
|
||||||
|
|
||||||
|
// Добавили себя к новому solidParent
|
||||||
|
value.solidObjects.add(this);
|
||||||
|
|
||||||
|
// Если я не солид - установить этот солидПарент у дочерних объектов
|
||||||
|
if (!solid) {
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setSolidParent(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
solidParent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установка новой камеры для объекта
|
||||||
|
engine3d function setView(value:View3D):void {
|
||||||
|
view = value;
|
||||||
|
// При снятии камеры сбросить флаги и очистить источники
|
||||||
|
if (value == null) {
|
||||||
|
geometryChanged = false;
|
||||||
|
positionChanged = false;
|
||||||
|
clearLightChanged();
|
||||||
|
// При назначении камеры установить флаги изменения и проверить свет
|
||||||
|
} else {
|
||||||
|
geometryChanged = true;
|
||||||
|
positionChanged = true;
|
||||||
|
updateLightChanged();
|
||||||
|
}
|
||||||
|
// Установить эту камеру у дочерних объектов
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setView(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function setParent(value:Object3D):void {
|
||||||
|
// Если отцепили, то сам себе солидПарент
|
||||||
|
if (value == null) {
|
||||||
|
setSolidParent(this);
|
||||||
|
// Взять парентСолид у парента
|
||||||
|
} else {
|
||||||
|
setSolidParent(value.solid ? value : value.solidParent);
|
||||||
|
}
|
||||||
|
parent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаги геометрии
|
||||||
|
engine3d function setGeometryChanged():void {
|
||||||
|
if (!geometryChanged) {
|
||||||
|
updateLightChanged();
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setGeometryChanged();
|
||||||
|
}
|
||||||
|
geometryChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаги позиции
|
||||||
|
engine3d function setPositionChanged():void {
|
||||||
|
if (!positionChanged) {
|
||||||
|
updateLightChanged();
|
||||||
|
for each (var object:Object3D in objects) {
|
||||||
|
object.setPositionChanged();
|
||||||
|
}
|
||||||
|
positionChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить источник света
|
||||||
|
engine3d function addLightChanged(value:Light3D):void {
|
||||||
|
lightChanged.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Убрать источники света
|
||||||
|
engine3d function clearLightChanged():void {
|
||||||
|
lightChanged = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаг интерактивности
|
||||||
|
public function set interactive(value:Boolean):void {
|
||||||
|
_interactive = value;
|
||||||
|
}
|
||||||
|
public function get interactive():Boolean {
|
||||||
|
return _interactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Координаты объекта в системе координат камеры
|
||||||
|
engine3d function get canvasCoords():Vector {
|
||||||
|
return (view != null) ? new Vector(transform.d, transform.h, transform.l) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
public function clone():Object3D {
|
||||||
|
var res:Object3D = new Object3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
protected function cloneParams(object:*):void {
|
||||||
|
var obj:Object3D = Object3D(object);
|
||||||
|
obj.x = x;
|
||||||
|
obj.y = y;
|
||||||
|
obj.z = z;
|
||||||
|
obj.rotX = rotX;
|
||||||
|
obj.rotY = rotY;
|
||||||
|
obj.rotZ = rotZ;
|
||||||
|
obj.scaleX = scaleX;
|
||||||
|
obj.scaleY = scaleY;
|
||||||
|
obj.scaleZ = scaleZ;
|
||||||
|
obj.solid = solid;
|
||||||
|
obj.name = name;
|
||||||
|
obj.interactive = interactive;
|
||||||
|
for each (var child:Object3D in objects) {
|
||||||
|
obj.attach(child.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить ветку объектов от текущего до корневого
|
||||||
|
engine3d function getBranch():Array {
|
||||||
|
var res:Array = new Array();
|
||||||
|
var object:Object3D = this;
|
||||||
|
while (object != null) {
|
||||||
|
res.push(object);
|
||||||
|
object = object.parent;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить локальные координаты внутри объекта из координат камеры
|
||||||
|
engine3d function canvasToLocal(coords:Vector):Vector {
|
||||||
|
var res:Vector = null;
|
||||||
|
if (view != null) {
|
||||||
|
// Формируем ветку объектов
|
||||||
|
var objectList:Array = getBranch();
|
||||||
|
|
||||||
|
// Перевести точку в мировые координаты
|
||||||
|
res = Math3D.vectorTransform(coords, view.inverseTransformation);
|
||||||
|
|
||||||
|
var object:Object3D;
|
||||||
|
var objectMatrix:Matrix3D;
|
||||||
|
|
||||||
|
// Перебираем список объектов с конца (с корневого объекта)
|
||||||
|
var i:int;
|
||||||
|
for (i = objectList.length - 1; i >= 0; i--) {
|
||||||
|
object = objectList[i];
|
||||||
|
// Трансформируем точку через матрицу в локальные координаты текущего объекта
|
||||||
|
res = Math3D.vectorTransform(res, object.inverseTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт обратной локальной трансформации текущего объекта
|
||||||
|
engine3d function get inverseTransform():Matrix3D {
|
||||||
|
var res:Matrix3D = new Matrix3D();
|
||||||
|
Math3D.translateMatrix(res, -_x, -_y, -_z);
|
||||||
|
Math3D.rotateZMatrix(res, -_rotZ);
|
||||||
|
Math3D.rotateYMatrix(res, -_rotY);
|
||||||
|
Math3D.rotateXMatrix(res, -_rotX);
|
||||||
|
Math3D.scaleMatrix(res, 1/_scaleX, 1/_scaleY, 1/_scaleZ);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.View3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.object.light.Light3D;
|
||||||
|
import com.alternativagame.engine3d.skin.DummySkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class SkinObject3D extends Object3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Отображение объекта в камере
|
||||||
|
protected var skin:Skin = null;
|
||||||
|
private var _material:Material;
|
||||||
|
|
||||||
|
// Список цветов источников с учетом силы
|
||||||
|
private var lights:Dictionary;
|
||||||
|
|
||||||
|
// Текущее освещение
|
||||||
|
private var _lightColor:RGB = null;
|
||||||
|
|
||||||
|
// Нормаль всех скин-объектов
|
||||||
|
static private var normal:Vector = new Vector(0, -1, 0);
|
||||||
|
|
||||||
|
public function SkinObject3D(material:Material = null) {
|
||||||
|
super();
|
||||||
|
this.material = material;
|
||||||
|
lights = new Dictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
// Обновить глубину скина и добавить его в список сортировки
|
||||||
|
if (skin != null) {
|
||||||
|
skin.depth = transform.h;
|
||||||
|
view.addToDepth(skin);
|
||||||
|
|
||||||
|
// Если изменилась геометрия
|
||||||
|
if (geometryChanged) {
|
||||||
|
view.addToDraw(skin);
|
||||||
|
} else {
|
||||||
|
if (positionChanged) {
|
||||||
|
// Если изменилась позиция
|
||||||
|
view.addToPosition(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
override protected function updateLight():void {
|
||||||
|
// Флаг на добавление в список освещения
|
||||||
|
var toLight:Boolean = false;
|
||||||
|
|
||||||
|
// Если есть источники на пересчёт, обновляем список
|
||||||
|
if (lightChanged.length > 0) {
|
||||||
|
|
||||||
|
var color:RGB;
|
||||||
|
|
||||||
|
for each (var light:Light3D in lightChanged) {
|
||||||
|
// Расчот производим, только если в одной солид-группе
|
||||||
|
if (light.solidParent == solidParent) {
|
||||||
|
// Мои координаты
|
||||||
|
var coords:Vector = new Vector(transform.d, transform.h, transform.l);
|
||||||
|
|
||||||
|
// Получаем освещение от источника
|
||||||
|
color = light.getLightColor(coords, normal);
|
||||||
|
|
||||||
|
if (color == null) {
|
||||||
|
delete lights[light];
|
||||||
|
} else {
|
||||||
|
lights[light] = color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete lights[light];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт общего света
|
||||||
|
var newLightColor:RGB = new RGB();
|
||||||
|
for each (color in lights) {
|
||||||
|
newLightColor.add(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если свет новый, добавляем на освещение
|
||||||
|
if (lightColor == null || !newLightColor.equals(lightColor)) {
|
||||||
|
_lightColor = newLightColor;
|
||||||
|
toLight = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Если освещения ещё не было, установить по умолчанию и добавить на освещение
|
||||||
|
if (lightColor == null) {
|
||||||
|
_lightColor = new RGB();
|
||||||
|
toLight = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Если добавляем на освещение, есть скин и камера, то отправляем на освещение в камеру
|
||||||
|
if (toLight && skin != null && view != null) {
|
||||||
|
view.addToLight(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setView(value:View3D):void {
|
||||||
|
if (value == null) {
|
||||||
|
if (skin != null) {
|
||||||
|
view.removeSkin(skin);
|
||||||
|
_lightColor = null;
|
||||||
|
skin = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (material != null) {
|
||||||
|
skin = createSkin();
|
||||||
|
if (skin != null) value.addSkin(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setView(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createSkin():Skin {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление скина при смене каких-либо параметров объекта
|
||||||
|
protected function updateSkin():void {
|
||||||
|
if (view != null && skin != null) {
|
||||||
|
view.addToDraw(skin);
|
||||||
|
view.addToLight(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get lightColor():RGB {
|
||||||
|
return _lightColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установить новый материал
|
||||||
|
public function set material(value:Material):void {
|
||||||
|
// Если объект в камере
|
||||||
|
if (view != null) {
|
||||||
|
// Устанавливаем материал
|
||||||
|
if (value != null) {
|
||||||
|
if (skin == null) {
|
||||||
|
skin = createSkin();
|
||||||
|
if (skin != null) view.addSkin(skin);
|
||||||
|
}
|
||||||
|
// Обновляем скин
|
||||||
|
updateSkin();
|
||||||
|
// Сбрасываем материал
|
||||||
|
} else {
|
||||||
|
if (skin != null) {
|
||||||
|
view.removeSkin(skin);
|
||||||
|
skin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Сохраняем значение материала
|
||||||
|
_material = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get material():Material {
|
||||||
|
return _material;
|
||||||
|
}
|
||||||
|
|
||||||
|
// При смене параметров обновляем скин
|
||||||
|
override public function set solid(value:Boolean):void {
|
||||||
|
super.solid = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
super.setSolidParent(value);
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setParent(value:Object3D):void {
|
||||||
|
super.setParent(value);
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function set name(value:String):void {
|
||||||
|
super.name = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:SkinObject3D = new SkinObject3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:SkinObject3D = SkinObject3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.alternativagame.engine3d.object {
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.material.SpriteMaterial;
|
||||||
|
import com.alternativagame.engine3d.skin.SpriteSkin;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
|
||||||
|
public class Sprite3D extends SkinObject3D {
|
||||||
|
|
||||||
|
private var _state:String = "default";
|
||||||
|
|
||||||
|
public function Sprite3D(material:SpriteMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new SpriteSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set state(value:String):void {
|
||||||
|
if (_state != value) {
|
||||||
|
_state = value;
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get state():String {
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Sprite3D = new Sprite3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Sprite3D = Sprite3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 113
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light
|
||||||
|
END
|
||||||
|
Light3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 124
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light/Light3D.as
|
||||||
|
END
|
||||||
|
Direct3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 125
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light/Direct3D.as
|
||||||
|
END
|
||||||
|
Ambient3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 126
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light/Ambient3D.as
|
||||||
|
END
|
||||||
|
Omni3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 123
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light/Omni3D.as
|
||||||
|
END
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/light
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
Light3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
bc1d814a095abb012111db377a7140d9
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Direct3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
dc14d09c074d63a456d37d5fdc342354
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Ambient3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
4591ece7920123a8cc21a94a421e2977
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Omni3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
610ec27852ea1488363489bf7f7860c8
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
public class Ambient3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public function Ambient3D(color:RGB = null) {
|
||||||
|
super(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Ambient3D = new Ambient3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.skin.DirectSkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Direct3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Текущая нормаль освещения в пространстве камеры
|
||||||
|
engine3d var canvasVector:Vector;
|
||||||
|
|
||||||
|
public function Direct3D(color:RGB = null, material:HelperMaterial = null) {
|
||||||
|
super(color, material);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
super.updateTransform();
|
||||||
|
|
||||||
|
// Сохраняем нормаль
|
||||||
|
canvasVector = new Vector(transform.b, transform.f, transform.j);
|
||||||
|
Math3D.normalize(canvasVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new DirectSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
override engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return calculateLightColor(normal, canvasVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Direct3D = new Direct3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.object.HelperObject3D;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Light3D extends HelperObject3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Цвет освещения
|
||||||
|
private var _color:RGB;
|
||||||
|
|
||||||
|
public function Light3D(color:RGB = null, material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
this.color = color;
|
||||||
|
solidLights.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращает освещение на основе направления света и нормали поверхности
|
||||||
|
protected function calculateLightColor(normal:Vector, vector:Vector):RGB {
|
||||||
|
if (color == null) {
|
||||||
|
// Если цвета нет, то вернуть null
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
var strength:Number = 1 - Math3D.vectorDot(normal, vector);
|
||||||
|
return new RGB((color.red*strength) >>> 1, (color.green*strength) >>> 1, (color.blue*strength) >>> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить освещение
|
||||||
|
override protected function updateLightChanged():void {
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Повлиять на солид-область
|
||||||
|
protected function applyToSolidObjects():void {
|
||||||
|
for each (var obj:Object3D in solidParent.solidObjects) {
|
||||||
|
// На источники света не светим
|
||||||
|
if (!(obj is Light3D)) {
|
||||||
|
obj.addLightChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
|
||||||
|
// Забрали себя от старого solidParent
|
||||||
|
solidParent.solidLights.remove(this);
|
||||||
|
|
||||||
|
// Добавили себя к новому solidParent
|
||||||
|
value.solidLights.add(this);
|
||||||
|
|
||||||
|
// Разослать старым соседям, чтобы пересчитались
|
||||||
|
applyToSolidObjects();
|
||||||
|
|
||||||
|
super.setSolidParent(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set color(value:RGB):void {
|
||||||
|
_color = value;
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get color():RGB {
|
||||||
|
return _color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Light3D = new Light3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Light3D = Light3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.color = color.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.skin.OmniSkin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Omni3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Расстояния влияния источника света
|
||||||
|
private var _near:Number;
|
||||||
|
private var _far:Number;
|
||||||
|
|
||||||
|
// Квадраты расстояний влияния
|
||||||
|
engine3d var nearSqr:Number;
|
||||||
|
engine3d var farSqr:Number;
|
||||||
|
|
||||||
|
// Предпросчитанная обратная разница расстояний влияния
|
||||||
|
engine3d var farNearSqr:Number;
|
||||||
|
|
||||||
|
// Параметры в системе камеры
|
||||||
|
engine3d var canvasNear:Number;
|
||||||
|
engine3d var canvasFar:Number;
|
||||||
|
engine3d var canvasNearSqr:Number;
|
||||||
|
engine3d var canvasFarSqr:Number;
|
||||||
|
engine3d var canvasFarNearSqr:Number;
|
||||||
|
|
||||||
|
// Часто изменяемый источник
|
||||||
|
private var _mobile:Boolean = false;
|
||||||
|
|
||||||
|
public function Omni3D(color:RGB = null, near:Number = 0, far:Number = 100, material:HelperMaterial = null) {
|
||||||
|
super(color, material);
|
||||||
|
_near = near;
|
||||||
|
_far = far;
|
||||||
|
calculateParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
super.updateTransform();
|
||||||
|
calculateCanvasParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new OmniSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке (null, если нет)
|
||||||
|
override engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
// Находим вектор до точки из источника
|
||||||
|
var vector:Vector = new Vector(coords.x - transform.d, coords.y - transform.h, coords.z - transform.l);
|
||||||
|
// Находим квадрат расстояния
|
||||||
|
var length:Number = Math3D.vectorLengthSquare(vector);
|
||||||
|
|
||||||
|
// Если за пределами влияния
|
||||||
|
if (length > canvasFarSqr) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
Math3D.normalize(vector);
|
||||||
|
var res:RGB = calculateLightColor(normal, vector);
|
||||||
|
// Если в промежутке near и far
|
||||||
|
if (res != null && length > canvasNearSqr) {
|
||||||
|
res.multiply(canvasFarNearSqr*(canvasFarSqr - length));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление предпросчитанных параметров
|
||||||
|
private function calculateParams():void {
|
||||||
|
nearSqr = _near * _near;
|
||||||
|
farSqr = _far * _far;
|
||||||
|
farNearSqr = 1/(farSqr - nearSqr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление предпросчитанных параметров с учётом масштаба камеры
|
||||||
|
private function calculateCanvasParams():void {
|
||||||
|
canvasNear = _near * view.zoom;
|
||||||
|
canvasFar = _far * view.zoom;
|
||||||
|
canvasNearSqr = canvasNear * canvasNear;
|
||||||
|
canvasFarSqr = canvasFar * canvasFar;
|
||||||
|
canvasFarNearSqr = 1/(canvasFarSqr - canvasNearSqr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set near(value:Number):void {
|
||||||
|
_near = value;
|
||||||
|
calculateParams();
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get near():Number {
|
||||||
|
return _near;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set far(value:Number):void {
|
||||||
|
_far = value;
|
||||||
|
calculateParams();
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get far():Number {
|
||||||
|
return _far;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get mobile():Boolean {
|
||||||
|
return _mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set mobile(value:Boolean):void {
|
||||||
|
if (_mobile != value) {
|
||||||
|
_mobile = value;
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Omni3D = new Omni3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Omni3D = Omni3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.far = far;
|
||||||
|
obj.near = near;
|
||||||
|
obj.mobile = mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
public class Ambient3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public function Ambient3D(color:RGB = null) {
|
||||||
|
super(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Ambient3D = new Ambient3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.skin.DirectSkin;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Direct3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Текущая нормаль освещения в пространстве камеры
|
||||||
|
engine3d var canvasVector:Vector;
|
||||||
|
|
||||||
|
public function Direct3D(color:RGB = null, material:HelperMaterial = null) {
|
||||||
|
super(color, material);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
super.updateTransform();
|
||||||
|
|
||||||
|
// Сохраняем нормаль
|
||||||
|
canvasVector = new Vector(transform.b, transform.f, transform.j);
|
||||||
|
Math3D.normalize(canvasVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new DirectSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
override engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return calculateLightColor(normal, canvasVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Direct3D = new Direct3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.object.HelperObject3D;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Light3D extends HelperObject3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Цвет освещения
|
||||||
|
private var _color:RGB;
|
||||||
|
|
||||||
|
public function Light3D(color:RGB = null, material:HelperMaterial = null) {
|
||||||
|
super(material);
|
||||||
|
this.color = color;
|
||||||
|
solidLights.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке
|
||||||
|
engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращает освещение на основе направления света и нормали поверхности
|
||||||
|
protected function calculateLightColor(normal:Vector, vector:Vector):RGB {
|
||||||
|
if (color == null) {
|
||||||
|
// Если цвета нет, то вернуть null
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
var strength:Number = 1 - Math3D.vectorDot(normal, vector);
|
||||||
|
return new RGB((color.red*strength) >>> 1, (color.green*strength) >>> 1, (color.blue*strength) >>> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить освещение
|
||||||
|
override protected function updateLightChanged():void {
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Повлиять на солид-область
|
||||||
|
protected function applyToSolidObjects():void {
|
||||||
|
for each (var obj:Object3D in solidParent.solidObjects) {
|
||||||
|
// На источники света не светим
|
||||||
|
if (!(obj is Light3D)) {
|
||||||
|
obj.addLightChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override engine3d function setSolidParent(value:Object3D):void {
|
||||||
|
|
||||||
|
// Забрали себя от старого solidParent
|
||||||
|
solidParent.solidLights.remove(this);
|
||||||
|
|
||||||
|
// Добавили себя к новому solidParent
|
||||||
|
value.solidLights.add(this);
|
||||||
|
|
||||||
|
// Разослать старым соседям, чтобы пересчитались
|
||||||
|
applyToSolidObjects();
|
||||||
|
|
||||||
|
super.setSolidParent(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set color(value:RGB):void {
|
||||||
|
_color = value;
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get color():RGB {
|
||||||
|
return _color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Light3D = new Light3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Light3D = Light3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.color = color.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package com.alternativagame.engine3d.object.light {
|
||||||
|
import com.alternativagame.engine3d.material.HelperMaterial;
|
||||||
|
import com.alternativagame.engine3d.material.Material;
|
||||||
|
import com.alternativagame.engine3d.skin.OmniSkin;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
import com.alternativagame.engine3d.skin.Skin;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Omni3D extends Light3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Расстояния влияния источника света
|
||||||
|
private var _near:Number;
|
||||||
|
private var _far:Number;
|
||||||
|
|
||||||
|
// Квадраты расстояний влияния
|
||||||
|
engine3d var nearSqr:Number;
|
||||||
|
engine3d var farSqr:Number;
|
||||||
|
|
||||||
|
// Предпросчитанная обратная разница расстояний влияния
|
||||||
|
engine3d var farNearSqr:Number;
|
||||||
|
|
||||||
|
// Параметры в системе камеры
|
||||||
|
engine3d var canvasNear:Number;
|
||||||
|
engine3d var canvasFar:Number;
|
||||||
|
engine3d var canvasNearSqr:Number;
|
||||||
|
engine3d var canvasFarSqr:Number;
|
||||||
|
engine3d var canvasFarNearSqr:Number;
|
||||||
|
|
||||||
|
// Часто изменяемый источник
|
||||||
|
private var _mobile:Boolean = false;
|
||||||
|
|
||||||
|
public function Omni3D(color:RGB = null, near:Number = 0, far:Number = 100, material:HelperMaterial = null) {
|
||||||
|
super(color, material);
|
||||||
|
_near = near;
|
||||||
|
_far = far;
|
||||||
|
calculateParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
super.updateTransform();
|
||||||
|
calculateCanvasParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected function createSkin():Skin {
|
||||||
|
return new OmniSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Освещение в заданной точке (null, если нет)
|
||||||
|
override engine3d function getLightColor(coords:Vector, normal:Vector):RGB {
|
||||||
|
// Находим вектор до точки из источника
|
||||||
|
var vector:Vector = new Vector(coords.x - transform.d, coords.y - transform.h, coords.z - transform.l);
|
||||||
|
// Находим квадрат расстояния
|
||||||
|
var length:Number = Math3D.vectorLengthSquare(vector);
|
||||||
|
|
||||||
|
// Если за пределами влияния
|
||||||
|
if (length > canvasFarSqr) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
Math3D.normalize(vector);
|
||||||
|
var res:RGB = calculateLightColor(normal, vector);
|
||||||
|
// Если в промежутке near и far
|
||||||
|
if (res != null && length > canvasNearSqr) {
|
||||||
|
res.multiply(canvasFarNearSqr*(canvasFarSqr - length));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление предпросчитанных параметров
|
||||||
|
private function calculateParams():void {
|
||||||
|
nearSqr = _near * _near;
|
||||||
|
farSqr = _far * _far;
|
||||||
|
farNearSqr = 1/(farSqr - nearSqr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление предпросчитанных параметров с учётом масштаба камеры
|
||||||
|
private function calculateCanvasParams():void {
|
||||||
|
canvasNear = _near * view.zoom;
|
||||||
|
canvasFar = _far * view.zoom;
|
||||||
|
canvasNearSqr = canvasNear * canvasNear;
|
||||||
|
canvasFarSqr = canvasFar * canvasFar;
|
||||||
|
canvasFarNearSqr = 1/(canvasFarSqr - canvasNearSqr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set near(value:Number):void {
|
||||||
|
_near = value;
|
||||||
|
calculateParams();
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get near():Number {
|
||||||
|
return _near;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set far(value:Number):void {
|
||||||
|
_far = value;
|
||||||
|
calculateParams();
|
||||||
|
updateSkin();
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get far():Number {
|
||||||
|
return _far;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get mobile():Boolean {
|
||||||
|
return _mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set mobile(value:Boolean):void {
|
||||||
|
if (_mobile != value) {
|
||||||
|
_mobile = value;
|
||||||
|
applyToSolidObjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Omni3D = new Omni3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Omni3D = Omni3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
obj.far = far;
|
||||||
|
obj.near = near;
|
||||||
|
obj.mobile = mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 112
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh
|
||||||
|
END
|
||||||
|
Point3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 123
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh/Point3D.as
|
||||||
|
END
|
||||||
|
Mesh3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 122
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh/Mesh3D.as
|
||||||
|
END
|
||||||
|
PolyMesh3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 126
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh/PolyMesh3D.as
|
||||||
|
END
|
||||||
|
Polygroup3D.as
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 127
|
||||||
|
/!svn/ver/154/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh/Polygroup3D.as
|
||||||
|
END
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
46043
|
||||||
|
http://svndev.alternativaplatform.com/platform/clients/fp9/libraries/Alternativa3D/branches/2.0/com/alternativagame/engine3d/object/mesh
|
||||||
|
http://svndev.alternativaplatform.com
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d9e2387a-1f3e-40e2-b57f-9df5970a2fa5
|
||||||
|
|
||||||
|
Point3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
34b42337804b3534bb07541820868608
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Mesh3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
4d514c00700b4c9ba6b7f93bf615f770
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
polygon
|
||||||
|
dir
|
||||||
|
|
||||||
|
primitive
|
||||||
|
dir
|
||||||
|
|
||||||
|
PolyMesh3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
b664bb4d05e6e8bcb00daa54e5469dc0
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
|
Polygroup3D.as
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-10-28T04:34:04.000000Z
|
||||||
|
c33cadd860c2867e041b9794466ee2ef
|
||||||
|
2008-08-25T13:05:49.549299Z
|
||||||
|
154
|
||||||
|
int
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package com.alternativagame.engine3d.object.mesh {
|
||||||
|
import com.alternativagame.engine3d.View3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.Polygon3D;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Mesh3D extends Object3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Список точек
|
||||||
|
private var _points:Set;
|
||||||
|
// Список полигонов
|
||||||
|
private var _polygons:Set;
|
||||||
|
|
||||||
|
public function Mesh3D() {
|
||||||
|
_points = new Set();
|
||||||
|
_polygons = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
|
||||||
|
transform.d = Math.floor(transform.d);
|
||||||
|
transform.h = Math.floor(transform.h);
|
||||||
|
transform.l = Math.floor(transform.l);
|
||||||
|
|
||||||
|
for each (var point:Point3D in points) {
|
||||||
|
point.updateTransform();
|
||||||
|
}
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
polygon.updateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
override protected function updateLight():void {
|
||||||
|
if (lightChanged.length > 0) {
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
polygon.updateLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновить полигоны, содержащие point
|
||||||
|
public function updatePolygons(point:Point3D):void {
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
if (polygon.a == point || polygon.b == point || polygon.c == point) {
|
||||||
|
polygon.reskin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить точку в объект
|
||||||
|
public function addPoint(point:Point3D):void {
|
||||||
|
// Если точка была в другом меше, удаляем её оттуда
|
||||||
|
if (point.mesh != null) {
|
||||||
|
point.mesh.removePoint(point);
|
||||||
|
}
|
||||||
|
// Добавляем себе точку
|
||||||
|
points.add(point);
|
||||||
|
point.setMesh(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить точку из объекта
|
||||||
|
public function removePoint(point:Point3D):void {
|
||||||
|
// Если у меша такая точка есть
|
||||||
|
if (points.has(point)) {
|
||||||
|
// Удаляем полигоны, зацепленные за эту точку
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
if (point == polygon.a || point == polygon.b || point == polygon.c) {
|
||||||
|
removePolygon(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Удаляем точку
|
||||||
|
points.remove(point);
|
||||||
|
point.setMesh(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить полигон в объект
|
||||||
|
public function addPolygon(polygon:Polygon3D):void {
|
||||||
|
// Если полигон был в другом меше, удаляем его оттуда
|
||||||
|
if (polygon.mesh != null) {
|
||||||
|
polygon.mesh.removePolygon(polygon);
|
||||||
|
}
|
||||||
|
// Добавляем полигон
|
||||||
|
polygons.add(polygon);
|
||||||
|
polygon.setMesh(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить полигон из объекта
|
||||||
|
public function removePolygon(polygon:Polygon3D):void {
|
||||||
|
if (polygons.has(polygon)) {
|
||||||
|
polygons.remove(polygon);
|
||||||
|
polygon.setMesh(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get points():Set {
|
||||||
|
return _points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get polygons():Set {
|
||||||
|
return _polygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Смена камеры
|
||||||
|
override engine3d function setView(value:View3D):void {
|
||||||
|
if (value == null) {
|
||||||
|
// Если удаляем из камеры - удалить скины полигонов
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
polygon.removeSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setView(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Флаг интерактивности
|
||||||
|
override public function set interactive(value:Boolean):void {
|
||||||
|
super.interactive = value;
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
polygon.interactive = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:Mesh3D = new Mesh3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать параметры
|
||||||
|
override protected function cloneParams(object:*):void {
|
||||||
|
var obj:Mesh3D = Mesh3D(object);
|
||||||
|
super.cloneParams(obj);
|
||||||
|
cloneGeometry(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать геометрию (точки, полигоны)
|
||||||
|
protected function cloneGeometry(obj:Mesh3D):void {
|
||||||
|
// Клонируем точки
|
||||||
|
var p:Dictionary = new Dictionary();
|
||||||
|
for each (var point:Point3D in points) {
|
||||||
|
p[point] = point.clone();
|
||||||
|
obj.addPoint(p[point]);
|
||||||
|
}
|
||||||
|
// Клонируем полигоны
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
obj.addPolygon(polygon.clone(p[polygon.a], p[polygon.b], p[polygon.c]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package com.alternativagame.engine3d.object.mesh {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Point3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Ссылка на родителя
|
||||||
|
engine3d var mesh:Mesh3D = null;
|
||||||
|
|
||||||
|
// Смещение точки относительно родителя
|
||||||
|
private var _coords:Vector;
|
||||||
|
|
||||||
|
// Координаты в камере
|
||||||
|
engine3d var canvasCoords:Vector;
|
||||||
|
|
||||||
|
// Округлённые координаты в камере
|
||||||
|
engine3d var canvasX:int;
|
||||||
|
engine3d var canvasY:int;
|
||||||
|
|
||||||
|
public function Point3D(x:Number = 0, y:Number = 0, z:Number = 0) {
|
||||||
|
_coords = new Vector(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function updateTransform():void {
|
||||||
|
canvasCoords = Math3D.vectorTransform(coords, mesh.transform);
|
||||||
|
|
||||||
|
// Округлённые координаты в камере для отрисовки
|
||||||
|
canvasX = Math.floor(canvasCoords.x);
|
||||||
|
canvasY = -Math.floor(canvasCoords.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function get x():Number {
|
||||||
|
return coords.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get y():Number {
|
||||||
|
return coords.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get z():Number {
|
||||||
|
return coords.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set x(value:Number):void {
|
||||||
|
coords.x = value;
|
||||||
|
updateCoords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set y(value:Number):void {
|
||||||
|
coords.y = value;
|
||||||
|
updateCoords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set z(value:Number):void {
|
||||||
|
coords.z = value;
|
||||||
|
updateCoords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get coords():Vector {
|
||||||
|
return _coords;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set coords(value:Vector):void {
|
||||||
|
_coords = value;
|
||||||
|
updateCoords();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновились координаты
|
||||||
|
private function updateCoords():void {
|
||||||
|
// Если в меше и в камере
|
||||||
|
if (mesh != null && mesh.view != null) {
|
||||||
|
// Расчитать глобальные координаты
|
||||||
|
updateTransform();
|
||||||
|
// Обновить зависимые полигоны
|
||||||
|
mesh.updatePolygons(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установить родителя
|
||||||
|
engine3d function setMesh(value:Mesh3D):void {
|
||||||
|
mesh = value;
|
||||||
|
// Пересчитать трансформацию, если установили родителя
|
||||||
|
if (value != null) {
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
public function clone():Point3D {
|
||||||
|
return new Point3D(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package com.alternativagame.engine3d.object.mesh {
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.Object3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.FillPolygon3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.Polygon3D;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class PolyMesh3D extends Mesh3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Полигруппы
|
||||||
|
private var polygroups:Array;
|
||||||
|
|
||||||
|
public function PolyMesh3D() {
|
||||||
|
polygroups = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после трансформации
|
||||||
|
override protected function updateTransform():void {
|
||||||
|
for each (var polygroup:Polygroup3D in polygroups) {
|
||||||
|
polygroup.updateTransform();
|
||||||
|
}
|
||||||
|
super.updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновиться после освещения
|
||||||
|
override protected function updateLight():void {
|
||||||
|
if (lightChanged.length > 0) {
|
||||||
|
for each (var polygroup:Polygroup3D in polygroups) {
|
||||||
|
polygroup.updateLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.updateLight();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установить полигруппу для полигонов
|
||||||
|
public function setPolygroup(name:String, polygons:Set):void {
|
||||||
|
var polygon:FillPolygon3D;
|
||||||
|
|
||||||
|
// Удаляем полигоны из старых полигрупп
|
||||||
|
for each (polygon in polygons) {
|
||||||
|
// Если полигон уже в полигруппе - убрать его оттуда
|
||||||
|
if (polygon.polygroup != null) {
|
||||||
|
// Если этот полигон последний в полигруппе - удалить её из списка
|
||||||
|
if (polygon.polygroup.polygons.length <= 1) {
|
||||||
|
delete polygroups[polygon.polygroup.name];
|
||||||
|
}
|
||||||
|
polygon.polygroup.removePolygon(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если устанавливаем полигруппу
|
||||||
|
if (name != null) {
|
||||||
|
// Если полигруппы нет - создаём
|
||||||
|
if (polygroups[name] == undefined) {
|
||||||
|
polygroups[name] = new Polygroup3D(name);
|
||||||
|
polygroups[name].mesh = this;
|
||||||
|
}
|
||||||
|
var polygroup:Polygroup3D = polygroups[name];
|
||||||
|
|
||||||
|
// Добавить полигоны в полигруппу
|
||||||
|
for each (polygon in polygons) {
|
||||||
|
polygroup.addPolygon(polygon);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновить весь меш
|
||||||
|
for each (polygroup in polygroups) {
|
||||||
|
polygroup.calculateParams();
|
||||||
|
}
|
||||||
|
updateLightChanged();
|
||||||
|
geometryChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клон
|
||||||
|
override public function clone():Object3D {
|
||||||
|
var res:PolyMesh3D = new PolyMesh3D();
|
||||||
|
cloneParams(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клонировать геометрию (точки, полигоны, полигруппы)
|
||||||
|
override protected function cloneGeometry(obj:Mesh3D):void {
|
||||||
|
// Клонируем точки
|
||||||
|
var p:Dictionary = new Dictionary();
|
||||||
|
for each (var point:Point3D in points) {
|
||||||
|
p[point] = point.clone();
|
||||||
|
obj.addPoint(p[point]);
|
||||||
|
}
|
||||||
|
// Клонируем полигоны
|
||||||
|
var f:Dictionary = new Dictionary();
|
||||||
|
for each (var polygon:Polygon3D in polygons) {
|
||||||
|
f[polygon] = polygon.clone(p[polygon.a], p[polygon.b], p[polygon.c]);
|
||||||
|
obj.addPolygon(f[polygon]);
|
||||||
|
}
|
||||||
|
// Клонируем полигруппы
|
||||||
|
/*for each (var polygroup:Polygroup3D in polygroups) {
|
||||||
|
var g:Polygroup3D = new Polygroup3D();
|
||||||
|
for each (polygon in polygroup.polygons) {
|
||||||
|
g.addPolygon(f[polygon]);
|
||||||
|
}
|
||||||
|
PolyMesh3D(obj).addPolygroup(g);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package com.alternativagame.engine3d.object.mesh {
|
||||||
|
import com.alternativagame.engine3d.Math3D;
|
||||||
|
import com.alternativagame.engine3d.Matrix3D;
|
||||||
|
import com.alternativagame.engine3d.engine3d;
|
||||||
|
import com.alternativagame.engine3d.object.light.Light3D;
|
||||||
|
import com.alternativagame.engine3d.object.mesh.polygon.FillPolygon3D;
|
||||||
|
import com.alternativagame.type.RGB;
|
||||||
|
import com.alternativagame.type.Set;
|
||||||
|
import com.alternativagame.type.Vector;
|
||||||
|
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
public class Polygroup3D {
|
||||||
|
|
||||||
|
use namespace engine3d;
|
||||||
|
|
||||||
|
// Имя
|
||||||
|
engine3d var name:String;
|
||||||
|
|
||||||
|
// Ссылка на родителя
|
||||||
|
engine3d var mesh:PolyMesh3D = null;
|
||||||
|
|
||||||
|
// Список полигонов
|
||||||
|
engine3d var polygons:Set;
|
||||||
|
|
||||||
|
// Нормаль
|
||||||
|
private var normal:Vector;
|
||||||
|
|
||||||
|
// Центр полигруппы
|
||||||
|
private var center:Vector;
|
||||||
|
|
||||||
|
// Нормаль в камере
|
||||||
|
engine3d var viewNormal:Vector;
|
||||||
|
|
||||||
|
// Центр полигруппы в камере
|
||||||
|
engine3d var viewCenter:Vector;
|
||||||
|
|
||||||
|
// Текущее освещение
|
||||||
|
engine3d var lightColor:RGB = null;
|
||||||
|
|
||||||
|
// Список цветов источников с учетом силы
|
||||||
|
private var lights:Dictionary;
|
||||||
|
|
||||||
|
public function Polygroup3D(name:String) {
|
||||||
|
lights = new Dictionary();
|
||||||
|
polygons = new Set(true);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление после трансформации меша
|
||||||
|
engine3d function updateTransform():void {
|
||||||
|
var transform:Matrix3D = mesh.transform.clone();
|
||||||
|
|
||||||
|
// Расчитываем центр в координатах камеры
|
||||||
|
viewCenter = Math3D.vectorTransform(center, transform);
|
||||||
|
|
||||||
|
// Убираем сдвиг матрицы родителя
|
||||||
|
transform.d = 0;
|
||||||
|
transform.h = 0;
|
||||||
|
transform.l = 0;
|
||||||
|
|
||||||
|
// Расчитываем нормаль в координатах камеры
|
||||||
|
viewNormal = Math3D.vectorTransform(normal, transform);
|
||||||
|
Math3D.normalize(viewNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт локальных нормали и центра
|
||||||
|
engine3d function calculateParams():void {
|
||||||
|
normal = new Vector();
|
||||||
|
center = new Vector();
|
||||||
|
|
||||||
|
// Если полигоны в группе есть
|
||||||
|
if (polygons.length > 0) {
|
||||||
|
|
||||||
|
var av:Vector;
|
||||||
|
var bv:Vector;
|
||||||
|
var cv:Vector;
|
||||||
|
var v:Vector;
|
||||||
|
var w:Vector;
|
||||||
|
var polynormal:Vector;
|
||||||
|
|
||||||
|
for each (var polygon:FillPolygon3D in polygons) {
|
||||||
|
av = polygon.a.coords;
|
||||||
|
bv = polygon.b.coords;
|
||||||
|
cv = polygon.c.coords;
|
||||||
|
|
||||||
|
// Добавляем центр полигона
|
||||||
|
center = Math3D.vectorAdd(center, new Vector(av.x + bv.x + cv.x, av.y + bv.y + cv.y, av.z + bv.z + cv.z));
|
||||||
|
|
||||||
|
// Добавляем нормаль полигона
|
||||||
|
v = new Vector(bv.x - av.x, bv.y - av.y, bv.z - av.z);
|
||||||
|
w = new Vector(cv.x - av.x, cv.y - av.y, cv.z - av.z);
|
||||||
|
polynormal = Math3D.vectorCross(v, w);
|
||||||
|
Math3D.normalize(polynormal);
|
||||||
|
normal = Math3D.vectorAdd(normal, polynormal);
|
||||||
|
}
|
||||||
|
// Усредняем центр
|
||||||
|
center = Math3D.vectorMultiply(center, 1/(polygons.length*3));
|
||||||
|
|
||||||
|
// Нормализуем сумму нормалей
|
||||||
|
Math3D.normalize(normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
engine3d function updateLight():void {
|
||||||
|
|
||||||
|
// Если есть источники на пересчёт, обновляем список
|
||||||
|
if (mesh.lightChanged.length > 0) {
|
||||||
|
|
||||||
|
var color:RGB;
|
||||||
|
|
||||||
|
for each (var light:Light3D in mesh.lightChanged) {
|
||||||
|
// Расчет производим, только если в одной солид-группе
|
||||||
|
if (light.solidParent == mesh.solidParent) {
|
||||||
|
|
||||||
|
// Получаем освещение от источника
|
||||||
|
color = light.getLightColor(viewCenter, viewNormal);
|
||||||
|
|
||||||
|
if (color == null) {
|
||||||
|
delete lights[light];
|
||||||
|
} else {
|
||||||
|
lights[light] = color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete lights[light];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Расчёт общего света
|
||||||
|
lightColor = new RGB();
|
||||||
|
for each (color in lights) {
|
||||||
|
lightColor.add(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавить полигон в группу
|
||||||
|
engine3d function addPolygon(polygon:FillPolygon3D):void {
|
||||||
|
if (polygon.polygroup != null) {
|
||||||
|
polygon.polygroup.removePolygon(polygon);
|
||||||
|
}
|
||||||
|
polygons.add(polygon);
|
||||||
|
polygon.setPolygroup(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удалить полигон из группы
|
||||||
|
engine3d function removePolygon(polygon:FillPolygon3D):void {
|
||||||
|
if (polygons.has(polygon)) {
|
||||||
|
polygons.remove(polygon);
|
||||||
|
polygon.setPolygroup(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user