more versions added

This commit is contained in:
Tubix
2024-10-05 12:11:16 +01:00
parent 413f563f33
commit c32c7e8c34
7661 changed files with 1343635 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
Alternativa3D2/.DS_Store vendored Normal file

Binary file not shown.

View 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>

View 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

View 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

View File

@@ -0,0 +1 @@
8

View File

@@ -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>

View File

@@ -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>

View 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>

View 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>&lt;project&gt;/.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>

View 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

View 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

View File

@@ -0,0 +1 @@
8

View File

@@ -0,0 +1,3 @@
#Fri Nov 17 12:29:06 YEKT 2006
eclipse.preferences.version=1
encoding/<project>=utf-8

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,3 @@
#Fri Nov 17 12:29:06 YEKT 2006
eclipse.preferences.version=1
encoding/<project>=utf-8

View File

@@ -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

View File

@@ -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

View 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

View 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

View File

@@ -0,0 +1 @@
8

View 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>

View 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>

View 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>&lt;project&gt;/.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>

View 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>

View 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>

View 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

View 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

View File

@@ -0,0 +1 @@
8

View 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

View 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

View File

@@ -0,0 +1 @@
8

View File

@@ -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

View 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

View File

@@ -0,0 +1 @@
8

View 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;
}
}
}

View 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;
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View File

@@ -0,0 +1,3 @@
package com.alternativagame.engine3d {
public namespace engine3d;
}

View 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;
}
}
}

View 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;
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View File

@@ -0,0 +1,3 @@
package com.alternativagame.engine3d {
public namespace engine3d;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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]));
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}*/
}
}
}

View File

@@ -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