diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..acfeeee --- /dev/null +++ b/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f547dc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.gradle/ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..72f65b4 --- /dev/null +++ b/.project @@ -0,0 +1,36 @@ + + + CactusServer + Project CactusServer created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..408b507 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..daedf95 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..ebcbb70 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/WEB-INF/web.xml b/WEB-INF/web.xml new file mode 100644 index 0000000..1c83f13 --- /dev/null +++ b/WEB-INF/web.xml @@ -0,0 +1,5 @@ + + + + webtest + \ No newline at end of file diff --git a/aopalliance-repackaged-2.5.0-b42.jar b/aopalliance-repackaged-2.5.0-b42.jar new file mode 100644 index 0000000..83558eb --- /dev/null +++ b/aopalliance-repackaged-2.5.0-b42.jar Binary files differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..40f5044 --- /dev/null +++ b/build.gradle @@ -0,0 +1,19 @@ + +apply plugin: 'war' +apply plugin: 'eclipse-wtp' + +repositories { + jcenter() +} + +configurations { + all*.exclude module: 'servlet-api' +} + +dependencies { + compile fileTree(dir: './', includes: ['*.jar']) + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.+' + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' + compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0' + testCompile group: 'junit', name: 'junit', version: '4.+' +} \ No newline at end of file diff --git a/cdi-api-1.1.jar b/cdi-api-1.1.jar new file mode 100644 index 0000000..d8aaf7e --- /dev/null +++ b/cdi-api-1.1.jar Binary files differ diff --git a/cv97r140.jar b/cv97r140.jar new file mode 100644 index 0000000..b742046 --- /dev/null +++ b/cv97r140.jar Binary files differ diff --git a/el-api-2.2.jar b/el-api-2.2.jar new file mode 100644 index 0000000..da6730c --- /dev/null +++ b/el-api-2.2.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..27768f1 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..4c637cc --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/hk2-api-2.5.0-b42.jar b/hk2-api-2.5.0-b42.jar new file mode 100644 index 0000000..c72ce98 --- /dev/null +++ b/hk2-api-2.5.0-b42.jar Binary files differ diff --git a/hk2-locator-2.5.0-b42.jar b/hk2-locator-2.5.0-b42.jar new file mode 100644 index 0000000..d05a71b --- /dev/null +++ b/hk2-locator-2.5.0-b42.jar Binary files differ diff --git a/hk2-utils-2.5.0-b42.jar b/hk2-utils-2.5.0-b42.jar new file mode 100644 index 0000000..fa5066f --- /dev/null +++ b/hk2-utils-2.5.0-b42.jar Binary files differ diff --git a/j3dcore.jar b/j3dcore.jar new file mode 100644 index 0000000..aea76e1 --- /dev/null +++ b/j3dcore.jar Binary files differ diff --git a/j3dutils.jar b/j3dutils.jar new file mode 100644 index 0000000..0e2e9c7 --- /dev/null +++ b/j3dutils.jar Binary files differ diff --git a/javassist-3.22.0-CR2.jar b/javassist-3.22.0-CR2.jar new file mode 100644 index 0000000..0b02004 --- /dev/null +++ b/javassist-3.22.0-CR2.jar Binary files differ diff --git a/javax.inject-1.jar b/javax.inject-1.jar new file mode 100644 index 0000000..b2a9d0b --- /dev/null +++ b/javax.inject-1.jar Binary files differ diff --git a/javax.json-1.1.jar b/javax.json-1.1.jar new file mode 100644 index 0000000..a47350c --- /dev/null +++ b/javax.json-1.1.jar Binary files differ diff --git a/javax.json-api-1.1.jar b/javax.json-api-1.1.jar new file mode 100644 index 0000000..94f556d --- /dev/null +++ b/javax.json-api-1.1.jar Binary files differ diff --git a/javax.json.bind-api-1.0.jar b/javax.json.bind-api-1.0.jar new file mode 100644 index 0000000..f971d6f --- /dev/null +++ b/javax.json.bind-api-1.0.jar Binary files differ diff --git a/javax.servlet-api-3.0.1.jar b/javax.servlet-api-3.0.1.jar new file mode 100644 index 0000000..4e2edcc --- /dev/null +++ b/javax.servlet-api-3.0.1.jar Binary files differ diff --git a/jaxb-api-2.2.7.jar b/jaxb-api-2.2.7.jar new file mode 100644 index 0000000..ae2adee --- /dev/null +++ b/jaxb-api-2.2.7.jar Binary files differ diff --git a/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar b/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar new file mode 100644 index 0000000..9f9fd82 --- /dev/null +++ b/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar Binary files differ diff --git a/jersey-client.jar b/jersey-client.jar new file mode 100644 index 0000000..5a130a7 --- /dev/null +++ b/jersey-client.jar Binary files differ diff --git a/jersey-common.jar b/jersey-common.jar new file mode 100644 index 0000000..3b35ecc --- /dev/null +++ b/jersey-common.jar Binary files differ diff --git a/jersey-container-servlet-core.jar b/jersey-container-servlet-core.jar new file mode 100644 index 0000000..5674f5d --- /dev/null +++ b/jersey-container-servlet-core.jar Binary files differ diff --git a/jersey-container-servlet.jar b/jersey-container-servlet.jar new file mode 100644 index 0000000..00f27b2 --- /dev/null +++ b/jersey-container-servlet.jar Binary files differ diff --git a/jersey-hk2.jar b/jersey-hk2.jar new file mode 100644 index 0000000..2d80a43 --- /dev/null +++ b/jersey-hk2.jar Binary files differ diff --git a/jersey-media-jaxb.jar b/jersey-media-jaxb.jar new file mode 100644 index 0000000..8211696 --- /dev/null +++ b/jersey-media-jaxb.jar Binary files differ diff --git a/jersey-media-json-binding.jar b/jersey-media-json-binding.jar new file mode 100644 index 0000000..3007732 --- /dev/null +++ b/jersey-media-json-binding.jar Binary files differ diff --git a/jersey-media-sse.jar b/jersey-media-sse.jar new file mode 100644 index 0000000..8df13c5 --- /dev/null +++ b/jersey-media-sse.jar Binary files differ diff --git a/jersey-server.jar b/jersey-server.jar new file mode 100644 index 0000000..71b81bd --- /dev/null +++ b/jersey-server.jar Binary files differ diff --git a/jsonic-1.3.10-javadoc.jar b/jsonic-1.3.10-javadoc.jar new file mode 100644 index 0000000..67630af --- /dev/null +++ b/jsonic-1.3.10-javadoc.jar Binary files differ diff --git a/jsonic-1.3.10-sources.jar b/jsonic-1.3.10-sources.jar new file mode 100644 index 0000000..a5cc106 --- /dev/null +++ b/jsonic-1.3.10-sources.jar Binary files differ diff --git a/jsonic-1.3.10.jar b/jsonic-1.3.10.jar new file mode 100644 index 0000000..05ef593 --- /dev/null +++ b/jsonic-1.3.10.jar Binary files differ diff --git a/jsr250-api-1.0.jar b/jsr250-api-1.0.jar new file mode 100644 index 0000000..c1f29bf --- /dev/null +++ b/jsr250-api-1.0.jar Binary files differ diff --git a/org.osgi.core-4.2.0.jar b/org.osgi.core-4.2.0.jar new file mode 100644 index 0000000..b986ac1 --- /dev/null +++ b/org.osgi.core-4.2.0.jar Binary files differ diff --git a/persistence-api-1.0.jar b/persistence-api-1.0.jar new file mode 100644 index 0000000..fe5dbcd --- /dev/null +++ b/persistence-api-1.0.jar Binary files differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..c7c0479 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,18 @@ +/* + * This settings file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * In a single project build this file can be empty or even removed. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/4.3/userguide/multi_project_builds.html + */ + +/* +// To declare projects as part of a multi-project build use the 'include' method +include 'shared' +include 'api' +include 'services:webservice' +*/ + +rootProject.name = 'CactusServer' diff --git a/src/main/java/fight3D/Attackable.java b/src/main/java/fight3D/Attackable.java new file mode 100644 index 0000000..28e63d3 --- /dev/null +++ b/src/main/java/fight3D/Attackable.java @@ -0,0 +1,19 @@ +package fight3D; +import javax.media.j3d.BranchGroup; + +import framework.model3D.Object3D; + + +public interface Attackable { + + abstract public Object3D getBody(); + abstract public String getPartName(); + abstract public Player getOwner(); + abstract public int getAP(); + abstract public boolean isMovable(); + abstract public boolean isAlive(); + abstract public void appear(); + abstract public void disappear(); + abstract public boolean isActivate(); + +} diff --git a/src/main/java/fight3D/AttackingPart.java b/src/main/java/fight3D/AttackingPart.java new file mode 100644 index 0000000..8b26717 --- /dev/null +++ b/src/main/java/fight3D/AttackingPart.java @@ -0,0 +1,88 @@ +package fight3D; +import javax.media.j3d.BranchGroup; + +import framework.model3D.Object3D; + + +/** + * �v���C���[�̑̂̒��̍U���Ɏg�p���Ă��镔�� + * @author �V�c���� + * + */ +public class AttackingPart implements Attackable { + + private String partName = null; + private Player owner; + private boolean fActive = true; + private long timeLag = 0; // �U���������n�߂�܂ł̎��ԁi�������ԁj + + //�R���X�g���N�^ + public AttackingPart(String pn, Player o, long t){ + partName = pn; + owner = o; + timeLag = t; + } + + @Override + //�U���͂�Ԃ� + public int getAP() { + // TODO Auto-generated method stub + return owner.character.getPower(); + } + + @Override + //���́i�R�����j�̌`�������� + public Object3D getBody() { + // TODO Auto-generated method stub + return owner.body; + + } + + @Override + public String getPartName() { + // TODO Auto-generated method stub + return partName; + } + + @Override + //�N���U���������i�L���ȍU���j + public Player getOwner() { + // TODO Auto-generated method stub + return owner; + } + + @Override + //�U�����镨�i�̂̈ꕔ�═��j�ƈꏏ�Ɏ��g���������Ƃ��ł��邩 + public boolean isMovable() { + // TODO Auto-generated method stub + return false; + } + + //�U�����I�������A������ + void onEndAnimation() { + disappear(); + } + + //���݂��Ă��邩 + public boolean isAlive() { + return fActive; + } + + @Override + public void appear() { + // TODO Auto-generated method stub + fActive = true; + } + + @Override + public void disappear() { + // TODO Auto-generated method stub + fActive = false; + } + + @Override + public boolean isActivate() { + // TODO Auto-generated method stub + return (owner.animation.time >= timeLag); + } +} diff --git a/src/main/java/fight3D/Character.java b/src/main/java/fight3D/Character.java new file mode 100644 index 0000000..90c499f --- /dev/null +++ b/src/main/java/fight3D/Character.java @@ -0,0 +1,295 @@ +package fight3D; +import framework.animation.Animation3D; +import framework.audio.Sound3D; +import framework.gameMain.Mode; +import framework.gameMain.ModeOnGround; +import framework.gameMain.ActorModel; +import framework.physics.Velocity3D; + + + +public class Character extends ActorModel { + + private String name, comment; + private String attackingPartName = null; + private String upperAttackingPartName = null; + private String jumpAttackingPartName = null; + private long attackTimeLag = 0; + private long upperAttackTimeLag = 0; + private long jumpAttackTimeLag = 0; + private WeaponModel weaponModel, upperWeaponModel, jumpWeaponModel; + private Velocity3D weaponSpeed = new Velocity3D(4.0, 0.0, 0.0); + private Velocity3D upperWeaponSpeed = new Velocity3D(4.0, 0.0, 0.0); + private Velocity3D jumpWeaponSpeed = new Velocity3D(4.0, 0.0, 0.0); + private double runSpeed = 5.0, jumpPower = 10.0; + private int p, jf, d, s; + + + private static Animation3D defaultAnimation = new Animation3D(); + public Animation3D rightMoveAnimation = defaultAnimation; + public Animation3D leftMoveAnimation = defaultAnimation; + public Animation3D jumpAnimation = defaultAnimation; + public Animation3D damagedAnimation = defaultAnimation; + public Animation3D attackAnimation = defaultAnimation; + public Animation3D upperAttackAnimation = defaultAnimation; + public Animation3D jumpAttackAnimation = defaultAnimation; + public Sound3D jumpSound = null; + public Sound3D attackSound = null; + public Sound3D upperAttackSound = null; + public Sound3D jumpAttackSound = null; + public Sound3D damagedSound = null; + + public Character(String fileName) { + super(fileName); + } + + /** + * �A�j���[�V������Ԃ� + * @param m �v���C���[�̃��[�h + * @param s �v���C���[�̏�� + * @return �A�j���[�V���� + */ + public Animation3D getAnimation(Mode m, State s) { + if(m instanceof ModeOnGround) { + //���E�ɓ����A�j���[�V�����͒n��ɂ���Ƃ��̂� + if(s instanceof StateLeftMove) { + return new Animation3D(leftMoveAnimation); + } + else if(s instanceof StateRightMove) { + return new Animation3D(rightMoveAnimation); + } + } + if(s instanceof StateJump) { + return new Animation3D(jumpAnimation); + } + else if(s instanceof StateAttack){ + return new Animation3D(attackAnimation); + } + else if(s instanceof StateUpperAttack){ + return new Animation3D(upperAttackAnimation); + } + else if(s instanceof StateJumpAttack){ + return new Animation3D(jumpAttackAnimation); + } + else if(s instanceof StateDamaged){ + return new Animation3D(damagedAnimation); + } + return new Animation3D(defaultAnimation); + } + + /** + * ���ʉ���Ԃ� + * @param m �v���C���[�̃��[�h + * @param s �v���C���[�̏�� + * @return ���ʉ� + */ + public Sound3D getSoundEffect(Mode m, State s) { + if(s instanceof StateJump) { + return jumpSound; + } + else if(s instanceof StateAttack){ + return attackSound; + } + else if(s instanceof StateUpperAttack){ + return upperAttackSound; + } + else if(s instanceof StateJumpAttack){ + return jumpAttackSound; + } + else if(s instanceof StateDamaged){ + return damagedSound; + } + return null; + } + +// public Attackable getAttackable(Player p){ +// Attackable a = new AttackingPart(attackingPartName , p); +// return a; +// } + + public void setName(String n) { + name = n; + } + + public String getName() { + return name; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getComment() { + return comment; + } + + // �U�����镔���̖��O�i�ʏ�U���A������̍U���A�������̍U���j + public void setAttackingPartName(String apn) { + attackingPartName = apn; + } + public String getAttackingPartName() { + return attackingPartName; + } + + public void setUpperAttackingPartName(String s) { + upperAttackingPartName = s; + } + + public String getUpperAttackingPartName() { + return upperAttackingPartName; + } + + public void setJumpAttackingPartName(String s) { + jumpAttackingPartName = s; + } + + public String getJumpAttackingPartName() { + return jumpAttackingPartName; + } + + // ���탂�f���i�ʏ�U���A������̍U���A�������̍U���j + public void setWeaponModel(WeaponModel w) { + weaponModel = w; + } + public WeaponModel getWeaponModel() { + return weaponModel; + } + + public void setUpperWeaponModel(WeaponModel w) { + upperWeaponModel = w; + } + + public WeaponModel getUpperWeaponModel() { + return upperWeaponModel; + } + + public void setJumpWeaponModel(WeaponModel w) { + jumpWeaponModel = w; + } + + public WeaponModel getJumpWeaponModel() { + return jumpWeaponModel; + } + + //��ѓ���̑����i�ʏ�U���A������̍U���A�������̍U���j + public void setWeaponSpeed(double x, double y, double z) { + this.weaponSpeed = new Velocity3D(x, y, z); + } + + public Velocity3D getWeaponSpeed() { + return weaponSpeed; + } + + public void setUpperWeaponSpeed(double x, double y, double z) { + upperWeaponSpeed = new Velocity3D(x, y, z); + } + + public Velocity3D getUpperWeaponSpeed() { + return upperWeaponSpeed; + } + + public void setJumpWeaponSpeed(double x, double y, double z) { + jumpWeaponSpeed = new Velocity3D(x, y, z); + } + + public Velocity3D getJumpWeaponSpeed() { + return jumpWeaponSpeed; + } + + //�ړ��̑��� + public void setRunSpeed(double rs) { + this.runSpeed = rs; + } + + public double getRunSpeed() { + return runSpeed; + } + + //�U���� + public void setPower(int p) { + this.p = p; + } + + public int getPower() { + return p; + } + + //�W�����v�� + public void setJumpPower(double e) { + this.jumpPower = e; + } + + public double getJumpPower() { + return jumpPower; + } + + //�W�����v�� + public void setJumpFrequency(int jf) { + this.jf = jf; + } + + public int getJumpFrequency() { + return jf; + } + + //�h��� + public void setDefense(int d) { + this.d = d; + } + + public int getDefense() { + return d; + } + + public void setSize(int s) { + this.s = s; + } + + public int getSize() { + return s; + } + + //Weapon��AttackingPart�Ƃǂ���������Ă��邩�𕷂����\�b�h + public boolean hasAttackingPart(){ + if(getAttackingPartName() != null) + return true; + else return false; + } + + public boolean hasUpperAttackingPart(){ + if(getUpperAttackingPartName() != null) + return true; + else return false; + } + + public boolean hasJumpAttackingPart(){ + if(getJumpAttackingPartName() != null) + return true; + else return false; + } + + public void setAttackTimeLag(long attackTimeLag) { + this.attackTimeLag = attackTimeLag; + } + + public long getAttackTimeLag() { + return attackTimeLag; + } + + public void setUpperAttackTimeLag(long upperAttackTimeLag) { + this.upperAttackTimeLag = upperAttackTimeLag; + } + + public long getUpperAttackTimeLag() { + return upperAttackTimeLag; + } + + public void setJumpAttackTimeLag(long jumpAttackTimeLag) { + this.jumpAttackTimeLag = jumpAttackTimeLag; + } + + public long getJumpAttackTimeLag() { + return jumpAttackTimeLag; + } + +} diff --git a/src/main/java/fight3D/CharacterManager.java b/src/main/java/fight3D/CharacterManager.java new file mode 100644 index 0000000..9e63f0f --- /dev/null +++ b/src/main/java/fight3D/CharacterManager.java @@ -0,0 +1,305 @@ +package fight3D; + +import java.util.ArrayList; + +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.audio.Sound3D; +import framework.gameMain.AbstractManager; + +public class CharacterManager extends AbstractManager{ + + private static CharacterManager theInstance = null; + + private static String filename = "data"; + private static String characterFile = "character.def"; + + private static final String NAME_TAG = "Name"; + private static final String MODEL_FILE_TAG = "ModelFile"; + private static final String RIGHTMOVE_ANIMATION_FILE_TAG = "RightMoveAnimationFile"; + private static final String LEFTMOVE_ANIMATION_FILE_TAG = "LeftMoveAnimationFile"; + + private static final String JUMP_ANIMATION_FILE_TAG = "JumpAnimationFile"; + private static final String JUMP_SOUND_FILE_TAG = "JumpSoundFile"; + private static final String JUMP_POWER_TAG = "JumpPower"; + private static final String JUMP_FREQUENCY_TAG = "JumpFrequency"; + + private static final String DAMAGED_ANIMATION_FILE_TAG = "DamagedAnimationFile"; + private static final String DAMAGED_SOUND_FILE_TAG = "DamagedSoundFile"; + + private static final String RUN_SPEED_TAG = "RunSpeed"; + private static final String POWER_TAG = "Power"; + private static final String DEFENSE_TAG = "Defense"; + + private static final String ATTACKING_PART_NAME_TAG = "AttackingPartName"; + private static final String ATTACK_ANIMATION_FILE_TAG = "AttackAnimationFile"; + private static final String ATTACK_SOUND_FILE_TAG = "AttackSoundFile"; + private static final String ATTACK_TIME_LAG_TAG = "AttackTimeLag"; + private static final String WEAPON_FILE_TAG = "WeaponFile"; + private static final String WEAPON_ANIMATION_FILE_TAG = "WeaponAnimationFile"; + private static final String WEAPON_SPEED_TAG = "WeaponSpeed"; + + private static final String UPPER_ATTACKING_PART_NAME_TAG = "UpperAttackingPartName"; + private static final String UPPER_ATTACK_ANIMATION_FILE_TAG = "UpperAttackAnimationFile"; + private static final String UPPER_ATTACK_SOUND_FILE_TAG = "UpperAttackSoundFile"; + private static final String UPPER_ATTACK_TIME_LAG_TAG = "UpperAttackTimeLag"; + private static final String UPPER_WEAPON_FILE_TAG = "UpperWeaponFile"; + private static final String UPPER_WEAPON_ANIMATION_FILE_TAG = "UpperWeaponAnimationFile"; + private static final String UPPER_WEAPON_SPEED_TAG = "UpperWeaponSpeed"; + + private static final String JUMP_ATTACKING_PART_NAME_TAG = "JumpAttackingPartName"; + private static final String JUMP_ATTACK_ANIMATION_FILE_TAG = "JumpAttackAnimationFile"; + private static final String JUMP_ATTACK_SOUND_FILE_TAG = "JumpAttackSoundFile"; + private static final String JUMP_ATTACK_TIME_LAG_TAG = "JumpAttackTimeLag"; + private static final String JUMP_WEAPON_FILE_TAG = "JumpWeaponFile"; + private static final String JUMP_WEAPON_ANIMATION_FILE_TAG = "JumpWeaponAnimationFile"; + private static final String JUMP_WEAPON_SPEED_TAG = "JumpWeaponSpeed"; + + private static final String SIZE_TAG = "Size"; + + private static final String COMMENT_TAG = "Comment"; + + private ArrayList characterList = new ArrayList(); + + private CharacterManager() { + addSeekFile(characterFile); + setTag(NAME_TAG); + setTag(MODEL_FILE_TAG); + setTag(RIGHTMOVE_ANIMATION_FILE_TAG); + setTag(LEFTMOVE_ANIMATION_FILE_TAG); + setTag(JUMP_ANIMATION_FILE_TAG); + setTag(JUMP_SOUND_FILE_TAG); + setTag(JUMP_POWER_TAG); + setTag(JUMP_FREQUENCY_TAG); + setTag(DAMAGED_ANIMATION_FILE_TAG); + setTag(DAMAGED_SOUND_FILE_TAG); + setTag(RUN_SPEED_TAG); + setTag(POWER_TAG); + setTag(DEFENSE_TAG); + setTag(ATTACKING_PART_NAME_TAG); + setTag(ATTACK_ANIMATION_FILE_TAG); + setTag(ATTACK_SOUND_FILE_TAG); + setTag(ATTACK_TIME_LAG_TAG); + setTag(WEAPON_FILE_TAG); + setTag(WEAPON_ANIMATION_FILE_TAG); + setTag(WEAPON_SPEED_TAG); + setTag(UPPER_ATTACKING_PART_NAME_TAG); + setTag(UPPER_ATTACK_ANIMATION_FILE_TAG); + setTag(UPPER_ATTACK_SOUND_FILE_TAG); + setTag(UPPER_ATTACK_TIME_LAG_TAG); + setTag(UPPER_WEAPON_FILE_TAG); + setTag(UPPER_WEAPON_ANIMATION_FILE_TAG); + setTag(UPPER_WEAPON_SPEED_TAG); + setTag(JUMP_ATTACKING_PART_NAME_TAG); + setTag(JUMP_ATTACK_ANIMATION_FILE_TAG); + setTag(JUMP_ATTACK_SOUND_FILE_TAG); + setTag(JUMP_ATTACK_TIME_LAG_TAG); + setTag(JUMP_WEAPON_FILE_TAG); + setTag(JUMP_WEAPON_ANIMATION_FILE_TAG); + setTag(JUMP_WEAPON_SPEED_TAG); + setTag(SIZE_TAG); + setTag(COMMENT_TAG); + seek(filename); + } + + static public CharacterManager getInstance() { + if(theInstance == null) { + theInstance = new CharacterManager(); + } + return theInstance; + } + + /** + * �L�����N�^�[��Ԃ��܂��B + * @param id�L�����N�^�[�i���o�[ + * @return + */ + public Character getCharacter(int id) { + if(id < characterList.size()) { + return characterList.get(id); + } + else { + return null; + } + } + + /** + * �L�����N�^�[�̐���Ԃ��܂��B + * @return + */ + public int getNumberOfCharacters() { + return characterList.size(); + } + + @Override + protected void create() { + // TODO Auto-generated method stub + Character p = new Character(getData(MODEL_FILE_TAG)); + //WeaponModel w = new WeaponModel(getData(WEAPON_FILE_TAG)); + //p.setWeponModel(w); + + // �L�����N�^�� + p.setName(getData(NAME_TAG)); + + // �L�����N�^�̐��� + p.setComment(getData(COMMENT_TAG)); + + // �A�j���[�V�����t�@�C�� + if(getData(RIGHTMOVE_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(RIGHTMOVE_ANIMATION_FILE_TAG)); + if(animation != null) { + p.rightMoveAnimation = animation; + } + } + if(getData(LEFTMOVE_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(LEFTMOVE_ANIMATION_FILE_TAG)); + if(animation != null) { + p.leftMoveAnimation = animation; + } + } + if(getData(JUMP_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(JUMP_ANIMATION_FILE_TAG)); + if(animation != null) { + p.jumpAnimation = animation; + } + } + if(hasData(JUMP_SOUND_FILE_TAG)) { + Sound3D sound = new Sound3D(getData(JUMP_SOUND_FILE_TAG)); + if(sound != null) { + p.jumpSound = sound; + } + } + if(getData(DAMAGED_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(DAMAGED_ANIMATION_FILE_TAG)); + if(animation != null) { + p.damagedAnimation = animation; + } + } + if(hasData(DAMAGED_SOUND_FILE_TAG)) { + Sound3D sound = new Sound3D(getData(DAMAGED_SOUND_FILE_TAG)); + if(sound != null) { + p.damagedSound = sound; + } + } + + // �p�����[�^ + if(!hasData(RUN_SPEED_TAG)) System.out.println("Error!! No RunSpeed data."); + else p.setRunSpeed(Double.parseDouble(getData(RUN_SPEED_TAG))); + if(!hasData(POWER_TAG)) System.out.println("Error!! No Power data."); + else p.setPower(Integer.parseInt(getData(POWER_TAG))); + if(!hasData(JUMP_POWER_TAG)) System.out.println("Error!! No JumpPower data."); + else p.setJumpPower(Double.parseDouble(getData(JUMP_POWER_TAG))); + if(!hasData(JUMP_FREQUENCY_TAG)) System.out.println("Error!! No JumpFrequency data."); + else p.setJumpFrequency(Integer.parseInt(getData(JUMP_FREQUENCY_TAG))); + if(!hasData(DEFENSE_TAG)) System.out.println("Error!! No Defense data."); + else p.setDefense(Integer.parseInt(getData(DEFENSE_TAG))); + if(!hasData(SIZE_TAG)) System.out.println("Error!! No Size data."); + else p.setSize(Integer.parseInt(getData(SIZE_TAG))); + + // �ʏ�̍U���i�����U���j + if(getData(ATTACK_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(ATTACK_ANIMATION_FILE_TAG)); + if(animation != null) { + p.attackAnimation = animation; + } + } + if(hasData(ATTACK_SOUND_FILE_TAG)) { + Sound3D sound = new Sound3D(getData(ATTACK_SOUND_FILE_TAG)); + if(sound != null) { + p.attackSound = sound; + } + } + if(hasData(ATTACKING_PART_NAME_TAG)) p.setAttackingPartName(getData(ATTACKING_PART_NAME_TAG)); + if(hasData(ATTACK_TIME_LAG_TAG)) p.setAttackTimeLag(Long.parseLong(getData(ATTACK_TIME_LAG_TAG))); + if(hasData(WEAPON_FILE_TAG)) { + WeaponModel weapon = new WeaponModel(getData(WEAPON_FILE_TAG)); + if(hasData(WEAPON_ANIMATION_FILE_TAG)) { + Animation3D animation = AnimationFactory.loadAnimation(getData(WEAPON_ANIMATION_FILE_TAG)); + if(animation != null) { + weapon.weaponAnimation = animation; + } + } + p.setWeaponModel(weapon); + } + if(hasData(WEAPON_SPEED_TAG)) { + String vector = getData(WEAPON_SPEED_TAG); + String axis[] = vector.split(","); + p.setWeaponSpeed(Double.parseDouble(axis[0]),Double.parseDouble(axis[1]),Double.parseDouble(axis[2])); + } + //ATTACKING_PART_NAME��WEAPON_FILE�̃f�[�^���d������Ƃ��A�ǂ�����f�[�^���Ȃ��Ƃ��A�G���[�B + if((!hasData(ATTACKING_PART_NAME_TAG))&&(!hasData(WEAPON_FILE_TAG))) + System.out.println("Error!! No Weapon nor AttackingPart data."); + else if((hasData(ATTACKING_PART_NAME_TAG))&&(hasData(WEAPON_FILE_TAG))) + System.out.println("Error!! Weapon & AttackingPart are overlapping."); + + // ������̍U���i�΋�U���j + if(getData(UPPER_ATTACK_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(UPPER_ATTACK_ANIMATION_FILE_TAG)); + if(animation != null) { + p.upperAttackAnimation = animation; + } + } + if(hasData(UPPER_ATTACK_SOUND_FILE_TAG)) { + Sound3D sound = new Sound3D(getData(UPPER_ATTACK_SOUND_FILE_TAG)); + if(sound != null) { + p.upperAttackSound = sound; + } + } + if(hasData(UPPER_ATTACKING_PART_NAME_TAG)) p.setUpperAttackingPartName(getData(UPPER_ATTACKING_PART_NAME_TAG)); + if(hasData(UPPER_ATTACK_TIME_LAG_TAG)) p.setUpperAttackTimeLag(Long.parseLong(getData(UPPER_ATTACK_TIME_LAG_TAG))); + if(hasData(UPPER_WEAPON_FILE_TAG)) { + WeaponModel upperWeapon = new WeaponModel(getData(UPPER_WEAPON_FILE_TAG)); + if(hasData(UPPER_WEAPON_ANIMATION_FILE_TAG)) { + Animation3D animation = AnimationFactory.loadAnimation(getData(UPPER_WEAPON_ANIMATION_FILE_TAG)); + if(animation != null) { + upperWeapon.weaponAnimation = animation; + } + } + p.setUpperWeaponModel(upperWeapon); + } + if(hasData(UPPER_WEAPON_SPEED_TAG)) { + String vector = getData(UPPER_WEAPON_SPEED_TAG); + String axis[] = vector.split(","); + p.setUpperWeaponSpeed(Double.parseDouble(axis[0]),Double.parseDouble(axis[1]),Double.parseDouble(axis[2])); + } + //UPPER_ATTACKING_PART_NAME��UPPER_WEAPON_FILE�̃f�[�^���d������Ƃ��A�G���[�B + if((hasData(UPPER_ATTACKING_PART_NAME_TAG))&&(hasData(UPPER_WEAPON_FILE_TAG))) + System.out.println("Error!! Weapon & AttackingPart are overlapping."); + + // �������̍U���i�W�����v�U���j + if(getData(JUMP_ATTACK_ANIMATION_FILE_TAG) != null) { + Animation3D animation = AnimationFactory.loadAnimation(getData(JUMP_ATTACK_ANIMATION_FILE_TAG)); + if(animation != null) { + p.jumpAttackAnimation = animation; + } + } + if(hasData(JUMP_ATTACK_SOUND_FILE_TAG)) { + Sound3D sound = new Sound3D(getData(JUMP_ATTACK_SOUND_FILE_TAG)); + if(sound != null) { + p.jumpAttackSound = sound; + } + } + if(hasData(JUMP_ATTACKING_PART_NAME_TAG)) p.setJumpAttackingPartName(getData(JUMP_ATTACKING_PART_NAME_TAG)); + if(hasData(JUMP_ATTACK_TIME_LAG_TAG)) p.setJumpAttackTimeLag(Long.parseLong(getData(JUMP_ATTACK_TIME_LAG_TAG))); + if(hasData(JUMP_WEAPON_FILE_TAG)) { + WeaponModel jumpWeapon = new WeaponModel(getData(JUMP_WEAPON_FILE_TAG)); + if(hasData(JUMP_WEAPON_ANIMATION_FILE_TAG)) { + Animation3D animation = AnimationFactory.loadAnimation(getData(JUMP_WEAPON_ANIMATION_FILE_TAG)); + if(animation != null) { + jumpWeapon.weaponAnimation = animation; + } + } + p.setJumpWeaponModel(jumpWeapon); + } + if(hasData(JUMP_WEAPON_SPEED_TAG)) { + String vector = getData(JUMP_WEAPON_SPEED_TAG); + String axis[] = vector.split(","); + p.setJumpWeaponSpeed(Double.parseDouble(axis[0]),Double.parseDouble(axis[1]),Double.parseDouble(axis[2])); + } + //JUMP_ATTACKING_PART_NAME��JUMP_WEAPON_FILE�̃f�[�^���d������Ƃ��A�G���[�B + if((hasData(JUMP_ATTACKING_PART_NAME_TAG))&&(hasData(JUMP_WEAPON_FILE_TAG))) + System.out.println("Error!! Weapon & AttackingPart are overlapping."); + + characterList.add(p); + } +} diff --git a/src/main/java/fight3D/CharacterSelectContainer.java b/src/main/java/fight3D/CharacterSelectContainer.java new file mode 100644 index 0000000..477e8f1 --- /dev/null +++ b/src/main/java/fight3D/CharacterSelectContainer.java @@ -0,0 +1,195 @@ +package fight3D; + +import java.awt.Color; +import java.awt.Font; +import java.awt.GraphicsConfiguration; +import java.util.ArrayList; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTLabel; +import framework.RWT.RWTLine; +import framework.RWT.RWTSelectionCanvas3D; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.model3D.BaseObject3D; + +public class CharacterSelectContainer extends RWTContainer { + /** + * + */ + private static final long serialVersionUID = 8354537837334374243L; + + Game game; + + static final int PLAYER_NUM = 2; // ���v���C���[�� + + private RWTSelectionCanvas3D objectCanvas; + private boolean flag = false; // �m�F��ʂ̃t���O + private ArrayList characters = new ArrayList(); + private int pn = 0; + private int character[] = new int[PLAYER_NUM]; + protected RWTLabel activatedLabel = new RWTLabel(); + private RWTLabel s1 = new RWTLabel(); + private RWTLabel s2 = new RWTLabel(); + private RWTLabel m5 = new RWTLabel(); + private RWTLabel m6 = new RWTLabel(); + private RWTLine l1 = new RWTLine(); + private RWTLine l2 = new RWTLine(); + + // �R���X�g���N�^ + public CharacterSelectContainer(Game g) { + game = g; + } + + // �t���[���ɒlj����ăT�C�Y���m�肵����ɒ��g���\�z���� + public void build(GraphicsConfiguration gc) { + // ������ + removeAll(); + setBackground(Color.BLACK); + + // �L�����N�^�[��`�悷�邽�߂̃L�����o�X(���ΓI�L�����o�X)��lj� + objectCanvas = new RWTSelectionCanvas3D(); + objectCanvas.setRelativePosition(0.03f, 0.675f); + objectCanvas.setRelativeSize(0.25f, 0.3f); + addCanvas(objectCanvas); + + //��ʃ^�C�g���A�߂�A�C�R���A���b�Z�[�W�G���A�E�P + s1.setRelativePosition(0.20f,0.10f); + s1.setString("�u�L�����N�^�[�I���v"); + s1.setColor(Color.WHITE); + Font f1 = new Font("",Font.PLAIN,20); + s1.setFont(f1); + addWidget(s1); + + s2.setRelativePosition(0.025f,0.05f); + s2.setString("�a�F�^�C�g����ʂ�"); + s2.setColor(Color.WHITE); + Font f2 = new Font("",Font.PLAIN,8); + s2.setFont(f2); + addWidget(s2); + + m5.setRelativePosition(0.60f,0.05f); + m5.setString((pn+1) + "�o�̓L�����N�^�[��I�����ĉ������B"); + m5.setColor(Color.YELLOW); + addWidget(m5); + m6.setRelativePosition(0.60f,0.10f); + m6.setString("�`�F����"); + m6.setColor(Color.YELLOW); + addWidget(m6); + + //�S�L�����N�^�[�̐� + int n = CharacterManager.getInstance().getNumberOfCharacters(); //�L�����N�^�[�̑��� + //�S�L�����N�^�[�̓o�^ + for(int i=0;i playerList = new ArrayList(); + ArrayList actorList = new ArrayList(); + ArrayList attackableList = new ArrayList(); + FightCalculation fightCalculation = new FightCalculation(); + + Universe universe; + Camera3D camera; + Ground stageGround = null; + + FightListener fightListener; + private boolean isEnd = false; + int rank[]; + int defeated[]; + int defeat[]; + private int tp[]; + private long startTime = 0; + private long leftTime; + + public Fight(RWTCanvas3D canvas, int stagenum, int[] selectedCharacterArray, + FightListener fightListener) { + + this.universe = new Universe(); + this.fightListener = fightListener; + + // �J�����̐ݒ� + camera = new Camera3D(universe); + camera.setSideView(); + canvas.attachCamera(camera); + + // �����̐ݒ� + createLight(universe); + + // �X�e�[�W�̓ǂݍ��� + Stage s = StageManager.getInstance().getStage(stagenum); + Model3D model = s.getModel(); + Object3D stageObj = model.createObject(); + stageGround = new Ground(stageObj); + universe.placeAsAReceiver(stageGround); + RWTCanvas3D c = (RWTCanvas3D) fightListener; + s.setBackgroundSize(new Dimension(c.getWidth(), c.getHeight())); + universe.place(s.getBackground()); + + // �L�����N�^�̒lj��A����̒lj� + for (int i = 0; i < selectedCharacterArray.length; i++) { + Player player = createPlayer(selectedCharacterArray[i]); + player.setPosition(getPlayersPosition(i, selectedCharacterArray.length)); + player.placeTo(universe); + getPlayerList().add(player); + actorList.add(player); + camera.addTarget(player.body); + player.setHp(fightCalculation.initialiseHP()); + player.setGp(fightCalculation.initialiseGP()); + player.setTp(fightCalculation.initialiseTP()); + + } + + universe.compile(); + + leftTime = ENDTIME; + rank = new int[2]; + } + + void createLight(Universe universe){ + //�‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.5f, 0.5f, 0.5f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + //���s���� + DirectionalLight dirlight = new DirectionalLight( + true, //����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), //���̐F + new Vector3f(0.0f, -1.0f, -0.5f) //���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + + universe.placeLight(dirlight); + } + + public Player createPlayer(int id) { + Player player; + Character c = CharacterManager.getInstance().getCharacter(id); + player = new Player(c); + + return player; + } + + public void progress(RWTVirtualController controller, long interval) { + long curTime = System.currentTimeMillis(); + if (startTime == 0) { + startTime = curTime; + } + + // �o�ߎ��Ԃ̌v�Z +// if (count < 2000) speed[count++] = interval; + if (interval > INTERVAL * 3) interval = INTERVAL * 3; + leftTime = (ENDTIME - (curTime - startTime)); + fightListener.update(this); + + // �T���o�߂����� + if (leftTime < 0) { + isEnd = true; + calculateRank(); + calculateDefeated(); + calculateDefeat(); + calculateTP(); + fightListener.update(this); +// for (int i = 0; i < count; i++) { +// System.out.println(speed[i]); +// } + return; + } + + // GP�̎��R�� + for (int i = 0; i < getPlayerList().size(); i++) { + getPlayerList().get(i).recoverGp(); + } + + // �J�����𒲐� + camera.adjust(interval); + + // �L�[���͂����������ǂ������L�^���� + boolean[] flags = new boolean[playerList.size()]; + for (int p = 0; p < flags.length; p++) { + flags[p] = false; + } + for (int playerNum = 0; playerNum < getPlayerList().size(); playerNum++) { + // keys��i�Ԗڂ̒��g�i�L�[���́j���L�����N�^�̂ǂ̓���ɓ��Ă͂܂邩 + if (controller.isKeyDown(playerNum, RWTVirtualController.UP)) { + flags[playerNum] = true; + // �U���{�^���𓯎��ɉ����Ă��Ȃ��ꍇ�W�����v���� + if (!controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_A)) getPlayerList().get(playerNum).startJump(); + } + if (controller.isKeyDown(playerNum, RWTVirtualController.RIGHT)) { + flags[playerNum] = true; + // �U���{�^���𓯎��ɉ����Ă��Ȃ��ꍇ�E�ɓ��� + if (!controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_A)) getPlayerList().get(playerNum).rightMove(); + } + if (controller.isKeyDown(playerNum, RWTVirtualController.LEFT)) { + flags[playerNum] = true; + // �U���{�^���𓯎��ɉ����Ă��Ȃ��ꍇ���ɓ��� + if (!controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_A)) getPlayerList().get(playerNum).leftMove(); + } + if (controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_B)) { + flags[playerNum] = true; + // �U���{�^���������Ă��Ȃ��ꍇ�K�[�h�̃��\�b�h���Ă� + if (!controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_A)) getPlayerList().get(playerNum).guard(); + } + if (controller.isKeyDown(playerNum, RWTVirtualController.BUTTON_A)) { + flags[playerNum] = true; + // �U���̃��\�b�h���Ă� + Attackable a; + Player player = getPlayerList().get(playerNum); + if (!player.isOnGround()) { + if (player.getElapsedTimeInJumping() > 2L || player.getElapsedTimeInJumping() < 0L) { + // �󒆂ɂ���Ƃ��͊�{�I�ɃW�����v�U�� + a = player.startJumpAttack(); + } else { + // �W�����v���Ă����͑΋�U��������悤�ɂ��� + // �i�������Ȃ��Ƒ΋�U�����o�����삪����Ȃ邽�߁j + a = player.startUpperAttack(); + } + } else { + // �n�ʂɂ���Ƃ� + if (controller.isKeyDown(playerNum, RWTVirtualController.UP)) { + // �΋�U�� + a = player.startUpperAttack(); + } else { + // �ʏ�U�� + a = player.startNormalAttack(); + } + } + if (a != null) { + attackableList.add(a); + if (a instanceof Weapon) { + if (a.isMovable()) { + actorList.add((Weapon) a); + } + } + } + } + } + for (int i = 0; i < flags.length; i++) { + if (!flags[i]) { + getPlayerList().get(i).normal(false); + } + } + + // �S�o�ꕨ�𓮂��� + for (int i = 0; i < actorList.size(); i++) { + Actor p = actorList.get(i); + // �ړ� + p.motion(interval, stageGround); + // �͈͊O�ɏo�����ǂ����̔��� + Position3D pos = p.getPosition(); + if (pos.getY() < DEFAULT_AREA_BOTTOM + || pos.getX() > DEFAULT_AREA_RIGHT + || pos.getX() < DEFAULT_AREA_LEFT) { + // �͈͊O�ɏo���Ƃ��̏��� + outOfArea(i); + } + } + + // �U���̓����蔻�� + hitJudg(); + } + + /** + * �͈͊O�ɏo���Ƃ��̏��� + * @param p �Ώە� + */ + private void outOfArea(int index) { + Actor p = actorList.get(index); + if (p instanceof Player) { + playerDefeated(index); + } else if (p instanceof Weapon) { + ((Weapon)p).disappear(); + } + } + + /** + * �U���̓����蔻��ƁA���������Ƃ��̏��� + */ + private void hitJudg() { + // �����蔻�� + for (int i = attackableList.size() - 1; i >= 0; i--) { + + Attackable attack = attackableList.get(i); + if (attack.isAlive() && attack.isActivate()) { + // �U�������L���������ꍇ + for (int j = 0; j < getPlayerList().size(); j++) { + CollisionResult collisionResult = null; + Player attacker = attack.getOwner(); + Player damagedCandidate = getPlayerList().get(j); + + if (attacker != damagedCandidate) { + collisionResult = PhysicsUtility.checkCollision(attack.getBody(), + attack.getPartName(), + (Object3D) damagedCandidate.body, + null); + } + // �Փ˂��������ꍇ + if (collisionResult != null) { + // if (attacker != damagedCandidate) { + + if (damagedCandidate.state.getClass() != StateGuard.class) { + // �_���[�W���󂯂�B + if (damagedCandidate.state.getClass() == StateFlinch.class) { + damagedCandidate.normal(true); + damagedCandidate.setGp(100); + } + damagedCandidate.damaged(attacker.getPosition()); + int afterHP = (int) fightCalculation.decreaseHP(attack + .getAP(), damagedCandidate.getHp(), + damagedCandidate.character.getDefense()); + // �U���ɂ���ăL����������ł��Ȃ��ꍇ + if (fightCalculation.isDead(afterHP) != true) { + damagedCandidate.setHp(afterHP); + // damagedCandidate.changeState(new StateFlinch(), + // false); + } + // ���񂾏ꍇ + else { + // �L�������E�����L�����N�^�́u�|�����񐔁v���P���₷ + attacker.setDefeat(attacker.getDefeat() + 1); + + // �L�������|���ꂽ�Ƃ��̏��� + playerDefeated(j); + } + // �U���ɂ��TP�̏㏸ + int attackerAfterTP = fightCalculation.increaseTP( + attack.getAP(), damagedCandidate.getHp(), + damagedCandidate.character.getDefense(), attacker.getTp()); + attacker.setTp(attackerAfterTP); + } else { + // �_���[�W���󂯂Ȃ��B + int afterGP = (int) fightCalculation.decreaseGP(attack + .getAP(), damagedCandidate.character.getDefense(), damagedCandidate.getGp()); + + if (!fightCalculation.isOver(afterGP)) { + // �U���ɂ����GP���O�ɂȂ�Ȃ������ꍇ + damagedCandidate.setGp(afterGP); + } else { + // �U���ɂ����GP���O�ɂȂ����ꍇ + damagedCandidate.flinch(); + damagedCandidate.setGp(0); + } + } + + // �U�����𖳌��ɂ��� + attack.disappear(); + } + } + } + if (!attack.isAlive()) { + // �U�����������ɂȂ��Ă����ꍇ�A�U�������X�g����폜 + attackableList.remove(i); + for (int j = 0; j < actorList.size(); j++) { + if (actorList.get(j) == attack) { + actorList.remove(j); + break; + } + } + continue; + } + } + } + + /** + * �v���C���[���|���ꂽ�Ƃ��̏��� + * @param index �|���ꂽ�v���C���[�̔ԍ� + */ + private void playerDefeated(int index) { + Player damagedCandidate = getPlayerList().get(index); + + // TP�����炷 + int damagedAfterTP = fightCalculation + .decreaseTP(damagedCandidate.getTp()); + damagedCandidate.setTp(damagedAfterTP); + + // ���񂾃L�����N�^�́u���S�񐔁v���P���₷ + damagedCandidate.setDefeated(damagedCandidate + .getDefeated() + 1); + + // HP��GP�������l�ɖ߂� + damagedCandidate.setHp(fightCalculation + .initialiseHP()); + damagedCandidate.setGp(fightCalculation + .initialiseGP()); + + // �o���ʒu�ɍēo�ꂳ���� + damagedCandidate.setPosition(getPlayersPosition(index, getPlayerList().size())); + } + + /** + * + * �v���C���[�̓o��i�ēo��j�ʒu��Ԃ� + * @param index�@�v���C���[�̔ԍ� + * @param numPlayer �S�v���C���[�̐� + * @return + */ + private Position3D getPlayersPosition(int index, int numPlayer) { + return new Position3D((((double)index / (double)(numPlayer - 1)) - 0.5) * DEFAULT_STAGE_WIDTH, 0.0, 0.0); + } + + private void calculateTP() { + // TODO Auto-generated method stub + tp = new int[playerList.size()]; + for (int i = 0; i < playerList.size(); i++) { + tp[i] = playerList.get(i).getTp(); + } + } + + private void calculateDefeated() { + // TODO Auto-generated method stub + defeated = new int[playerList.size()]; + for (int i = 0; i < playerList.size(); i++) { + defeated[i] = playerList.get(i).getDefeated(); + } + } + + private void calculateDefeat() { + // TODO Auto-generated method stub + defeat = new int[playerList.size()]; + for (int i = 0; i < playerList.size(); i++) { + defeat[i] = playerList.get(i).getDefeat(); + } + } + + private void calculateRank() { + // TODO Auto-generated method stub + + for (int i = 0; i < rank.length; i++) { + int max = 0; + int maxNum = 0; + int playerTp; + for (int j = 0; j < rank.length; j++) { + if (rank[j] == 0 + && max <= (playerTp = getPlayerList().get(j).getTp())) { + max = playerTp; + maxNum = j; + } + } + rank[maxNum] = i + 1; + } + } + + int getRemnantMinute() { + int time = (int) (leftTime / 1000) / 60; + if(time > 0) { + return time; + } + return 0; + } + + int getRemnantSecond() { + int time = (int) (leftTime / 1000) % 60; + if (time > 0) { + return time; + } + return 0; + } + + boolean checkEnd() { + return isEnd; + } + + int[] getRank() { + return rank; + } + + ArrayList getPlayerList() { + return playerList; + } + + int[] getTp() { + return tp; + } + + int[] getDefeated() { + return defeated; + } + + int[] getDefeat() { + return defeat; + } +} \ No newline at end of file diff --git a/src/main/java/fight3D/FightCalculation.java b/src/main/java/fight3D/FightCalculation.java new file mode 100644 index 0000000..fe8850f --- /dev/null +++ b/src/main/java/fight3D/FightCalculation.java @@ -0,0 +1,84 @@ +package fight3D; + +public class FightCalculation { + static final int MAX_HP = 100; + static final int MIN_HP = 0; + static final int MAX_TP = 999; + static final int MIN_TP = 0; + static final int MAX_GP = 100; + static final int MIN_GP = 0; + + int initialiseHP(){ + return MAX_HP; + } + + + int initialiseTP(){ + return MIN_TP; + } + + + int initialiseGP(){ + return MAX_GP; + } + + + int decreaseHP(int enemiesAP,int myHP,int myDP){ + int afterHP = 0; + afterHP = myHP - (enemiesAP*2 - myDP); + if(afterHPMAX_TP){ + afterTP = MAX_TP; + } + return afterTP; + } + + + int decreaseTP(int myTP){ + return myTP/2; + } + + + int increaseGP(int myGP){ + int afterGP = 0; + afterGP = myGP+1; + if(myGP>MAX_GP){ + myGP =MAX_GP; + } + return afterGP; + } + + + int decreaseGP(int enemiesAP,int myDP,int myGP){ + int afterGP = 0; + afterGP = myGP - (enemiesAP*2 - myDP); + if(afterGP getPosition().getX()) { + body.apply(new Quaternion3D(0.0, 1.0, 0.0, 0), false); + lastMoveState = stateRightMove; + } else { + body.apply(new Quaternion3D(0.0, 1.0, 0.0, Math.PI), false); + lastMoveState = stateLeftMove; + } + State s = stateDamaged; + changeState(s, false); + } + + void setHp(int hp) { + this.hp = hp; + } + + int getHp() { + return hp; + } + + void setTp(int tp) { + this.tp = tp; + } + + int getTp() { + return tp; + } + + void setGp(int gp) { + this.gp = gp; + } + + int getGp() { + return gp; + } + + void recoverGp() { + if (state.getClass() == StateGuard.class) { + gpCounter = 0; + return; + } + gpCounter++; + if (gpCounter < 20) { + return; + } + gpCounter = 0; + if (FightCalculation.MIN_GP < gp && gp < FightCalculation.MAX_GP) { + this.gp += 1; + } else if (gp >= FightCalculation.MAX_GP) { + gp = FightCalculation.MAX_GP; + } + } + + void setDefeat(int defeat) { + this.defeat = defeat; + } + + int getDefeat() { + return defeat; + } + + void setDefeated(int defeated) { + this.defeated = defeated; + } + + int getDefeated() { + return defeated; + } + + /** + * �W�����v���J�n���Ă���̌o�ߎ��ԁi���[�v�񐔁j��Ԃ��A + * �W�����v��ԂɂȂ��Ƃ��� -1 ��Ԃ� + * @return �o�ߎ��� + */ + public long getElapsedTimeInJumping() { + if (state instanceof StateJump) { +// System.out.println(state.getCounter()); + return state.getCounter(); + } +// System.out.println(-1); + return -1L; + } + + private void setGuardVisible(double j) { + // TODO Auto-generated method stub + Transform3D t = new Transform3D(); + t.setScale(j); + guardScale.setTransform(t); + } + + private void setGuardInvisible() { + // TODO Auto-generated method stub + Transform3D t = new Transform3D(); + t.setScale(0.01); + guardScale.setTransform(t); + + } + + private void setGuardScale(int i) { + double j = 0; + if (i > 0) { + j = 1.5 * (i / 100.0); + setGuardVisible(j); + } else { + setGuardInvisible(); + } + } +} diff --git a/src/main/java/fight3D/Ranking1Container.java b/src/main/java/fight3D/Ranking1Container.java new file mode 100644 index 0000000..09a9d21 --- /dev/null +++ b/src/main/java/fight3D/Ranking1Container.java @@ -0,0 +1,112 @@ +package fight3D; + +import java.awt.Color; +import java.awt.Font; +import java.awt.GraphicsConfiguration; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTLabel; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; + + +public class Ranking1Container extends RWTContainer { + private static final long serialVersionUID = 883828261190427156L; + + private Game game; + + public Ranking1Container(Game g) { + game = g; + } + + public void build(GraphicsConfiguration gc) { + // ������ + removeAll(); + + int character[] = game.getCharacter(); + int rank[] = game.getRank(); + + //�P�ʕ\�� + int i; + for(i=0 ; i effectList = new ArrayList(); + + private BufferedImage image; + + //�R���X�g���N�^ + public Stage(String fileName) { + super(fileName); + // TODO Auto-generated constructor stub + } + + //�X�e�[�W�� + public void setName(String n){ + name = n; + } + public String getName(){ + return name; + } + + //�w�i + public void setBackground(String fileName){ + try { + image = ImageIO.read(new File(fileName)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void setBackgroundSize(Dimension size){ + double scalew = (double)size.width/image.getWidth(); + double scaleh = (double)size.height/image.getHeight(); + AffineTransformOp atOp = new AffineTransformOp(AffineTransform.getScaleInstance(scalew, scaleh), AffineTransformOp.TYPE_BILINEAR); + + BufferedImage img = new BufferedImage(size.width, size.height, image.getType()); + atOp.filter(image, img); + image = img; + } + + public Background getBackground() { + Background background = new Background(); + ImageComponent2D imageCompornent = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, image); + background.setImage(imageCompornent); + BoundingSphere bs = new BoundingSphere(); + bs.setRadius(100); + background.setApplicationBounds(bs); + + return background; + } + + //�X�e�[�W�̐��� + public void setComment(String comment) { + this.comment = comment; + } + public String getComment() { + return comment; + } + + //�X�e�[�W�̓�Փx +// public void setLevel(int level) { +// this.level = level; +// } +// public int getLevel() { +// return level; +// } + +// //�X�e�[�W�̑傫�� +// public void setSize(int size) { +// this.size = size; +// } +// public int getSize() { +// return size; +// } + + //������ʂ����ƒX�e�[�W�� + public void addEffect(StageEffect effect){ + effectList.add(effect); + } + + public ArrayList getEffectList() { + return effectList; + } +} diff --git a/src/main/java/fight3D/StageEffect.java b/src/main/java/fight3D/StageEffect.java new file mode 100644 index 0000000..3b49d10 --- /dev/null +++ b/src/main/java/fight3D/StageEffect.java @@ -0,0 +1,59 @@ +package fight3D; +import javax.vecmath.Point3d; + + +public class StageEffect { + + private Point3d p1 = new Point3d(); + private Point3d p2 = new Point3d(); + private String effect; + + //�X�e�[�W�́A������ʂ̂���ʒu + public void setPositions(Point3d p1, Point3d p2) { + this.p1 = p1; + this.p2 = p2; + } + + public Point3d[] getPositions(){ + Point3d[] p = {p1, p2}; + return p; + } + + //�X�e�[�W�̎��“������ + public void setEffect(String e){ + effect = e; + } + public String getEffect(){ + return effect; + } + + /** + * ���̃|�C���g��effect�G���A�ɓ����Ă邩�ǂ����B + * @param p + * @return + */ + public boolean isIncluded(Point3d p){ + if(isIncluded(p.x, p1.x, p2.x) && isIncluded(p.y, p1.y, p2.y) && isIncluded(p.z, p1.z, p2.z)){ + return true; + } + else{ + return false;} + } + + /** + * x��p1��p2�̊Ԃɓ����Ă邩�ǂ����B + * @param x + * @param p1 + * @param p2 + * @return + */ + private boolean isIncluded(double x, double p1, double p2) { + if((x-p1)*(x-p2) <= 0) { + return true; + } + else { + return false; + } + } + +} diff --git a/src/main/java/fight3D/StageManager.java b/src/main/java/fight3D/StageManager.java new file mode 100644 index 0000000..697f8f2 --- /dev/null +++ b/src/main/java/fight3D/StageManager.java @@ -0,0 +1,121 @@ +package fight3D; + +import java.util.ArrayList; + +import javax.vecmath.Point3d; + +import framework.gameMain.AbstractManager; + +public class StageManager extends AbstractManager{ + private String filename= "data"; + private static StageManager theInstance = null; + + private static String stageFile = "stage.def"; + + //�X�e�[�W�̃f�[�^�^�O + private static final String NAME_TAG = "Name"; + private static final String MODELFILE_TAG = "ModelFile"; + private static final String BACKGROUNDFILE_TAG = "BackgroundFile"; + private static final String COMMENT_TAG = "Comment"; + private static final String EFFECT_TAG = "Effect"; + private ArrayList stageList = new ArrayList(); + + /** + *�R���X�g���N�^ + */ + private StageManager(){ + addSeekFile(stageFile); + setTag(NAME_TAG); + setTag(MODELFILE_TAG); + setTag(BACKGROUNDFILE_TAG); + setTag(COMMENT_TAG); + setTag(EFFECT_TAG); + seek(filename); + } + public static StageManager getInstance(){ + if(theInstance == null){ + theInstance = new StageManager(); + } + return theInstance; + } + + /** + * Stage��ArrayList��Ԃ��܂� + * @return + */ + public ArrayList getStageList(){ + return stageList; + } + + /** + * �w�肳�ꂽStage��Ԃ��܂��B + * @param id�@ Stage number + * @return + */ + public Stage getStage(int id){ + if(id stages; + private RWTLabel title = new RWTLabel(); + private RWTLabel back = new RWTLabel(); + private RWTLabel message1 = new RWTLabel(); + private RWTLabel message2 = new RWTLabel(); + private RWTLine line1 = new RWTLine(); + private RWTLine line2 = new RWTLine(); + + public StageSelectContainer(Game g) { + game = g; + } + + // �t���[���ɒlj����ăT�C�Y���m�肵����ɒ��g���\�z���� + public void build(GraphicsConfiguration gc) { + // ������ + removeAll(); + setBackground(Color.BLACK); + + // �I�������X�e�[�W��`�悷�邽�߂̃L�����o�X��lj� + objectCanvas = new RWTSelectionCanvas3D(); + objectCanvas.setRelativePosition(0.03f, 0.675f); + objectCanvas.setRelativeSize(0.25f, 0.30f); + addCanvas(objectCanvas); + + stages = StageManager.getInstance().getStageList(); + + // �^�C�g���E�߂�A�C�R���E���b�Z�[�W�G���A�̕`�� + title.setString("��X�e�[�W�I��"); + title.setColor(Color.white); + title.setFont(new Font("", Font.PLAIN, 20)); + title.setRelativePosition(0.20f, 0.10f); + addWidget(title); + + back.setString("B:��׸���I����ʂ�"); + back.setColor(Color.white); + back.setFont(new Font("", Font.PLAIN, 8)); + back.setRelativePosition(0.025f, 0.05f); + addWidget(back); + + message1.setRelativePosition(0.60f, 0.05f); + message1.setString("�X�e�[�W��I�����ĉ������B"); + message1.setColor(Color.YELLOW); + addWidget(message1); + message2.setRelativePosition(0.60f, 0.10f); + message2.setString("�`�F����"); + message2.setColor(Color.YELLOW); + addWidget(message2); + + // �X�e�[�W�̕`�� + for (int i = 0; i < stages.size(); i++) { + String str = stages.get(i).getName() + RWTLabel.NEW_PARAGRAPH + + stages.get(i).getComment(); + StageSelectImageButton stage = new StageSelectImageButton(str, + stages.get(i).getModel(), activatedLabel, i, this); + stage.setString(stages.get(i).getName()); + stage.setColor(Color.white); + stage.setRelativePosition(0.10f + i % 3 * 0.3f, (i / 3 + 1) * 0.3f); + addSelectableWidget(stage, i % 3, i / 3); + } + + // �I�����ꂽ�X�e�[�W�̐������̕`�� + addWidget(activatedLabel); + + // ��ʕ������C���̕`�� + line1.setColor(Color.white); + line1.setRelativePosition(0.00f, 0.15f, 1.00f, 0.15f); + addWidget(line1); + + line2.setColor(Color.white); + line2.setRelativePosition(0.00f, 0.65f, 1.00f, 0.65f); + addWidget(line2); + + repaint(); + } + + public void updateObjectCanvas(BaseObject3D o) { + if (objectCanvas != null) objectCanvas.setObject(o); + } + + @Override + public void keyPressed(RWTVirtualKey key) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(RWTVirtualKey key) { + // TODO Auto-generated method stub + + if (key.getVirtualKey() == RWTVirtualController.BUTTON_A) { + // �m�F��� + setConfirmMessage(); + repaint(); + + if (goFight == true) { + // �I�����ꂽ�X�e�[�W�̓o�^ + StageSelectImageButton activeWidget; + activeWidget = (StageSelectImageButton) getSelectedWidget(); + game.setStage(activeWidget.number); + + game.goNextGameState(); + } + goFight = true; + } + + if (key.getVirtualKey() == RWTVirtualController.BUTTON_B) { + if (goFight == true) { + initializeMessage(); + repaint(); + goFight = false; + } else { + game.goPrevGameState(); + } + } + + if (key.getVirtualKey() == RWTVirtualController.RIGHT) { + cursorMoveRight(); + + } + if (key.getVirtualKey() == RWTVirtualController.LEFT) { + cursorMoveLeft(); + } + } + + @Override + public void keyTyped(RWTVirtualKey key) { + // TODO Auto-generated method stub + + } + + // �X�e�[�W��I�񂾍ۂ̃��x���̏����������� + private void setConfirmMessage() { + back.setString(""); + message1.setString("����ł�낵���ł����B"); + message2.setString("�`�F����@�a�F�߂�"); + } + + // �X�e�[�W��I�тȂ������ۂ̃��x���̏����������� + private void initializeMessage() { + back.setString("B:��׸���I����ʂ�"); + message1.setString("�X�e�[�W��I�����ĉ������B"); + message2.setString("�`�F����"); + } +} diff --git a/src/main/java/fight3D/StageSelectImageButton.java b/src/main/java/fight3D/StageSelectImageButton.java new file mode 100644 index 0000000..4ba64cd --- /dev/null +++ b/src/main/java/fight3D/StageSelectImageButton.java @@ -0,0 +1,59 @@ +package fight3D; + +import java.awt.Color; + +import framework.RWT.RWTLabel; +import framework.RWT.RWTSelectableWidget; +import framework.model3D.Model3D; + +public class StageSelectImageButton extends RWTLabel implements RWTSelectableWidget { + private RWTLabel label; + protected int number = 0; + private String comment; + StageSelectContainer container; + Model3D model; + + public StageSelectImageButton(String str, Model3D m, RWTLabel activeLabel, + int i, StageSelectContainer c) { + comment = str; + model = m; + label = activeLabel; + number = i; + container = c; + } + + @Override + public void selected() { + // �A�N�e�B�u�ȃL�����N�^�̖��O�������\�� + label.setString(comment); + label.setColor(Color.WHITE); + label.setRelativePosition(0.35f, 0.75f); + + // �A�N�e�B�u�ȃL�����N�^�̃I�u�W�F�N�g��ݒ� + container.updateObjectCanvas(model.createObject()); + } + + @Override + public void deselected() { + } + + @Override + public int getAbsoluteHeight() { + return super.getAbsoluteHeight(); + } + + @Override + public int getAbsoluteWidth() { + return super.getAbsoluteWidth(); + } + + @Override + public int getAbsoluteX() { + return super.getAbsoluteX(); + } + + @Override + public int getAbsoluteY() { + return super.getAbsoluteY(); + } +} diff --git a/src/main/java/fight3D/StageSelectState.java b/src/main/java/fight3D/StageSelectState.java new file mode 100644 index 0000000..e390d06 --- /dev/null +++ b/src/main/java/fight3D/StageSelectState.java @@ -0,0 +1,28 @@ +package fight3D; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTVirtualController; +import framework.gameMain.AbstractGameState; + +public class StageSelectState extends AbstractGameState { + + Game game; + + StageSelectState(Game g) { + this.game = g; + } + + @Override + public RWTContainer createContainer() { + return new StageSelectContainer(game); + } + + @Override + public void update(RWTVirtualController controller, long interval) { + } + + @Override + public boolean useTimer() { + return false; + } +} diff --git a/src/main/java/fight3D/State.java b/src/main/java/fight3D/State.java new file mode 100644 index 0000000..cce4521 --- /dev/null +++ b/src/main/java/fight3D/State.java @@ -0,0 +1,56 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + + +public abstract class State { + protected long counter = 0; // ���̏�Ԃɐ؂�ւ���Ă��牽���[�v�ڂ��H + + public void init() { + counter = 0; + } + + public void countUp() { + counter++; + } + + public long getCounter() { + return counter; + } + + /** + * ���x��Ԃ� + * @param curVelocity ���݂̑��x + * @param mode ���݂̃��[�h + * @return ���̏u�Ԃ̑��x + */ + public Velocity3D getVelocity(Velocity3D curVelocity, Mode mode) { + if (counter == 0) { + // �ŏ��̏u�Ԃ��������x��Ԃ� + return getInitialVelocity(); + } + return null; + } + + /** + * �������玟�̏�ԂɑJ�ډ”\���ۂ���Ԃ� + * @param nextState ���̏�� + * @param mode ���݂̃��[�h�i�󒆂ɑ؍݂��Ă��邩�n��ɂ��邩�j + * @return true --- �J�ډ”\, false --- �J�ڕs�”\ + */ + public abstract boolean canChange(State nextState, Mode mode); + + + /** + * �����i�p���j�”\�ȏ�Ԃ�1�����Ō��ɖ߂��Ԃ� + * @return true --- �����i�p���j�”\�ȏ��, false --- 1�����Ō��ɖ߂��� + */ + public abstract boolean isRepeatable(); + + /** + * �����x��Ԃ� + * @return �����x + */ + public abstract Velocity3D getInitialVelocity(); + +} diff --git a/src/main/java/fight3D/StateAttack.java b/src/main/java/fight3D/StateAttack.java new file mode 100644 index 0000000..849399a --- /dev/null +++ b/src/main/java/fight3D/StateAttack.java @@ -0,0 +1,25 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + +//�U�� +public class StateAttack extends StateOnce { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + public boolean canChange(State nextState, Mode mode) { + if (nextState instanceof StateAttack) return false; + if (nextState instanceof StateUpperAttack) return false; + if (nextState instanceof StateJumpAttack) return false; + if (nextState instanceof StateNormalLeft) return false; + if (nextState instanceof StateNormalRight) return false; + + if(nextState instanceof StateFlinch) return true; + if(nextState instanceof StateDamaged) return true; + + return false; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } +} diff --git a/src/main/java/fight3D/StateBend.java b/src/main/java/fight3D/StateBend.java new file mode 100644 index 0000000..7eeffff --- /dev/null +++ b/src/main/java/fight3D/StateBend.java @@ -0,0 +1,31 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.gameMain.ModeOnGround; +import framework.physics.Velocity3D; + +//���Ⴊ�� +public class StateBend extends StateRepeatable { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + public boolean canChange(State nextState, Mode mode) { + + //�ʏ� + if(mode instanceof ModeOnGround) { + if(nextState instanceof StateAttack) return false; + if(nextState instanceof StateUpperAttack) return false; + if(nextState instanceof StateJumpAttack) return false; + if(nextState instanceof StateGuard) return false; + if(nextState instanceof StateJump) return false; + if(nextState instanceof StateLeftMove) return false; + if(nextState instanceof StateRightMove) return false; + } + + //������ + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + +} diff --git a/src/main/java/fight3D/StateDamaged.java b/src/main/java/fight3D/StateDamaged.java new file mode 100644 index 0000000..1c49d8c --- /dev/null +++ b/src/main/java/fight3D/StateDamaged.java @@ -0,0 +1,19 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + + +public class StateDamaged extends StateOnce { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + @Override + public boolean canChange(State nextState, Mode mode) { + return false; + } + + @Override + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + +} diff --git a/src/main/java/fight3D/StateFlinch.java b/src/main/java/fight3D/StateFlinch.java new file mode 100644 index 0000000..cb301d8 --- /dev/null +++ b/src/main/java/fight3D/StateFlinch.java @@ -0,0 +1,33 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.physics.Velocity3D; + +//�Ђ�� +public class StateFlinch extends StateOnce { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + @Override + public boolean canChange(State nextState, Mode mode) { + // TODO Auto-generated method stub + if (nextState instanceof StateDamaged) return true; + + //�ʏ� + if(mode instanceof ModeOnGround) { + + } + + //������ + if(mode instanceof ModeFreeFall) { + + } + + return false; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + +} diff --git a/src/main/java/fight3D/StateGuard.java b/src/main/java/fight3D/StateGuard.java new file mode 100644 index 0000000..b5813bf --- /dev/null +++ b/src/main/java/fight3D/StateGuard.java @@ -0,0 +1,27 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + + +public class StateGuard extends StateRepeatable { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + public boolean canChange(State nextState, Mode mode) { + + if(nextState instanceof StateAttack) return false; + if(nextState instanceof StateUpperAttack) return false; + if(nextState instanceof StateJumpAttack) return false; + if(nextState instanceof StateBend) return false; + // if(nextState instanceof StateFlinch) return false; + if(nextState instanceof StateJump) return false; + if(nextState instanceof StateLeftMove) return false; + if(nextState instanceof StateRightMove) return false; + + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + +} diff --git a/src/main/java/fight3D/StateJump.java b/src/main/java/fight3D/StateJump.java new file mode 100644 index 0000000..5ce3133 --- /dev/null +++ b/src/main/java/fight3D/StateJump.java @@ -0,0 +1,37 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.physics.Velocity3D; + + +public class StateJump extends StateOnce { + private Velocity3D initialVelocity = new Velocity3D(0.0, 10.0, 0.0); + + void setSpeed(double speed) { + initialVelocity.setY(speed); + } + + public boolean canChange(State nextState, Mode mode) { + if(mode instanceof ModeOnGround) { + if(nextState instanceof StateNormalRight) return true; + else if(nextState instanceof StateNormalLeft) return true; + } + if(mode instanceof ModeFreeFall) { + //������ + if(nextState instanceof StateJumpAttack) return true; + if(nextState instanceof StateUpperAttack) return true; // �W�����v��������͑΋�U�����ł���i���쐫��̗��R�j + if(nextState instanceof StateFlinch) return true; + if(nextState instanceof StateLeftMove) return true; + if(nextState instanceof StateRightMove) return true; + if(nextState instanceof StateGuard) return true; + if(nextState instanceof StateNormalRight) return true; + if(nextState instanceof StateNormalLeft) return true; + } + return false; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } +} diff --git a/src/main/java/fight3D/StateJumpAttack.java b/src/main/java/fight3D/StateJumpAttack.java new file mode 100644 index 0000000..ed7e1c4 --- /dev/null +++ b/src/main/java/fight3D/StateJumpAttack.java @@ -0,0 +1,28 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + + +public class StateJumpAttack extends StateOnce { + + @Override + public boolean canChange(State nextState, Mode mode) { + if (nextState instanceof StateAttack) return false; + if (nextState instanceof StateUpperAttack) return false; + if (nextState instanceof StateJumpAttack) return false; + if (nextState instanceof StateNormalLeft) return false; + if (nextState instanceof StateNormalRight) return false; + + if(nextState instanceof StateFlinch) return true; + if(nextState instanceof StateDamaged) return true; + + return false; + } + + @Override + public Velocity3D getInitialVelocity() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/main/java/fight3D/StateLeftMove.java b/src/main/java/fight3D/StateLeftMove.java new file mode 100644 index 0000000..f7df430 --- /dev/null +++ b/src/main/java/fight3D/StateLeftMove.java @@ -0,0 +1,56 @@ +package fight3D; + +import javax.vecmath.Vector3d; + +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; + + +public class StateLeftMove extends StateRepeatable { + private Velocity3D initialVelocity = new Velocity3D(-5.0, 0.0, 0.0); + + void setSpeed(double speed) { + initialVelocity.setX(-speed); + } + + public boolean canChange(State nextState, Mode mode) { + if(mode instanceof ModeFreeFall) { + //������ + if(nextState instanceof StateBend) return false; + if(nextState instanceof StateGuard) return false; + if(nextState instanceof StateJump) return false; + } + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + + public Velocity3D getVelocity(Velocity3D curVelocity, Mode mode) { + if (mode instanceof ModeOnGround) { + // �n�ʂ̌����ɉ����悤�ɑ��x�x�N�g���̌�����ς��� + // �i�n�������Ă���Ƃ��̓A�j���[�V�����Ȃǂ̉e���ő��x���ς��”\��������̂ŁA��ԕω����Ȃ��Ă��������x��ݒ肵������j + ModeOnGround modeOnGround = (ModeOnGround)mode; + Vector3d v = getInitialVelocity().getVector3d(); + double d = v.dot(modeOnGround.getNormal()); + v.scaleAdd(-d, modeOnGround.getNormal(), v); + return new Velocity3D(v); + } + // �󒆂ɑ؍݂��Ă���ꍇ�͐��������̑��x���������ύX����i���R�����ɂ͉e����^���Ȃ��悤�Ɂj + if (counter == 0) { + // �󒆂̏ꍇ�A���������ɉ��������邱�Ƃ͂Ȃ��̂ŁA���x��ݒ肷��̂͏���݂̂ł��� + Vector3d v0 = curVelocity.getVector3d(); + Vector3d v1 = getInitialVelocity().getVector3d(); + v0.add(v1); + double d0 = v0.dot(PhysicsUtility.horizon); + double d1 = v1.dot(PhysicsUtility.horizon); + v0.scaleAdd(d1 - d0, PhysicsUtility.horizon, v0); + return new Velocity3D(v0); + } + return null; + } +} diff --git a/src/main/java/fight3D/StateNormalLeft.java b/src/main/java/fight3D/StateNormalLeft.java new file mode 100644 index 0000000..916a0ba --- /dev/null +++ b/src/main/java/fight3D/StateNormalLeft.java @@ -0,0 +1,50 @@ +package fight3D; + +import javax.vecmath.Vector3d; + +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.model3D.GeometryUtility; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; + + +public class StateNormalLeft extends StateRepeatable { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + public boolean canChange(State nextState, Mode mode) { + if(mode instanceof ModeFreeFall){ + //������ + if(nextState instanceof StateBend) return false; + if(nextState instanceof StateGuard) return false; + if(nextState instanceof StateJump) return false; + } + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + + public Velocity3D getVelocity(Velocity3D curVelocity, Mode mode) { + if (mode instanceof ModeOnGround) { + if (curVelocity.getVector3d().length() <= GeometryUtility.TOLERANCE) return null; + // �������Ă��ĎΖʂɏՓ˂�����A�Ζʂ����ׂ��Ă����Ȃ��悤�Ɏ~�߂� + return getInitialVelocity(); + } + // �󒆂ɑ؍݂��Ă���ꍇ�͐��������̑��x���������ύX����i���R�����ɂ͉e����^���Ȃ��悤�Ɂj + if (counter == 0) { + // ���̏�Ԃɕς�����u�� + Vector3d v0 = curVelocity.getVector3d(); + Vector3d v1 = getInitialVelocity().getVector3d(); + v0.add(v1); + double d0 = v0.dot(PhysicsUtility.horizon); + double d1 = v1.dot(PhysicsUtility.horizon); + v0.scaleAdd(d1 - d0, PhysicsUtility.horizon, v0); + if (v0.y >= 0.0) v0.y = 0.0; // �������㏸���͗������u�Ԃɗ������J�n���� + return new Velocity3D(v0); + } + return null; + } +} diff --git a/src/main/java/fight3D/StateNormalRight.java b/src/main/java/fight3D/StateNormalRight.java new file mode 100644 index 0000000..c1b3cac --- /dev/null +++ b/src/main/java/fight3D/StateNormalRight.java @@ -0,0 +1,50 @@ +package fight3D; + +import javax.vecmath.Vector3d; + +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.model3D.GeometryUtility; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; + + +public class StateNormalRight extends StateRepeatable { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + public boolean canChange(State nextState, Mode mode) { + if(mode instanceof ModeFreeFall){ + //������ + if(nextState instanceof StateBend) return false; + if(nextState instanceof StateGuard) return false; + if(nextState instanceof StateJump) return false; + } + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + + public Velocity3D getVelocity(Velocity3D curVelocity, Mode mode) { + if (mode instanceof ModeOnGround) { + if (curVelocity.getVector3d().length() <= GeometryUtility.TOLERANCE) return null; + // �������Ă��ĎΖʂɏՓ˂�����A�Ζʂ����ׂ��Ă����Ȃ��悤�Ɏ~�߂� + return getInitialVelocity(); + } + // �󒆂ɑ؍݂��Ă���ꍇ�͐��������̑��x���������ύX����i���R�����ɂ͉e����^���Ȃ��悤�Ɂj + if (counter == 0) { + // ���̏�Ԃɕς�����u�� + Vector3d v0 = curVelocity.getVector3d(); + Vector3d v1 = getInitialVelocity().getVector3d(); + v0.add(v1); + double d0 = v0.dot(PhysicsUtility.horizon); + double d1 = v1.dot(PhysicsUtility.horizon); + v0.scaleAdd(d1 - d0, PhysicsUtility.horizon, v0); + if (v0.y >= 0.0) v0.y = 0.0; // �������㏸���͗������u�Ԃɗ������J�n���� + return new Velocity3D(v0); + } + return null; + } +} diff --git a/src/main/java/fight3D/StateOnce.java b/src/main/java/fight3D/StateOnce.java new file mode 100644 index 0000000..1b7c55d --- /dev/null +++ b/src/main/java/fight3D/StateOnce.java @@ -0,0 +1,10 @@ +package fight3D; + +public abstract class StateOnce extends State { + + public boolean isRepeatable() { + + return false; + } + +} diff --git a/src/main/java/fight3D/StateRepeatable.java b/src/main/java/fight3D/StateRepeatable.java new file mode 100644 index 0000000..750509c --- /dev/null +++ b/src/main/java/fight3D/StateRepeatable.java @@ -0,0 +1,10 @@ +package fight3D; + +public abstract class StateRepeatable extends State { + + public boolean isRepeatable() { + + return true; + } + +} diff --git a/src/main/java/fight3D/StateRightMove.java b/src/main/java/fight3D/StateRightMove.java new file mode 100644 index 0000000..b9e9333 --- /dev/null +++ b/src/main/java/fight3D/StateRightMove.java @@ -0,0 +1,56 @@ +package fight3D; + +import javax.vecmath.Vector3d; + +import framework.gameMain.Mode; +import framework.gameMain.ModeFreeFall; +import framework.gameMain.ModeOnGround; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; + + +public class StateRightMove extends StateRepeatable { + private Velocity3D initialVelocity = new Velocity3D(5.0, 0.0, 0.0); + + void setSpeed(double speed) { + initialVelocity.setX(speed); + } + + public boolean canChange(State nextState, Mode mode) { + if(mode instanceof ModeFreeFall) { + //������ + if(nextState instanceof StateBend) return false; + if(nextState instanceof StateGuard) return false; + if(nextState instanceof StateJump) return false; + } + return true; + } + + public Velocity3D getInitialVelocity() { + return initialVelocity; + } + + public Velocity3D getVelocity(Velocity3D curVelocity, Mode mode) { + if (mode instanceof ModeOnGround) { + // �n�ʂ̌����ɉ����悤�ɑ��x�x�N�g���̌�����ς��� + // �i�n�������Ă���Ƃ��̓A�j���[�V�����Ȃǂ̉e���ő��x���ς��”\��������̂ŁA��ԕω����Ȃ��Ă��������x��ݒ肵������j + ModeOnGround modeOnGround = (ModeOnGround)mode; + Vector3d v = getInitialVelocity().getVector3d(); + double d = v.dot(modeOnGround.getNormal()); + v.scaleAdd(-d, modeOnGround.getNormal(), v); + return new Velocity3D(v); + } + // �󒆂ɑ؍݂��Ă���ꍇ�͐��������̑��x���������ύX����i���R�����ɂ͉e����^���Ȃ��悤�Ɂj + if (counter == 0) { + // �󒆂̏ꍇ�A���������ɉ��������邱�Ƃ͂Ȃ��̂ŁA���x��ݒ肷��̂͏���݂̂ł��� + Vector3d v0 = curVelocity.getVector3d(); + Vector3d v1 = getInitialVelocity().getVector3d(); + v0.add(v1); + double d0 = v0.dot(PhysicsUtility.horizon); + double d1 = v1.dot(PhysicsUtility.horizon); + v0.scaleAdd(d1 - d0, PhysicsUtility.horizon, v0); + return new Velocity3D(v0); + } + return null; + } +} diff --git a/src/main/java/fight3D/StateUpperAttack.java b/src/main/java/fight3D/StateUpperAttack.java new file mode 100644 index 0000000..4d7f069 --- /dev/null +++ b/src/main/java/fight3D/StateUpperAttack.java @@ -0,0 +1,29 @@ +package fight3D; +import framework.gameMain.Mode; +import framework.physics.Velocity3D; + + +public class StateUpperAttack extends StateOnce { + static final Velocity3D initialVelocity = new Velocity3D(0.0, 0.0, 0.0); + + @Override + public boolean canChange(State nextState, Mode mode) { + if (nextState instanceof StateAttack) return false; + if (nextState instanceof StateUpperAttack) return false; + if (nextState instanceof StateJumpAttack) return false; + if (nextState instanceof StateNormalLeft) return false; + if (nextState instanceof StateNormalRight) return false; + + if(nextState instanceof StateFlinch) return true; + if(nextState instanceof StateDamaged) return true; + + return false; + } + + @Override + public Velocity3D getInitialVelocity() { + // �W�����v�J�n����͑΋�U�����ł���̂ŁA���̏ꍇ�̓W�����v�𒆒f����i����������j + return initialVelocity; + } + +} diff --git a/src/main/java/fight3D/Weapon.java b/src/main/java/fight3D/Weapon.java new file mode 100644 index 0000000..24268e0 --- /dev/null +++ b/src/main/java/fight3D/Weapon.java @@ -0,0 +1,132 @@ +package fight3D; + +import framework.gameMain.Actor; +import framework.model3D.CollisionResult; +import framework.model3D.Object3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; + + +/** + * ��ѓ���A�e + * @author �V�c���� + * + */ +public class Weapon extends Actor implements Attackable { + private Player owner; + private boolean fCalculatePhysics = false; + boolean fActive = true; + long lifetime; + private long timeLag = 0; // �U���������n�߂�܂ł̎��ԁi�������ԁj + + public Weapon(WeaponModel m, Player owner, long t) { + super(m); + this.owner = owner; + lifetime = 10000; + timeLag = t; + disappear(); + } + + public void motion(long interval, Ground ground){ + + if(doesCalculatePhysics()){ + lifetime = lifetime -interval; + if(lifetime <= 0){ + disappear(); + } + } + super.motion(interval, ground); + } + + public void appear(){ + fActive = true; + setVisible(); + } + + public void disappear() { + fActive = false; + setInvisible(); + } + + //�������U���̒����^��������̂������^��������̂��𔻒� + public boolean doesCalculatePhysics(){ + + return fCalculatePhysics; + } + + public boolean isAlive(){ + return fActive; + } + + //�U���͂������� + public int getAP() { + // TODO Auto-generated method stub + return owner.character.getPower(); + } + + //2�‚̕��̂�������Ƃ��̂R�����̌`���������� + public Object3D getBody() { + // TODO Auto-generated method stub + return body; + } + + @Override + public String getPartName() { + // TODO Auto-generated method stub + return null; + } + + //�N��Weapon�����������̂����肷�� + public Player getOwner() { + // TODO Auto-generated method stub + return owner; + } + + //Player�ƓƗ���������������̂��ǂ�������iWeapon�ł͓Ɨ�����������������j + public boolean isMovable() { + // TODO Auto-generated method stub + return true; + } + + public void onEndAnimation() { + } + + public void onEndFall(){ + } + + //Weapon���n�ʂɓ��������Ƃ��ɂǂ��������������邩 + public void onIntersect(CollisionResult cr, long interval) { + // TODO Auto-generated method stub + if(doesCalculatePhysics()){ + Force3D f = PhysicsUtility.calcForce(interval, cr.normal, (Solid3D)body); + ((Solid3D)body).move(interval, f, cr.collisionPoint); + } + else{ + disappear(); + } + } + + public Force3D getGravity() { + if (doesCalculatePhysics()) { + return super.getGravity(); + } + return Force3D.ZERO; + } + + private void setVisible(){ + animation.reset(); + body.scale(1.0); + } + + private void setInvisible(){ + body.apply(owner.getPosition(), false); + body.scale(0.01); + } + + @Override + public boolean isActivate() { + return (animation.time >= timeLag); + } +} diff --git a/src/main/java/fight3D/WeaponModel.java b/src/main/java/fight3D/WeaponModel.java new file mode 100644 index 0000000..9ab83e2 --- /dev/null +++ b/src/main/java/fight3D/WeaponModel.java @@ -0,0 +1,17 @@ +package fight3D; +import framework.animation.Animation3D; +import framework.gameMain.ActorModel; + + +public class WeaponModel extends ActorModel { + public Animation3D weaponAnimation = new Animation3D(); + + public WeaponModel(String fileName) { + super(fileName); + // TODO Auto-generated constructor stub + } + + public Animation3D getAnimation() { + return new Animation3D(weaponAnimation); + } +} diff --git a/src/main/java/framework/AI/AStar.java b/src/main/java/framework/AI/AStar.java new file mode 100644 index 0000000..4934a6a --- /dev/null +++ b/src/main/java/framework/AI/AStar.java @@ -0,0 +1,91 @@ +package framework.AI; + +import java.util.*; + +/** + * A*�N���X�B + */ +public class AStar { + private LinkedList locationOpenList = new LinkedList(); + private LinkedList locationClosedList = new LinkedList(); + + /** + * �ŒZ�o�H�T���B �ŒZ�o�H�̃��X�g��Ԃ����A���‚���Ȃ��ꍇnull��Ԃ��B + * start = goal�̏ꍇ��null��Ԃ��B + * �߂�l�ɂ�goal����start�̂P�‘O�܂Ōo�H�������̂ڂ������̂������Ă���Bstart�͓����Ă��Ȃ��B + */ + public Plan getPath(Location startLocation, + Location goalLocation) { + + //�o���n�_�ƖړI�n�_�������Ȃ�null��Ԃ� + if (startLocation.equals(goalLocation)) { + return null; + } + + // ������ + locationOpenList = new LinkedList(); + locationClosedList = new LinkedList(); + + // �o���n�_��LocationOpenList�ɒlj����� + locationOpenList.add(startLocation); + while (!locationOpenList.isEmpty()) { + // LocationOpenList�̍ŏ��X�R�A�̒n�_��curLocation�Ƃ��Ď��o�� + Collections.sort(locationOpenList, new CostComparator()); + Location curLocation = locationOpenList.removeFirst(); + + // ���݂̒n�_���ړI�n�_�Ȃ�ΒT������ + if (curLocation.equals(goalLocation)) { + LinkedList locationPath = new LinkedList(); + + // �o���n�_�܂Œʂ����n�_��H�� + curLocation = goalLocation; + while (!curLocation.equals(startLocation)) { + locationPath.add(curLocation); + curLocation = (Location) curLocation.getParent(); + } + return new Plan(locationPath); + } + + // ���݂̒n�_���ړI�n�_�łȂ��Ȃ�A���݂̒n�_��LocationClosedList�Ɉڂ� + locationClosedList.add(curLocation); + + // �אڂ���n�_�𒲂ׂ� + ArrayList neighbors = curLocation.getSuccessors(); + + // �אڂ���n�_�̐������A���[�v + for (int i = 0; i < neighbors.size(); i++) { + // �ʉ߂ł��A�e���X�g�ɓ����ĂȂ��Ȃ�R�X�g�����炢�A + if (!locationOpenList.contains(neighbors.get(i)) + && !locationClosedList.contains(neighbors.get(i))) { + //�n�_�R�X�g�����߂� + //agent.getLocationCost((Location)neighbors.get(i), null, null, null); + + //�p�X�R�X�g�����߂� + ((Location)neighbors.get(i)).calculatesCosts(curLocation, goalLocation); + + // LocationOpenList�Ɉڂ� + locationOpenList.add((Location) neighbors.get(i)); + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + + } + return null; + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + // �R�X�g�̏����\�[�g�̂��߂̃N���X����낤 + + /** + * �\�[�g�������N���X�B + */ + class CostComparator implements Comparator { + public int compare(Location n1, Location n2) { + return n1.getScore() - n2.getScore(); + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + +} diff --git a/src/main/java/framework/AI/GeometryGraph.java b/src/main/java/framework/AI/GeometryGraph.java new file mode 100644 index 0000000..86381da --- /dev/null +++ b/src/main/java/framework/AI/GeometryGraph.java @@ -0,0 +1,169 @@ +package framework.AI; + +import java.util.ArrayList; + +import javax.media.j3d.Geometry; +import javax.media.j3d.IndexedTriangleArray; +import javax.vecmath.Point3d; + +import framework.model3D.Position3D; + +public class GeometryGraph extends StateMachine { + // �R���X�g���N�^ + public GeometryGraph(Geometry g) { + if (g instanceof IndexedTriangleArray) { + + IndexedTriangleArray ita = (IndexedTriangleArray) g; + + // ita����states�Ƀf�[�^���������� + for (int i = 0; i < ita.getIndexCount() / 3; i++) {// �ʂ̐��������[�v + Location e = new Location(i, ita); + if (e.getNormal() != null) { + states.add(e); + } + } + + // �֘A�t�� + for (int i = 0; i < states.size(); i++) { + setSuccessors(i, ita); + } + } + } + + + // �A���������֘A�t�� + public void setSuccessors(int index, IndexedTriangleArray ita) { + Location e = (Location)states.get(index); + + // �T�� + int[] List = new int[ita.getIndexCount()]; + + for (int i = 0; i < ita.getIndexCount(); i++) { + List[i] = ita.getCoordinateIndex(i); + } + + // -1�ŏ����� + for (int i = 0; i < 3; i++) { + e.successorIndex[i] = -1; + e.IndexOfSharedEdge[i] = -1; + } + + int j = 0; + + for (int i = 0; i < states.size() * 3; i++) { + // System.out.println("indexList[0] ��List["+i+"] �̏ƍ�"); + // //////id�łk��������u�������ă��\�b�h�Ăяo�������Ȃ�? + // int id = ita.getCoordinateIndex(i); + if (e.indexList[0] == List[i]) { + if (i % 3 == 0) { + if (e.indexList[1] == List[i + 2]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.addSuccessor(states.get(i / 3)); + j++; + } else if (e.indexList[2] == List[i + 1]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } else if (i % 3 == 1) { + if (e.indexList[1] == List[i - 1]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.addSuccessor(states.get(i / 3)); + j++; + } else if (e.indexList[2] == List[i + 1]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } else if (i % 3 == 2) { + if (e.indexList[1] == List[i - 1]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.addSuccessor(states.get(i / 3)); + j++; + } else if (e.indexList[2] == List[i - 2]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[0] = e.indexList[0]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } + + } + } + + for (int i = 0; i < states.size() * 3; i++) { + // System.out.println("indexList[1] ��List["+i+"] �̏ƍ�"); + if (e.indexList[1] == List[i]) { + if (i % 3 == 0) { + if (e.indexList[2] == List[i + 2]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } else if (i % 3 == 1) { + if (e.indexList[2] == List[i - 1]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } else if (i % 3 == 2) { + if (e.indexList[2] == List[i - 2]) { + e.successorIndex[j] = i / 3; + e.IndexOfSharedEdge[1] = e.indexList[1]; + e.IndexOfSharedEdge[2] = e.indexList[2]; + e.addSuccessor(states.get(i / 3)); + j++; + } + } + } + } + + // System.out.println("1�–ڂ�successor**"+successorIndex[0]+"***"); + // System.out.println("2�–ڂ�successor**"+successorIndex[1]+"***"); + // System.out.println("3�–ڂ�successor**"+successorIndex[2]+"***"); + + return; + } + + + // �A�N�Z�b�T + public ArrayList getStates() { + return states; + } + + public Location getNearestLocation(Position3D pos) { + Location nearest = null; + double distance = 0.0; + for (int n = 0; n < states.size(); n++) { + Location loc = (Location)states.get(n); + if (nearest == null) { + nearest = loc; + distance = nearest.getCenter().distance( + new Point3d(pos.getVector3d())); + } else { + double d = loc.getCenter().distance( + new Point3d(pos.getVector3d())); + if (d < distance) { + nearest = loc; + distance = d; + } + } + } + return nearest; + } +} diff --git a/src/main/java/framework/AI/IState.java b/src/main/java/framework/AI/IState.java new file mode 100644 index 0000000..bef6db0 --- /dev/null +++ b/src/main/java/framework/AI/IState.java @@ -0,0 +1,16 @@ +package framework.AI; + +import java.util.ArrayList; + +public interface IState { + + abstract ArrayList getSuccessors(); + + abstract void addSuccessor(IState s); + /** + * �T�����̃m�[�h�擾�B + * @return + * �T�����̃m�[�h��Ԃ��B + */ + abstract IState getParent(); +} diff --git a/src/main/java/framework/AI/Location.java b/src/main/java/framework/AI/Location.java new file mode 100644 index 0000000..d0db4cf --- /dev/null +++ b/src/main/java/framework/AI/Location.java @@ -0,0 +1,139 @@ +package framework.AI; + +import java.awt.Point; +import java.util.ArrayList; + +import javax.media.j3d.IndexedTriangleArray; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; + +import framework.model3D.GeometryUtility; + +public class Location implements IState { + public int planeIndex; + public int[] indexList = new int[3]; + public int[] successorIndex = new int[100]; + public int numberOfSharedEdge;// ���L�ӂ̖{�� + public int[] IndexOfSharedEdge = new int[3];// ���L�ӂ̒��_�C���f�b�N�X + private Point3d center; + private Vector3d normal; + + private double cost = 0; + private double heuristicCost = 0; + private Location parentNode = null; + private ArrayList successors = new ArrayList(); + + // �e�X�g�p�̋�̃R���X�g���N�^ + public Location(Point3d center) { + this.center = center; + normal = new Vector3d(0.0, 1.0, 0.0); + } + + // �R���X�g���N�^ + public Location(int index, IndexedTriangleArray ita) { + planeIndex = index; + + indexList[0] = ita.getCoordinateIndex(index * 3); + indexList[1] = ita.getCoordinateIndex(index * 3 + 1); + indexList[2] = ita.getCoordinateIndex(index * 3 + 2); + + Point3d p1 = new Point3d(); + Point3d p2 = new Point3d(); + Point3d p3 = new Point3d(); + + ita.getCoordinate(indexList[0], p1); + ita.getCoordinate(indexList[1], p2); + ita.getCoordinate(indexList[2], p3); + + // ���S���W�̌v�Z + center = new Point3d((p1.getX() + p2.getX() + p3.getX()) / 3.0, (p1 + .getY() + + p2.getY() + p3.getY()) / 3.0, (p1.getZ() + p2.getZ() + p3 + .getZ()) / 3.0); + + // �@���x�N�g���̌v�Z + p2.sub(p1); + p3.sub(p1); + Vector3d v2 = new Vector3d(p2); + Vector3d v3 = new Vector3d(p3); + v2.cross(v2, v3); + if (v2.length() < GeometryUtility.TOLERANCE) { + v2 = null; + } else { + v2.normalize(); + } + normal = v2; + } + + public void addSuccessor(IState s) { + successors.add(s); + } + + @Override + public ArrayList getSuccessors() { + // TODO Auto-generated method stub + return (ArrayList) successors; + } + + @Override + public IState getParent() { + // TODO Auto-generated method stub + return parentNode; + } + + /** + * �X�R�A�̎擾�B + * + * @return �X�R�A��Ԃ��B + */ + public int getScore() { + // ��r�ɏ����_�����f������ׁA1000���|���Ă��� + return (int) ((cost + heuristicCost) * 1000); + } + + /** + * �R�X�g�v�Z�ƒT�����m�[�h��ݒ�B + * + * @param parentNode + * �T�����̃m�[�h�B + * @param goalNode + * �ړI�n�̃m�[�h�B + */ + public void calculatesCosts(Location parentNode, Location goalNode) { + // �R�X�g�����Z + cost = parentNode.cost + 1; // agent.getPathCost(parentNode, this, null, + // null, null, null, null, null); + + // //�q���[���X�e�B�b�N�R�X�g���v�Z + // disX = point.x - goalNode.point.x; + // disY = point.y - goalNode.point.y; + // �q���[���X�e�B�b�N�R�X�g�̐M�����������ׁA3����1�ɂ��Ă��� + heuristicCost = 0; + + // �T�����m�[�h���L�^ + this.parentNode = parentNode; + } + + // ///////// + // �A�N�Z�b�T// + // ///////// + public int getPlaneIndex() { + return planeIndex; + } + + public int getIndexList(int index) { + return indexList[index]; + } + + public int getSuccessorIndex(int index) { + return successorIndex[index]; + } + + public Point3d getCenter() { + return center; + } + + public Vector3d getNormal() { + return normal; + } +} diff --git a/src/main/java/framework/AI/Plan.java b/src/main/java/framework/AI/Plan.java new file mode 100644 index 0000000..512f55b --- /dev/null +++ b/src/main/java/framework/AI/Plan.java @@ -0,0 +1,75 @@ +package framework.AI; + +import java.util.LinkedList; + +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; + +import framework.model3D.Position3D; + +public class Plan { + private LinkedList path; // �v����e��\���p�X + private int currentLoc = 0; // �p�X��̌��݂� Location + + /** + * �����̒ʉߓ_�����Œv�� + * @param locationPath + */ + public Plan(LinkedList locationPath) { + path = locationPath; + currentLoc = locationPath.size() - 1; + } + + /** + * �X�^�[�g�ƃS�[�����_�C���N�g�Ɍ��Ԍv�� + * @param start + * @param goal + */ + public Plan(Location start, Location goal) { + path = new LinkedList(); + path.add(goal); + path.add(start); + currentLoc = 1; + } + + /** + * ���݂� Location ���擾���� + * @return�@���݂� Location, ���łɃS�[���ɒ����Ă���Ƃ��� null ��Ԃ� + */ + public Location getCurrentLocation() { + if (currentLoc <= 0) return null; + return path.get(currentLoc); + } + + /** + * ���� Location ���擾���� + * @return�@���� Location, ���łɃS�[���ɒ����Ă���Ƃ��� null ��Ԃ� + */ + public Location getNextLocation() { + if (currentLoc <= 0) return null; + return path.get(currentLoc - 1); + } + + /** + * ���݂̍��W�l�����ɁA���݂� Location ���X�V���� + * @param position�@���݂̍��W�l + * @return�@�X�V���� --- true, �ȑO�̂܂� --- false + */ + public boolean updateCurrentLocation(Position3D position) { + Vector3d toCurrentPosition = position.getVector3d(); + Location curLocation = getCurrentLocation(); + if (curLocation == null) return true; + toCurrentPosition.sub(curLocation.getCenter()); + double distanceToCurrentPosition = toCurrentPosition.length(); + Vector3d toNextLocation = new Vector3d(getNextLocation().getCenter()); + toNextLocation.sub(curLocation.getCenter()); + double distanceToNextLocation = toNextLocation.length(); + if (distanceToCurrentPosition >= distanceToNextLocation) { + // ���� Location ��ʂ�߂����ꍇ + currentLoc--; + return true; + } + return false; + } + +} diff --git a/src/main/java/framework/AI/StateMachine.java b/src/main/java/framework/AI/StateMachine.java new file mode 100644 index 0000000..c1b7e21 --- /dev/null +++ b/src/main/java/framework/AI/StateMachine.java @@ -0,0 +1,9 @@ +package framework.AI; + +import java.util.ArrayList; + +public abstract class StateMachine { + protected ArrayList states = new ArrayList(); + protected IState curState; + +} diff --git a/src/main/java/framework/RWT/DefaultSelector.java b/src/main/java/framework/RWT/DefaultSelector.java new file mode 100644 index 0000000..058728b --- /dev/null +++ b/src/main/java/framework/RWT/DefaultSelector.java @@ -0,0 +1,12 @@ +package framework.RWT; +import java.awt.Color; +import java.awt.Graphics; + + +public class DefaultSelector extends RWTSelector { + @Override + public void paint(Graphics g) { + g.setColor(new Color(0.0f, 0.5f, 1.0f, 0.3f)); + g.fill3DRect(widget.getAbsoluteX() - 5, widget.getAbsoluteY() - 5, widget.getAbsoluteWidth() + 10, widget.getAbsoluteHeight() + 10, true); + } +} diff --git a/src/main/java/framework/RWT/RWTBoard.java b/src/main/java/framework/RWT/RWTBoard.java new file mode 100644 index 0000000..5aaec12 --- /dev/null +++ b/src/main/java/framework/RWT/RWTBoard.java @@ -0,0 +1,62 @@ +package framework.RWT; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; + +public class RWTBoard extends RWTWidget { + protected float relativeX = 0.0f; + protected float relativeY = 0.0f; + protected float relativeWidth = 0.0f; + protected float relativeHeight = 0.0f; + private int x = 0; + private int y = 0; + private int width = 0; + private int height = 0; + + public RWTBoard(float x, float y, float w, float h, Color c) { + setRelativePosition(x, y); + setRelativeSize(w, h); + setColor(c); + } + + /** + * ���Έʒu���w�肷��B + * @param x x���W�l(0.0f�`1.0f) + * @param y y���W�l(0.0f�`1.0f) + */ + public void setRelativePosition(float x, float y) { + relativeX = x; + relativeY = y; + } + /** + * ���΃T�C�Y�����肷��B + * @param w ��(0.0f�`1.0f) + * @param h ����(0.0f�`1.0f) + */ + public void setRelativeSize(float w, float h) { + relativeWidth = w; + relativeHeight = h; + } + + @Override + public void adjust(Component parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + x = (int) (sx * relativeX); + y = (int) (sy * relativeY); + width = (int) (sx * relativeWidth); + height = (int) (sy * relativeHeight); + } + + @Override + public void paint(Graphics g) { + g.setColor(new Color(0.0f, 0.0f, 0.0f, 0.3f)); + g.fillRoundRect(x + 5, y + 5, width, height, 10, 10); + g.setColor(color); + g.fillRoundRect(x, y, width, height, 10, 10); + g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue())); + g.drawRoundRect(x, y, width, height, 10, 10); + } + +} diff --git a/src/main/java/framework/RWT/RWTButton.java b/src/main/java/framework/RWT/RWTButton.java new file mode 100644 index 0000000..9b1978a --- /dev/null +++ b/src/main/java/framework/RWT/RWTButton.java @@ -0,0 +1,36 @@ +package framework.RWT; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; + +/** + * �{�^���ł��B + * @author Wataru + * + */ +public abstract class RWTButton extends RWTLabel implements RWTSelectableWidget { + private float relativeX = 0.0f; + private float relativeY = 0.0f; + private float relativeWidth = 0.0f; + private float relativeHeight = 0.0f; + private int x = 0; + private int y = 0; + private int width = 0; + private int height = 0; + + @Override + public void adjust(Component parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + x = (int) (sx * relativeX); + y = (int) (sy * relativeY); + width = (int) (sx * relativeWidth); + height = (int) (sy * relativeHeight); + } + + @Override + public void paint(Graphics g) { + // ������ + } +} diff --git a/src/main/java/framework/RWT/RWTCanvas3D.java b/src/main/java/framework/RWT/RWTCanvas3D.java new file mode 100644 index 0000000..1b78a45 --- /dev/null +++ b/src/main/java/framework/RWT/RWTCanvas3D.java @@ -0,0 +1,241 @@ +package framework.RWT; +import java.awt.AWTEvent; +import java.awt.Canvas; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +import javax.media.j3d.Canvas3D; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.View; +import javax.swing.event.MouseInputListener; + +import com.sun.j3d.utils.universe.SimpleUniverse; + +import framework.model3D.IViewer3D; +import framework.model3D.Universe; +import framework.schedule.ScheduleManager; +import framework.schedule.TaskController; +import framework.view3D.Camera3D; +import framework.view3D.Viewer3D; + +/** + * GUI���i�iRWTWidget�j��z�u�”\��Canvas3D�A�e�R���e�i�ɑ΂��đ��΍��W�Ŕz�u�ł��� + * @author �V�c���� + * + */ +@SuppressWarnings("serial") +public class RWTCanvas3D extends Canvas3D { + private ArrayList widgetList = new ArrayList(); + private float relativeX = 0.0f; + private float relativeY = 0.0f; + private float relativeWidth = 0.0f; + private float relativeHeight = 0.0f; + private int x = 0; + private int y = 0; + private int width = 0; + private int height = 0; + + private Camera3D camera = null; + private IViewer3D viewer = null; + + private DisplayCanvas displayCanvas = null; + private BufferedImage image = null; + private static TaskController renderingController = ScheduleManager.getInstance().registerTask("rendering"); + + public RWTCanvas3D() { + this(SimpleUniverse.getPreferredConfiguration()); + } + + public RWTCanvas3D(GraphicsConfiguration gc) { + this(gc, false); + } + + public RWTCanvas3D(boolean offScreen) { + this(SimpleUniverse.getPreferredConfiguration(), offScreen); + } + + public RWTCanvas3D(GraphicsConfiguration gc, boolean offScreen) { + super(gc, offScreen); + setFocusable(false); + if (offScreen) { + displayCanvas = new DisplayCanvas(); + } else { + enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + } + renderingController.deactivate(); + } + + public Canvas getDisplayCanvas() { + if (isOffScreen()) { + return displayCanvas; + } + return this; + } + + public void attachCamera(Camera3D camera) { + viewer = new Viewer3D(camera); + View oldView = this.getView(); + if (oldView != null) oldView.removeCanvas3D(this); + camera.getView().addCanvas3D(this); + this.camera = camera; + } + + /** + * Widget��z�u����B + * @param widget + */ + public void addWidget(RWTWidget widget) { + widgetList.add(widget); + } + + /** + * RWTCanvas3D�̑��Έʒu�����肷��B + * @param x x���W�l(0.0f�`1.0f) + * @param y y���W�l(0.0f�`1.0f) + */ + public void setRelativePosition(float x, float y) { + relativeX = x; + relativeY = y; + } + + /** + * RWTCanvas3D�̑��΃T�C�Y�����肷��B + * @param w ��(0.0f�`1.0f) + * @param h ����(0.0f�`1.0f) + */ + public void setRelativeSize(float w, float h) { + relativeWidth = w; + relativeHeight = h; + } + + /** + * �e�̃R���e�i�ɉ����Ĉʒu�ƃT�C�Y�����킹��B + * @param parent �e�R���e�i + */ + public void adjust(Container parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + x = (int) (sx * relativeX); + y = (int) (sy * relativeY); + width = (int) (sx * relativeWidth); + height = (int) (sy * relativeHeight); + if (isOffScreen()) { + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + ImageComponent2D ic = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, image, true, false); + ic.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); + ic.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); + setOffScreenBuffer(ic); + displayCanvas.setBounds(x, y, width, height); + getScreen3D().setSize(width, height); + getScreen3D().setPhysicalScreenWidth(0.0254/90.0 * (double)width); + getScreen3D().setPhysicalScreenHeight(0.0254/90.0 * (double)height); + } else { + setBounds(x, y, width, height); + } + } + + @Override + public void preRender() { + if (viewer == null || camera == null) return; + viewer.setGraphicsContext3D(this.getGraphicsContext3D()); + camera.getUniverse().preRender(viewer); + } + + @Override + public void renderField(int fieldDesc) { + if (viewer == null || camera == null) return; + viewer.setGraphicsContext3D(this.getGraphicsContext3D()); + camera.getUniverse().renderField(viewer); + } + + @Override + public void postRender() { + if (viewer == null || camera == null) return; + viewer.setGraphicsContext3D(this.getGraphicsContext3D()); + camera.getUniverse().postRender(viewer); + if (isOffScreen()) { + //�@�I�t�X�N���[���o�b�t�@��̉摜�擾 + ImageComponent2D ic = getOffScreenBuffer(); + image = ic.getImage(); + Graphics src = image.getGraphics(); + //�@�L�����o�X��́@Widget ������ + drawWidgets(src); + src.dispose(); + //�@�f�B�X�v���C�o�b�t�@�ɕ`�� + Graphics dst = displayCanvas.getGraphics(); + dst.drawImage(image, 0, 0, null); + dst.dispose(); + } + } + + @Override + public void postSwap() { + super.postSwap(); + + if (!isOffScreen()) { + //�@�L�����o�X��́@Widget �̕`�� + Graphics g = getGraphics(); + drawWidgets(g); + g.dispose(); + } + renderingController.deactivate(); + } + + /** + * �I�t�X�N���[���̏ꍇ�̂݁A�����_�����O�𖾎��I�ɃX�P�W���[�����O���� + */ + public void doRender() { + if (isOffScreen()) { + if (renderingController.activate()) { + // �O��̃����_�����O���I�����Ă����ꍇ + renderOffScreenBuffer(); + } + } + } + + private void drawWidgets(Graphics g) { + for(int i = 0; i < widgetList.size(); i++) { + RWTWidget widget = widgetList.get(i); + if(widget.isVisible()) { + widget.adjust(this); + widget.paint(g); + } + } + } + + public void processEvent(AWTEvent e) { + // �C�x���g���R���e�i���ɕԂ� + Container c = this.getParent(); + if (c != null) c.dispatchEvent(e); + } + + private class DisplayCanvas extends Canvas { + + public DisplayCanvas() { + setFocusable(false); + enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + } + + public void paint(Graphics g) { + super.paint(g); + if (image != null) { + synchronized (image) { + g.drawImage(image, 0, 0, null); + } + } + } + + public void processEvent(AWTEvent e) { + // �C�x���g���R���e�i���ɕԂ� + Container c = this.getParent(); + if (c != null) c.dispatchEvent(e); + } + } +} diff --git a/src/main/java/framework/RWT/RWTContainer.java b/src/main/java/framework/RWT/RWTContainer.java new file mode 100644 index 0000000..6d58f92 --- /dev/null +++ b/src/main/java/framework/RWT/RWTContainer.java @@ -0,0 +1,180 @@ +package framework.RWT; + +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +import javax.swing.event.MouseInputListener; + + +import framework.model3D.Universe; + + +/** + * GUI���i�iRWTWidget�j��z�u�”\�ȃR���e�i�AGUI���i�̃A�N�e�B�x�[�V�������Ǘ��ł��� + * + * @author �V�c���� + * + */ +@SuppressWarnings("serial") +public abstract class RWTContainer extends Container { + private ArrayList canvases = null; + + private ArrayList widgetList = new ArrayList(); + private RWTSelectionManager active = new RWTSelectionManager(); + + public abstract void build(GraphicsConfiguration gc); + + public abstract void keyPressed(RWTVirtualKey key); + + public abstract void keyReleased(RWTVirtualKey key); + + public abstract void keyTyped(RWTVirtualKey key); + + public RWTContainer() { + setLayout(null); + setFocusable(false); + widgetList.add(active.getSelector()); + enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + } + + public void addCanvas(RWTCanvas3D cavas) { + if (canvases == null) canvases = new ArrayList(); + canvases.add(cavas); + cavas.adjust(this); + add(cavas.getDisplayCanvas()); + } + + public void paint(Graphics g) { + super.paint(g); + + if (canvases != null) { + for (int i = 0; i < canvases.size(); i++) { + canvases.get(i).adjust(this); + canvases.get(i).getDisplayCanvas().paint(g); + } + } + + for (int i = 0; i < widgetList.size(); i++) { + RWTWidget widget = widgetList.get(i); + if (widget.isVisible()) { + widget.adjust(this); + widget.paint(g); + } + } + } + + public RWTCanvas3D getPrimaryRWTCanvas3D() { + if (canvases == null) return null; + return canvases.get(0); + } + + public int getNumberOfRWTCanvas3D() { + if (canvases == null) return 0; + return canvases.size(); + } + + public RWTCanvas3D getRWTCanvas3D(int index) { + return canvases.get(index); + } + + /** + * �J�[�\���őI�ׂȂ�Widget�������܂��B + * + * @param widget + */ + public void addWidget(RWTWidget widget) { + widgetList.add(widget); + } + + /** + * �J�[�\���őI�ׂȂ�Widget�������܂��B + * + * @param widget + */ + public void addWidgetOnBack(RWTWidget widget) { + widgetList.add(0, widget); + } + + /** + * �@�A�N�e�B�x�[�V�����𑀍삷��}�l�[�W���[��ݒ肷��B + * + * @param manager + */ + public void setActiveManager(RWTSelectionManager manager) { + active = manager; + } + + /** + * �J�[�\���őI�ׂ�Widget�������܂��B + * + * @param w + * @param n + * @param m + */ + public void addSelectableWidget(RWTSelectableWidget r, int n, int m) { + active.add(r, n, m); + widgetList.add(0, (RWTWidget) r); + } + + /** + * �J�[�\���őI�ׂ�Widget��O�ʂɉ����܂��B + * + * @param w + * @param n + * @param m + */ + public void addSelectableWidgetOnFront(RWTSelectableWidget r, int n, int m) { + active.add(r, n, m); + widgetList.add((RWTWidget) r); + } + + /** + * �J�[�\�����ЂƂ�ɓ������܂��B + */ + public void cursorMoveUp() { + active.up(); + repaint(); + } + + /** + * �J�[�\�����ЂƂ‰��ɓ������܂��B + */ + public void cursorMoveDown() { + active.down(); + repaint(); + } + + /** + * �J�[�\�����ЂƂ��ɓ������܂��B + */ + public void cursorMoveLeft() { + active.left(); + repaint(); + } + + /** + * �J�[�\�����ЂƂ‰E�ɓ������܂��B + */ + public void cursorMoveRight() { + active.right(); + repaint(); + } + + public RWTWidget getSelectedWidget() { + return active.getSelectedWidget(); + } + + public void processEvent(AWTEvent e) { + // �C�x���g�� RWTFrame3D �ɕԂ� + Container c = this.getParent(); + while (c != null && !(c instanceof RWTFrame3D)) { + c = c.getParent(); + } + if (c != null) ((RWTFrame3D)c).processEvent(e); + super.processEvent(e); + } +} diff --git a/src/main/java/framework/RWT/RWTFrame3D.java b/src/main/java/framework/RWT/RWTFrame3D.java new file mode 100644 index 0000000..6c90f99 --- /dev/null +++ b/src/main/java/framework/RWT/RWTFrame3D.java @@ -0,0 +1,172 @@ +package framework.RWT; +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.DisplayMode; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; + +import javax.swing.JFrame; +import javax.swing.event.MouseInputListener; + + +public class RWTFrame3D extends JFrame implements KeyListener, MouseInputListener { + + private static final long serialVersionUID = 1L; + private RWTVirtualController virtualController = new RWTVirtualController(); + private RWTContainer container; + private Robot robot = null; + private boolean bShadowCasting = false; + private boolean bMouseCapture = false; + + public RWTFrame3D() { + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// GraphicsDevice screen = GraphicsEnvironment. +// getLocalGraphicsEnvironment().getDefaultScreenDevice(); +// setUndecorated(true); +// screen.setFullScreenWindow(this); +// screen.setDisplayMode(new DisplayMode(800, 600, 32, +// DisplayMode.REFRESH_RATE_UNKNOWN)); + addKeyListener(this); + addMouseListener(this); + addMouseMotionListener(this); + try { + robot = new Robot(); + } catch (AWTException e) { + } + requestFocus(); + } + + public void setContentPane(RWTContainer contentPane) { + container = contentPane; + super.setContentPane(contentPane); + setVisible(true); + contentPane.repaint(); + requestFocus(); + } + + /** + * �����_�����O�̊J�n�i�I�t�X�N���[�����[�h�̏ꍇ�̂ݗL���j + */ + public void doRender() { + if (container == null) return; + for (int n = 0; n < container.getNumberOfRWTCanvas3D(); n++) { + container.getRWTCanvas3D(n).doRender(); + } + } + + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + if (0 <= e.getKeyCode() && e.getKeyCode() < 256) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) System.exit(0); + virtualController.setKeyDown(e.getKeyCode(), true); + if (virtualController.getVirtualKey(e.getKeyCode()) != null) { + if (container != null) container.keyPressed(virtualController.getVirtualKey(e.getKeyCode())); + } + } + } + + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + if (0 <= e.getKeyCode() && e.getKeyCode() < 256) { + virtualController.setKeyDown(e.getKeyCode(), false); + if (virtualController.getVirtualKey(e.getKeyCode()) != null) { + if (container != null)container.keyReleased(virtualController.getVirtualKey(e.getKeyCode())); + } + } + } + + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + } + + public RWTVirtualController getVirtualController() { + return virtualController; + } + + public void setShadowCasting(boolean b) { + bShadowCasting = b; + } + + public boolean isShadowCasting() { + return bShadowCasting; + } + + public void setMouseCapture(boolean b) { + bMouseCapture = b; + } + + public void processEvent(AWTEvent e) { + super.processEvent(e); + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + switch (e.getButton()) { + case MouseEvent.BUTTON1: + virtualController.setMouseButtonDown(0, true); + break; + case MouseEvent.BUTTON2: + virtualController.setMouseButtonDown(1, true); + break; + case MouseEvent.BUTTON3: + virtualController.setMouseButtonDown(2, true); + break; + } + } + + @Override + public void mouseReleased(MouseEvent e) { + switch (e.getButton()) { + case MouseEvent.BUTTON1: + virtualController.setMouseButtonDown(0, false); + break; + case MouseEvent.BUTTON2: + virtualController.setMouseButtonDown(1, false); + break; + case MouseEvent.BUTTON3: + virtualController.setMouseButtonDown(2, false); + break; + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (bMouseCapture ) { + int cx = getWidth() / 2; + int cy = getHeight() / 2; + robot.mouseMove(cx, cy); + virtualController.moveMousePosition((double)(e.getXOnScreen()- cx) / (double)getWidth(), (double)(e.getYOnScreen() - cy) / (double)getHeight()); + } else { + virtualController.setMousePosition((double)e.getXOnScreen() / (double)getWidth(), (double)e.getYOnScreen() / (double)getHeight()); + } + } + + @Override + public void mouseMoved(MouseEvent e) { + if (bMouseCapture) { + int cx = getWidth() / 2; + int cy = getHeight() / 2; + robot.mouseMove(cx, cy); + virtualController.moveMousePosition((double)(e.getXOnScreen() - cx) / (double)getWidth(), (double)(e.getYOnScreen() - cy) / (double)getHeight()); + } else { + virtualController.setMousePosition((double)e.getXOnScreen() / (double)getWidth(), (double)e.getYOnScreen() / (double)getHeight()); + } + } +} diff --git a/src/main/java/framework/RWT/RWTImage.java b/src/main/java/framework/RWT/RWTImage.java new file mode 100644 index 0000000..599f468 --- /dev/null +++ b/src/main/java/framework/RWT/RWTImage.java @@ -0,0 +1,95 @@ +package framework.RWT; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.io.File; +import java.util.ArrayList; + +import javax.imageio.ImageIO; +import javax.vecmath.Point2f; + +/** + * �摜�ł��B + * @author Wataru + * + */ +public class RWTImage extends RWTWidget { + protected float relativeX = 0.0f; + protected float relativeY = 0.0f; + protected float relativeWidth = 0.0f; + protected float relativeHeight = 0.0f; + protected int x = 0; + protected int y = 0; + protected int width = 0; + protected int height = 0; + + private BufferedImage image = null; + private ImageObserver observer; + + private int imageWidth = 0; + private int imageHeight = 0; + + public RWTImage(String fileName) { + try { + image = ImageIO.read(new File(fileName)); + setSize(image.getWidth(), image.getHeight()); + } catch (Exception e) { + e.printStackTrace(); + image = null; + } + } + + /** + * �摜�̑��Έʒu���w�肷��B + * @param x x���W�l(0.0f�`1.0f) + * @param y y���W�l(0.0f�`1.0f) + */ + public void setRelativePosition(float x, float y) { + relativeX = x; + relativeY = y; + } + + /** + * �摜��ݒ肵�܂��B + * @param fileName + */ + public void setImage(String fileName) { + try { + image = ImageIO.read(new File(fileName)); + setSize(image.getWidth(), image.getHeight()); + } catch (Exception e) { + e.printStackTrace(); + image = null; + } + } + + /** + * �摜�̃T�C�Y��ݒ肵�܂��B + * ���Βl�ł͂���܂���B + * @param x + * @param y + */ + public void setSize(int x, int y) { + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + } + + public void setObserver(ImageObserver o) { + observer = o; + } + + @Override + public void adjust(Component parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + x = (int) (sx * relativeX); + y = (int) (sy * relativeY); + } + + @Override + public void paint(Graphics g) { + g.drawImage(image, x, y, imageWidth, imageHeight, observer); + } +} diff --git a/src/main/java/framework/RWT/RWTImageButton.java b/src/main/java/framework/RWT/RWTImageButton.java new file mode 100644 index 0000000..cd56f28 --- /dev/null +++ b/src/main/java/framework/RWT/RWTImageButton.java @@ -0,0 +1,44 @@ +package framework.RWT; +/** + * �摜�̃{�^���ł��B + * @author Wataru + * + */ +public class RWTImageButton extends RWTImage implements RWTSelectableWidget { + + public RWTImageButton(String fileName) { + super(fileName); + } + + public void selected() { + } + + public void buttonDown() { + } + + public void buttonUp() { + } + + public void deselected() { + } + + @Override + public int getAbsoluteHeight() { + return height; + } + + @Override + public int getAbsoluteWidth() { + return width; + } + + @Override + public int getAbsoluteX() { + return x; + } + + @Override + public int getAbsoluteY() { + return y; + } +} diff --git a/src/main/java/framework/RWT/RWTLabel.java b/src/main/java/framework/RWT/RWTLabel.java new file mode 100644 index 0000000..81daf40 --- /dev/null +++ b/src/main/java/framework/RWT/RWTLabel.java @@ -0,0 +1,148 @@ +package framework.RWT; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; +import java.util.ArrayList; + +import javax.vecmath.Point2f; + +/** + * �������\��������̂ł��B + * @author Wataru + * + */ +public class RWTLabel extends RWTWidget { + private float relativeBaselineX = 0.0f; + private float relativeBaselineY = 0.0f; + private float relativeWidth = 0.0f; + private float relativeHeight = 0.0f; + private Font relativeFont = new Font("", Font.PLAIN, 12); + + private int baselineX = 0; + private int baselineY = 0; + private int y = 0; + private int width = 0; + private int height = 0; + protected Font font = new Font("", Font.PLAIN, 12); + + protected String[] strings; + protected int drawMode = DRAW_RIGHT; + + public static final int DEFAULT_PARENT_WIDTH_IN_POINT = 500; + + public static final int DRAW_CENTER = 0; + public static final int DRAW_RIGHT = 1; + public static final int DRAW_LEFT = 2; + + public static final String NEW_PARAGRAPH = "#"; + + public RWTLabel() { + strings = new String[1]; + strings[0] = ""; + } + + public RWTLabel(float x, float y, String s, Color c, Font f) { + setRelativePosition(x, y); + setString(s); + setColor(c); + setFont(f); + } + + /** + * ���Έʒu���w�肷��B + * @param x x���W�l(0.0f�`1.0f) + * @param y y���W�l(0.0f�`1.0f) + */ + public void setRelativePosition(float x, float y) { + relativeBaselineX = x; + relativeBaselineY = y; + } + + /** + * ���Έʒu���w�肷��B + * @param x x���W�l(0.0f�`1.0f) + * @param y y���W�l(0.0f�`1.0f) + * @param m �\�����@ + */ + public void setRelativePosition(float x, float y, int m) { + setRelativePosition(x, y); + drawMode = m; + } + + /** + * �\�����镶�����ݒ肷��B + * @param s + */ + public void setString(String s) { + if(s != null) { + strings = s.split(NEW_PARAGRAPH); + } + } + + /** + * �\�����镶����̃t�H���g��ݒ肷��B�������A�t�H���g�̃T�C�Y�̓L�����o�X�̕���500pt�ł���Ƃ��̂��̂Ƃ���B + * @param f + */ + public void setFont(Font f) { + relativeFont = f; + } + + public int getAbsoluteHeight() { + return height; + } + + public int getAbsoluteWidth() { + return width; + } + + public int getAbsoluteX() { + return baselineX; + } + + public int getAbsoluteY() { + return y; + } + + @Override + public void adjust(Component parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + baselineX = (int) (sx * relativeBaselineX); + baselineY = (int) (sy * relativeBaselineY); + font = new Font(relativeFont.getName(), + relativeFont.getStyle(), + (int)(relativeFont.getSize() * sx / DEFAULT_PARENT_WIDTH_IN_POINT)); + + FontMetrics fm = parent.getFontMetrics(font); + y = baselineY - fm.getAscent() + (int)(fm.getDescent() * 1.1); + width = fm.stringWidth(strings[0]); // ��ԏ�̍s�̕��i���{���͍ő啝�ɂ��ׂ��j + height = fm.getAscent(); + } + + @Override + public void paint(Graphics g) { + FontMetrics fm = g.getFontMetrics(font); + g.setColor(color); + g.setFont(font); + int height = fm.getHeight(); + int h = 0; + for(int i = 0; i < strings.length; i++){ + int top = 0; + if(drawMode == DRAW_CENTER) { + top = fm.stringWidth(strings[i]) / 2; + } + else if(drawMode == DRAW_LEFT) { + top = fm.stringWidth(strings[i]); + } + + if (strings[i] != null && strings[i].length() > 0) { + g.drawString(strings[i], baselineX - top, baselineY + h); + } + + h += height; + } + } +} diff --git a/src/main/java/framework/RWT/RWTLine.java b/src/main/java/framework/RWT/RWTLine.java new file mode 100644 index 0000000..50046ca --- /dev/null +++ b/src/main/java/framework/RWT/RWTLine.java @@ -0,0 +1,59 @@ +package framework.RWT; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Point; +import java.util.ArrayList; + +import javax.vecmath.Point2f; + +/** + * ���C���ł��B + * @author Wataru + * + */ +public class RWTLine extends RWTWidget { + private float relativeX1 = 0.0f; + private float relativeY1 = 0.0f; + private float relativeX2 = 0.0f; + private float relativeY2 = 0.0f; + private int x1 = 0; + private int y1 = 0; + private int x2 = 0; + private int y2 = 0; + + /** + * �ꏊ��ݒ肵�܂��B�l�͑��Βl�ł��B + * @param w + * @param h + */ + public void setRelativePosition(float x1, float y1, float x2, float y2) { + relativeX1 = x1; + relativeY1 = y1; + relativeX2 = x2; + relativeY2 = y2; + } + + @Override + public void adjust(Component parent) { + int sx = parent.getWidth(); + int sy = parent.getHeight(); + x1 = (int) (sx * relativeX1); + y1 = (int) (sy * relativeY1); + x2 = (int) (sx * relativeX2); + y2 = (int) (sy * relativeY2); + } + + @Override + public void paint(Graphics g) { + g.setColor(color); + g.drawLine(x1, y1, x2, y2); + } + +// @Override +// public void paint(Graphics g, ArrayList list, double scale) { +// // TODO Auto-generated method stub +// g.setColor(color); +// g.drawLine(list.get(0).x, list.get(0).y, list.get(1).x, list.get(1).y); +// } + +} diff --git a/src/main/java/framework/RWT/RWTSelectableWidget.java b/src/main/java/framework/RWT/RWTSelectableWidget.java new file mode 100644 index 0000000..1bd7b8d --- /dev/null +++ b/src/main/java/framework/RWT/RWTSelectableWidget.java @@ -0,0 +1,23 @@ +package framework.RWT; +import java.awt.Dimension; +import java.awt.Point; + +/** + * �A�N�e�B�u�ɂȂ邽�߂ɕK�v�Ȃ��̂ł��B + * @author Wataru + * + */ +public interface RWTSelectableWidget { + + public abstract void selected(); + + public abstract void deselected(); + + public abstract int getAbsoluteX(); + + public abstract int getAbsoluteY(); + + public abstract int getAbsoluteWidth(); + + public abstract int getAbsoluteHeight(); +} diff --git a/src/main/java/framework/RWT/RWTSelectionCanvas3D.java b/src/main/java/framework/RWT/RWTSelectionCanvas3D.java new file mode 100644 index 0000000..3f864b5 --- /dev/null +++ b/src/main/java/framework/RWT/RWTSelectionCanvas3D.java @@ -0,0 +1,73 @@ +package framework.RWT; + +import java.util.Enumeration; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import framework.model3D.BaseObject3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +public class RWTSelectionCanvas3D extends RWTCanvas3D { + Universe universe = null; + BranchGroup objRoot = null; + + public RWTSelectionCanvas3D() { + this(0.0, 0.0, 12.0); + } + + public RWTSelectionCanvas3D(double cameraX, double cameraY, double cameraZ) { + universe = new Universe(); + objRoot = new BranchGroup(); + objRoot.setCapability(BranchGroup.ALLOW_DETACH); + objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); + objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_READ); + objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + universe.getRoot().addChild(objRoot); + createLight(universe); + setCamera(universe, cameraX, cameraY, cameraZ); + universe.compile(); + } + + private void setCamera(Universe universe, double cameraX, double cameraY, double cameraZ) { + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(cameraX, cameraY, cameraZ)); + camera.addTarget(new Position3D(0.0, 0.0, 0.0)); + camera.adjust(0L); + attachCamera(camera); + } + + void createLight(Universe universe) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.5f, 0.5f, 0.5f)); + amblight + .setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight + .setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + } + + public void setObject(BaseObject3D obj) { + BranchGroup newObj = new BranchGroup(); + newObj.setCapability(BranchGroup.ALLOW_DETACH); + newObj.addChild(obj.getTransformGroupToPlace()); + objRoot.removeAllChildren(); + objRoot.addChild(newObj); + } +} diff --git a/src/main/java/framework/RWT/RWTSelectionManager.java b/src/main/java/framework/RWT/RWTSelectionManager.java new file mode 100644 index 0000000..7d82515 --- /dev/null +++ b/src/main/java/framework/RWT/RWTSelectionManager.java @@ -0,0 +1,266 @@ +package framework.RWT; + + +public class RWTSelectionManager { + + private int size = 0; + + private WidgetHolder selectedHolder = new WidgetHolder(null, 0, 0); + + private WidgetHolder upMostHolder; + private WidgetHolder leftMostHolder; + + private RWTSelector selector = new DefaultSelector(); + + public void add(RWTSelectableWidget widget, int m, int n) { + WidgetHolder holder = new WidgetHolder(widget, m, n); + if(size == 0) { + widget.selected(); + selectedHolder = holder; + upMostHolder = holder; + leftMostHolder = holder; + selector.setSelectableWidget(selectedHolder.getSelectableWidget()); + } + else { + //�ǂꂭ�炢���� + connectY(holder); + + //�ǂꂭ�炢�E�� + connectX(holder); + } + size++; + } + + public void up() { + if(selectedHolder.hasUp()) { + selectedHolder.getSelectableWidget().deselected(); + selectedHolder = selectedHolder.getUp(); + selectedHolder.getSelectableWidget().selected(); + selector.setSelectableWidget(selectedHolder.getSelectableWidget()); + } + } + + public void down() { + if(selectedHolder.hasDown()) { + selectedHolder.getSelectableWidget().deselected(); + selectedHolder = selectedHolder.getDown(); + selectedHolder.getSelectableWidget().selected(); + selector.setSelectableWidget(selectedHolder.getSelectableWidget()); + } + } + + public void right() { + if(selectedHolder.hasRight()) { + selectedHolder.getSelectableWidget().deselected(); + selectedHolder = selectedHolder.getRight(); + selectedHolder.getSelectableWidget().selected(); + selector.setSelectableWidget(selectedHolder.getSelectableWidget()); + } + } + + public void left() { + if(selectedHolder.hasLeft()) { + selectedHolder.getSelectableWidget().deselected(); + selectedHolder = selectedHolder.getLeft(); + selectedHolder.getSelectableWidget().selected(); + selector.setSelectableWidget(selectedHolder.getSelectableWidget()); + } + } + + public RWTWidget getSelectedWidget() { + if(selectedHolder != null) { + return selectedHolder.getWidget(); + } + else { + return null; + } + } + + public void setSelector(RWTSelector c) { + selector = c; + } + + public RWTSelector getSelector() { + return selector; + } + + /** + * ���E���‚Ȃ��� + * @param newHolder + */ + private void connectX(WidgetHolder newHolder) { + WidgetHolder holder = leftMostHolder; + while(true) { + if(newHolder.getY() < holder.getY()) { + //holder�̂ق����� + if(holder.getLeft() != null) { + holder.getLeft().setRight(newHolder); + } + newHolder.setLeft(holder.getLeft()); + + holder.setLeft(newHolder); + newHolder.setRight(holder); + return; + } + else if(newHolder.getY() == holder.getY()) { + if(newHolder.getX() < holder.getX()) { + //holder�̂ق����� + if(holder.getLeft() != null) { + holder.getLeft().setRight(newHolder); + } + newHolder.setLeft(holder.getLeft()); + + holder.setLeft(newHolder); + newHolder.setRight(holder); + return; + } + } + //�܂��E�̂�‚͂���H + if(holder.hasRight()) { + holder = holder.getRight(); + } + //�����E�̂�‚͂��Ȃ� + else { + holder.setRight(newHolder); + newHolder.setLeft(holder); + return; + } + } + } + + /** + * �㉺���‚Ȃ��� + * @param newHolder + */ + private void connectY(WidgetHolder newHolder) { + WidgetHolder holder = upMostHolder; + while(true) { + if(newHolder.getX() < holder.getX()) { + //holder�̂ق����� + if(holder.getUp() != null) { + holder.getUp().setDown(newHolder); + } + newHolder.setUp(holder.getUp()); + + holder.setUp(newHolder); + newHolder.setDown(holder); + return; + } + else if(newHolder.getX() == holder.getX()) { + if(newHolder.getY() < holder.getY()) { + //holder�̂ق����� + if(holder.getUp() != null) { + holder.getUp().setDown(newHolder); + } + newHolder.setUp(holder.getUp()); + + holder.setUp(newHolder); + newHolder.setDown(holder); + return; + } + } + //�܂����̂�‚͂���H + if(holder.hasDown()) { + holder = holder.getDown(); + } + //�������̂�‚͂��Ȃ� + else { + holder.setDown(newHolder); + newHolder.setUp(holder); + return; + } + } + } + + private class WidgetHolder { + private RWTSelectableWidget widget; + + //�s + private int x; + //�� + private int y; + + private WidgetHolder up = null; + private WidgetHolder down = null; + private WidgetHolder right = null; + private WidgetHolder left = null; + + public WidgetHolder(RWTSelectableWidget r, int m, int n) { + widget = r; + x = m; + y = n; + } + + //getter + public RWTWidget getWidget() { + return (RWTWidget) widget; + } + + public RWTSelectableWidget getSelectableWidget() { + return widget; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public WidgetHolder getUp() { + return up; + } + public WidgetHolder getDown() { + return down; + } + public WidgetHolder getRight() { + return right; + } + public WidgetHolder getLeft() { + return left; + } + + //setter + public void setUp(WidgetHolder d) { + up = d; + } + public void setDown(WidgetHolder d) { + down = d; + } + public void setRight(WidgetHolder d) { + right = d; + } + public void setLeft(WidgetHolder d) { + left = d; + } + + public boolean hasUp() { + if(up == null) { + return false; + } + return true; + } + + public boolean hasDown() { + if(down == null) { + return false; + } + return true; + } + + public boolean hasRight() { + if(right == null) { + return false; + } + return true; + } + + public boolean hasLeft() { + if(left == null) { + return false; + } + return true; + } + } +} diff --git a/src/main/java/framework/RWT/RWTSelector.java b/src/main/java/framework/RWT/RWTSelector.java new file mode 100644 index 0000000..33c38e6 --- /dev/null +++ b/src/main/java/framework/RWT/RWTSelector.java @@ -0,0 +1,49 @@ +package framework.RWT; +import java.awt.Component; +import java.util.ArrayList; + +import javax.vecmath.Point2f; + +public abstract class RWTSelector extends RWTWidget { + protected float relativeX = 0.0f; + protected float relativeY = 0.0f; + protected float relativeWidth = 0.0f; + protected float relativeHeight = 0.0f; + protected int x = 0; + protected int y = 0; + protected int width = 0; + protected int height = 0; + + protected RWTSelectableWidget widget = null; + + public void setSelectableWidget(RWTSelectableWidget w) { + widget = w; + } + + public boolean hasWidget() { + if(widget == null) { + return false; + } + return true; + } + + @Override + public void adjust(Component parent) { + x = widget.getAbsoluteX(); + y = widget.getAbsoluteY(); + width = widget.getAbsoluteWidth(); + height = widget.getAbsoluteHeight(); + } + + @Override + public boolean isVisible() { + if(hasWidget()) { + x = widget.getAbsoluteX(); + y = widget.getAbsoluteY(); + width = widget.getAbsoluteWidth(); + height = widget.getAbsoluteHeight(); + return visible; + } + return false; + } +} diff --git a/src/main/java/framework/RWT/RWTVirtualController.java b/src/main/java/framework/RWT/RWTVirtualController.java new file mode 100644 index 0000000..661f069 --- /dev/null +++ b/src/main/java/framework/RWT/RWTVirtualController.java @@ -0,0 +1,116 @@ +package framework.RWT; + +import java.awt.event.KeyEvent; + + +public class RWTVirtualController { + + private boolean bKeyDown[][] = { + {false, false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false, false}}; + private boolean rawKeyDown[] = new boolean[256]; + private boolean mouseButtonDown1 = false; + private boolean mouseButtonDown2 = false; + private boolean mouseButtonDown3 = false; + private double mouseX = 0; + private double mouseY = 0; + private static RWTVirtualKey keyMap[] = new RWTVirtualKey[256]; + + public static final int UP = 0; + public static final int DOWN = 1; + public static final int RIGHT = 2; + public static final int LEFT = 3; + public static final int BUTTON_A = 4; + public static final int BUTTON_B = 5; + public static final int BUTTON_C = 6; + public static final int BUTTON_D = 7; + + public RWTVirtualController() { + // player1�p��keyBind�̏����� + RWTVirtualController.keyBind(KeyEvent.VK_W, 0, RWTVirtualController.UP); // w + RWTVirtualController.keyBind(KeyEvent.VK_D, 0, RWTVirtualController.RIGHT); //d + RWTVirtualController.keyBind(KeyEvent.VK_A, 0, RWTVirtualController.LEFT); // a + RWTVirtualController.keyBind(KeyEvent.VK_S, 0, RWTVirtualController.DOWN); // s + RWTVirtualController.keyBind(KeyEvent.VK_V, 0, RWTVirtualController.BUTTON_B); // v + RWTVirtualController.keyBind(KeyEvent.VK_B, 0, RWTVirtualController.BUTTON_A); // b + RWTVirtualController.keyBind(KeyEvent.VK_SPACE, 0, RWTVirtualController.BUTTON_C); // space + RWTVirtualController.keyBind(KeyEvent.VK_E, 0, RWTVirtualController.BUTTON_D); // e + + // player2�p��keyBind�̏����� + RWTVirtualController.keyBind(KeyEvent.VK_O, 1, RWTVirtualController.UP); // o + RWTVirtualController.keyBind(KeyEvent.VK_SEMICOLON, 1, RWTVirtualController.RIGHT); //; + RWTVirtualController.keyBind(KeyEvent.VK_K, 1, RWTVirtualController.LEFT); // k + RWTVirtualController.keyBind(KeyEvent.VK_L, 1, RWTVirtualController.DOWN); // l + RWTVirtualController.keyBind(KeyEvent.VK_BACK_SLASH, 1, RWTVirtualController.BUTTON_B); // \ + RWTVirtualController.keyBind(KeyEvent.VK_SHIFT, 1, RWTVirtualController.BUTTON_A); // shift + RWTVirtualController.keyBind(KeyEvent.VK_CONTROL, 1, RWTVirtualController.BUTTON_C); // ctrl + RWTVirtualController.keyBind(KeyEvent.VK_P, 1, RWTVirtualController.BUTTON_D); // p + } + + static public void keyBind(int keyCode, int playerNo, int buttonNo) { + keyMap[keyCode] = new RWTVirtualKey(playerNo, keyCode, buttonNo); + } + + public boolean isKeyDown(int player, int keyNo) { + return bKeyDown[player][keyNo]; + } + + public boolean isKeyDown(int keyCode) { + return rawKeyDown[keyCode]; + } + + public void setKeyDown(int keyCode, boolean b) { + if (keyMap[keyCode] != null) { + bKeyDown[keyMap[keyCode].getPlayer()][keyMap[keyCode].getVirtualKey()] = b; + } + rawKeyDown[keyCode] = b; + } + + public RWTVirtualKey getVirtualKey(int keyCode) { + return keyMap[keyCode]; + } + + public boolean isMouseButtonDown(int buttonNo) { + switch (buttonNo) { + case 0: + return mouseButtonDown1; + case 1: + return mouseButtonDown2; + case 2: + return mouseButtonDown3; + } + return false; + } + + public void setMouseButtonDown(int buttonNo, boolean b) { + switch (buttonNo) { + case 0: + mouseButtonDown1 = b; + break; + case 1: + mouseButtonDown2 = b; + break; + case 2: + mouseButtonDown3 = b; + break; + } + } + + public double getMouseX() { + return mouseX; + } + + public double getMouseY() { + return mouseY; + } + + public void setMousePosition(double x, double y) { + mouseX = x; + mouseY = y; + } + + public void moveMousePosition(double dx, double dy) { + mouseX += dx; + mouseY += dy; + } +} diff --git a/src/main/java/framework/RWT/RWTVirtualKey.java b/src/main/java/framework/RWT/RWTVirtualKey.java new file mode 100644 index 0000000..9c9640e --- /dev/null +++ b/src/main/java/framework/RWT/RWTVirtualKey.java @@ -0,0 +1,43 @@ +package framework.RWT; + + +public class RWTVirtualKey { + + private int player; + private int physicalKey; + private int virtualKey; + + public RWTVirtualKey(int player, int physicalKey, int virtualKey){ + setPlayer(player); + setPhysicalKey(physicalKey); + setVirtualKey(virtualKey); + } + + public void setPlayer(int player) { + this.player = player; + } + + public int getPlayer() { + return player; + } + + public void setPhysicalKey(int physicalKey) { + this.physicalKey = physicalKey; + } + + public int getPhysicalKey() { + return physicalKey; + } + + public void setVirtualKey(int virtualKey) { + this.virtualKey = virtualKey; + } + + public int getVirtualKey() { + return virtualKey; + } + + public void assignPlayer(int playernum) { + + } +} diff --git a/src/main/java/framework/RWT/RWTWidget.java b/src/main/java/framework/RWT/RWTWidget.java new file mode 100644 index 0000000..5c99cc4 --- /dev/null +++ b/src/main/java/framework/RWT/RWTWidget.java @@ -0,0 +1,43 @@ +package framework.RWT; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.util.ArrayList; + +import javax.vecmath.Point2f; + +/** + * �e�R���e�i�ɑ΂��đ��΍��W�Ŕz�u�ł���GUI���i + * @author Wataru + * + */ +public abstract class RWTWidget { + protected Color color = Color.BLACK; + + protected boolean visible = true; + + /** + * �e�R���e�i�i�L�����o�X�̏ꍇ������j�̑傫���ɍ��킹�Ĉʒu�ƃT�C�Y�𒲐����� + * @param parent + */ + public abstract void adjust(Component parent); + public abstract void paint(Graphics g); + + /** + * �F��ݒ肷�� + * @param c + */ + public void setColor(Color c) { + color = c; + } + + public void setVisible(boolean b) { + visible = b; + } + + public boolean isVisible() { + return visible; + } +} diff --git a/src/main/java/framework/animation/Animation3D.java b/src/main/java/framework/animation/Animation3D.java new file mode 100644 index 0000000..45de74e --- /dev/null +++ b/src/main/java/framework/animation/Animation3D.java @@ -0,0 +1,137 @@ +package framework.animation; + +import java.util.ArrayList; + +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; + +/** + * �K�w�����ꂽ�I�u�W�F�N�g�ɑ΂���A�j���[�V��������ێ�����i���i�P�ʂňʒu�A�����A�e�N�X�`�����A�j���[�V�����”\�j + * @author �V�c���� + * + */ +public class Animation3D { + public long time = 0; + + private ArrayList partList = new ArrayList(); + private long maxKey = getMaxKey(); + + public Animation3D() { + time = 0; + } + + public Animation3D(Animation3D a) { + time = 0; + partList = a.partList; + maxKey = a.maxKey; + } + + public boolean equals(Animation3D a) { + return (partList == a.partList && maxKey == a.maxKey); + } + + public void reset() { + time = 0; + } + + public boolean progress(long interval) { + if (maxKey == 0) + return true; // ��̃A�j���[�V�����̏ꍇ�������Ȃ� + time += interval; + // System.out.println(time + "/" + maxKey); + if (time > maxKey) { + time = time % maxKey; // time���Ō�̗v�f��key�̒l�i�A�j���[�V�����̍Ō��key)�𒴂��Ă���ꍇ�At���Ō��key�̒l�imaxKey)�Ŋ������]��Ƃ��Đݒ肷�� + return false; + } else + return true; + } + + public Pose3D getPose() { + if (maxKey == 0 || partList.size() == 0) + return new DefaultPose3D(); + + KeyFrame[] aroundKey = new KeyFrame[2]; + Quaternion3D q; + Position3D p; + Quaternion3D tq; + Position3D tp; + Pose3D pose = new Pose3D(); + for (int i = 0; i < partList.size(); i++) { + aroundKey = partList.get(i).getKey(time); + + // �R�s�[�R���X�g���N�^�̍쐬 + q = null; + p = null; + tq = null; + tp = null; + if (aroundKey[0].getPosition() != null) { + p = new Position3D(aroundKey[0].getPosition()); // getPosition()���Q�Ƃ�Ԃ��̂ŃR�s�[���Ă���ύX + } + if (aroundKey[0].getQuaternion() != null) { + q = new Quaternion3D(aroundKey[0].getQuaternion()); // getQuaternion()���A�h���X�i�Q�Ɓj��Ԃ��̂ŁA�R�s�[�i�����j���쐬���Ă������ύX���Ă���B + } + if (aroundKey[0].getTexturePosition() != null) { + tp = new Position3D(aroundKey[0].getTexturePosition()); // getPosition()���Q�Ƃ�Ԃ��̂ŃR�s�[���Ă���ύX + } + if (aroundKey[0].getTextureQuaternion() != null) { + tq = new Quaternion3D(aroundKey[0].getTextureQuaternion()); // getQuaternion()���A�h���X�i�Q�Ɓj��Ԃ��̂ŁA�R�s�[�i�����j���쐬���Ă������ύX���Ă���B + } + + // time��key���̂��̂������ꍇ�i��Ԃ̌v�Z���s�v�ȏꍇ�j + if (aroundKey[1] != null) { + // t1 ��t�̑O��key�iaroundKey[0]�j�̃X�J���[�{ + double t1 = aroundKey[1].key - time; + // t2 ��t�̌��key�iaroundKey[1]�j�̃X�J���[�{ + double t2 = time - aroundKey[0].key; + double t3 = aroundKey[1].key - aroundKey[0].key; + double timealpha = t2 / t3; + + // time�ɑ΂���Quaternion��Position�̌v�Z + if (p != null) { + Position3D p2 = new Position3D(aroundKey[1].getPosition()); + p.mul(t1 / t3).add(p2.mul(t2 / t3)); + } + if (q != null) { + Quaternion3D q2 = new Quaternion3D(aroundKey[1].getQuaternion()); + q.getInterpolate(q2, timealpha); + } + if (tp != null) { + Position3D tp2 = new Position3D(aroundKey[1].getTexturePosition()); + tp.mul(t1 / t3).add(tp2.mul(t2 / t3)); + } + if (tq != null) { + Quaternion3D tq2 = new Quaternion3D(aroundKey[1].getTextureQuaternion()); + tq.getInterpolate(tq2, timealpha); + } + } + pose.addPose(partList.get(i).getName(), p, q, aroundKey[0].getTexture(), tp, tq, partList.get(i).getTextureUnit()); + } + + return pose; + } + + public Animation3D merge(Animation3D a) { + this.partList.addAll(a.partList); + maxKey = getMaxKey(); + return this; + } + + public void addPartAnimation(PartAnimation pa) { + partList.add(pa); + maxKey = getMaxKey(); + } + + // �A�j���[�V�������I���������𔻒肷�邽�߂�key�̍ő�l��T�����ĕԂ����\�b�h + private long getMaxKey() { + long maxKey = 0; + int i; + + for (i = 0; i < partList.size(); i++) { + if (maxKey < partList.get(i).getLastKey()) { + maxKey = partList.get(i).getLastKey(); + } else + continue; + } + return maxKey; + } +} diff --git a/src/main/java/framework/animation/AnimationFactory.java b/src/main/java/framework/animation/AnimationFactory.java new file mode 100644 index 0000000..ca36a75 --- /dev/null +++ b/src/main/java/framework/animation/AnimationFactory.java @@ -0,0 +1,138 @@ +package framework.animation; + +import java.awt.GraphicsConfiguration; +import java.util.ArrayList; + +import javax.media.j3d.Canvas3D; +import javax.media.j3d.View; + +import com.sun.j3d.utils.universe.SimpleUniverse; + +import cv97.SceneGraph; +import cv97.field.MFFloat; +import cv97.field.MFVec3f; +import cv97.j3d.AppearanceNodeObject; +import cv97.j3d.IndexedFaceSetNodeObject; +import cv97.j3d.SceneGraphJ3dObject; +import cv97.node.AppearanceNode; +import cv97.node.BackgroundNode; +import cv97.node.IndexedFaceSetNode; +import cv97.node.Node; +import cv97.node.NodeObject; +import cv97.node.OrientationInterpolatorNode; +import cv97.node.PositionInterpolatorNode; +import cv97.node.ShapeNode; +import cv97.node.SpotLightNode; +import cv97.node.TransformNode; +import cv97.util.LinkedListNode; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.schedule.ScheduleManager; +import framework.schedule.TaskController; + +public class AnimationFactory { + private static Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + + public static Animation3D loadAnimation(String fileName){ + + SceneGraph sg = new SceneGraph(SceneGraph.NORMAL_GENERATION); + + // �t�@�C���ǂݍ��ݎ��Ƀ����_�����O���s����̂ŁA�I�t�X�N���[�������_�����O���֎~���� + TaskController renderingController = ScheduleManager.getInstance().getController("rendering"); + renderingController.waitForActivation(); + renderingController.activate(); + + // �t�@�C���ǂݍ��� + View view = canvas.getView(); + if (view != null) view.removeCanvas3D(canvas); + SceneGraphJ3dObject sgObject = new SceneGraphJ3dObject(canvas, sg); + sg.setObject(sgObject); + sg.load(fileName); + + // �I�t�X�N���[�������_�����O�̋��� + renderingController.deactivate(); + + // Animation3D�ւ̕ϊ� + Animation3D animation= loadAnimation(sg); + + return animation; + } + + private static Animation3D loadAnimation(LinkedListNode node){ + Animation3D mergedAnimation = null; + System.out.println(node.getClass()); + + if( ! (node instanceof PositionInterpolatorNode || node instanceof OrientationInterpolatorNode) ){ + Node childNodes; + String name = ""; + if (node instanceof SceneGraph) { + childNodes = ((SceneGraph)node).getNodes(); + } else { + childNodes = ((Node)node).getChildNodes(); + name = ((Node)node).getName(); + } + if(childNodes != null){ + + for(Node n = childNodes;n != null;n = n.next()){ + Animation3D animation; + if((animation = loadAnimation(n)) != null){ + if (mergedAnimation != null) { + mergedAnimation.merge(animation); + } else { + mergedAnimation = animation; + } + } + + //�Z��Ŗ������[�v�ɂȂ�Ȃ��悤�ɂ��鏈�� + Node dummy = n; + dummy = dummy.next(); + if(n == dummy){ + break; + } + } + +// System.out.println("�q���̐���"+ list.size()); + + if(mergedAnimation != null){ + return mergedAnimation; + } + } + return null; + } else if (node instanceof PositionInterpolatorNode) { + + String name = ((PositionInterpolatorNode)node).getName(); + PositionInterpolatorNode pi = (PositionInterpolatorNode)node; + + //�A�j���[�V�����f�[�^�̎擾 + int i=0; + PartAnimation pa = new PartAnimation(name); + for(i=0;i keyList = new ArrayList(); + public static final int SINGLE_TEXTURE = -1; + + public PartAnimation(String name) { + this.name = name; + textureUnit = SINGLE_TEXTURE; + } + + public PartAnimation(String name, int textureUnit) { + this.name = name; + this.textureUnit = textureUnit; + } + + String getName() { + return name; + } + + int getTextureUnit() { + return textureUnit; + } + + //�A�j���[�V�����̌o�ߎ��Ԃ̑O���key��KeyFrame�^�̔z��Ŏ擾���郁�\�b�h + KeyFrame[] getKey(long t){ + int i; + KeyFrame[] aroundKey = new KeyFrame[2]; + + for(i=1;i partPoseList = new ArrayList(); + + public Pose3D() { + } + + public Pose3D(Pose3D p) { + partPoseList = new ArrayList(p.partPoseList); + } + + public void applyTo(Object3D obj) { + // obj.rotate(part, vx, vy, vz, a); + int n = partPoseList.size(); + for (int i = 0; i < n; i++) { + final PartPose partpose = (PartPose) partPoseList.get(i); + Object3D partObj = obj.getPart(partpose.name); + if (partObj != null) { + // �ʒu + if (partpose.position != null) + partObj.apply(partpose.position, false); + // ���� + if (partpose.quaternion != null) + partObj.apply(partpose.quaternion, false); + // �e�N�X�`�� + if (partpose.texture != null + || partpose.texturePosition != null + || partpose.textureQuaternion != null) { + ObjectVisitor v = new ObjectVisitor() { + @Override + public void postVisit(Object3D obj) { + Appearance appearance = null; + Node node = obj.getPrimitiveNode(); + if (node != null && node instanceof Shape3D) { + appearance = ((Shape3D)node).getAppearance(); + } else if (node != null && node instanceof Primitive) { + appearance = ((Primitive)node).getAppearance(); + } + if (appearance != null) { + TextureUnitState tu = null; + if (partpose.texture != null) { + if (partpose.textureUnit == PartAnimation.SINGLE_TEXTURE) { + appearance.setTexture(partpose.texture); + } else { + tu = appearance.getTextureUnitState(partpose.textureUnit); + tu.setTexture(partpose.texture); + appearance.setTextureUnitState(partpose.textureUnit, tu); + } + } + if ((partpose.texturePosition != null || partpose.textureQuaternion != null) + && obj.hasAppearancePrepared()) { // Appearance ������̃����_�����O�̒��O�ōX�V�����”\�������邽�� + TextureAttributes ta; + if (partpose.textureUnit == PartAnimation.SINGLE_TEXTURE) { + ta = appearance.getTextureAttributes(); + } else { + tu = appearance.getTextureUnitState(partpose.textureUnit); + ta = tu.getTextureAttributes(); + } + if (ta == null) { + ta = new TextureAttributes(); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + } + Transform3D t = new Transform3D(); + if (partpose.texturePosition != null) { + t.set(new Vector3d(partpose.texturePosition.getVector3d())); + } + if (partpose.textureQuaternion != null) { + Transform3D t2 = new Transform3D(); + t2.set(partpose.textureQuaternion.getQuat()); + t.mul(t2); + } +// shape.getAppearance().getTextureAttributes().setTextureTransform(t); + ta.setTextureTransform(t); + if (partpose.textureUnit == PartAnimation.SINGLE_TEXTURE) { + appearance.setTextureAttributes(ta); + } else { + tu.setTextureAttributes(ta); + appearance.setTextureUnitState(partpose.textureUnit, tu); + } + } + } + } + @Override + public void preVisit(Object3D obj) { + } + }; + partObj.accept(v); + } + } + } + } + + public void addPose(String name, Position3D p, Quaternion3D q, Texture texture, Position3D tp, Quaternion3D tq, int textureUnit) { + PartPose partpose = new PartPose(name, p, q, texture, tp, tq, textureUnit); + partPoseList.add(partpose); + } + + @Override + public Property3D clone() { + // TODO Auto-generated method stub + return new Pose3D(this); + } +} diff --git a/src/main/java/framework/audio/BGM3D.java b/src/main/java/framework/audio/BGM3D.java new file mode 100644 index 0000000..6d0dd55 --- /dev/null +++ b/src/main/java/framework/audio/BGM3D.java @@ -0,0 +1,15 @@ +package framework.audio; + +public class BGM3D { + private static Sound3D currentBGM = null; + + public static Sound3D registerBGM(String fileName) { + return new Sound3D(fileName); + } + + public static void playBGM(Sound3D newBGM) { + if (currentBGM != null) currentBGM.stop(); + newBGM.loopPlay(); + currentBGM = newBGM; + } +} diff --git a/src/main/java/framework/audio/Sound3D.java b/src/main/java/framework/audio/Sound3D.java new file mode 100644 index 0000000..9ba50f2 --- /dev/null +++ b/src/main/java/framework/audio/Sound3D.java @@ -0,0 +1,60 @@ +package framework.audio; +import java.io.File; +import java.io.IOException; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.Control; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; + + +public class Sound3D { + private Clip clip = null; + + public Sound3D(String fileName) { + Clip clip = null; + AudioInputStream aistream; + try { + File file = new File(fileName); + aistream = AudioSystem.getAudioInputStream(file); + DataLine.Info info = new DataLine.Info(Clip.class, aistream.getFormat()); + clip = (Clip)AudioSystem.getLine(info); + clip.open(aistream); + } catch (UnsupportedAudioFileException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (LineUnavailableException e) { + e.printStackTrace(); + } + this.clip = clip; + } + + public void play() { + clip.stop(); + clip.setFramePosition(0); + clip.start(); + } + + public void play(double vol) { + FloatControl control = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); + control.setValue((float)Math.log10(vol) * 20); + clip.stop(); + clip.setFramePosition(0); + clip.start(); + } + + public void loopPlay() { + clip.stop(); + clip.setFramePosition(0); + clip.loop(Clip.LOOP_CONTINUOUSLY); + } + + public void stop() { + clip.stop(); + } +} diff --git a/src/main/java/framework/gameMain/AbstractGame.java b/src/main/java/framework/gameMain/AbstractGame.java new file mode 100644 index 0000000..2cf83ae --- /dev/null +++ b/src/main/java/framework/gameMain/AbstractGame.java @@ -0,0 +1,95 @@ +package framework.gameMain; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import framework.RWT.RWTFrame3D; +import framework.schedule.ScheduleManager; + +/** + * �Q�[���̊�{�N���X + * @author �V�c���� + * + */ +public abstract class AbstractGame implements Runnable { + protected RWTFrame3D mainFrame; + private ScheduledExecutorService t; + private long minimumFrameTime = 5; + private long maximumFrameTime = 15; + private boolean bWaitForRender = true; + private long prevTime = 0L; + + public abstract RWTFrame3D createFrame3D(); + protected abstract IGameState getCurrentGameState(); + + public AbstractGame() { + mainFrame = createFrame3D(); + } + + public void start() { + if (getCurrentGameState() != null) { + activateState(getCurrentGameState()); + } + } + + public void stop() { + if (getCurrentGameState() != null) { + deactivateState(getCurrentGameState()); + } + } + + public void setFramePolicy(long minimumFrameTime, boolean bWaitForRender) { + this.minimumFrameTime = minimumFrameTime; + this.bWaitForRender = bWaitForRender; + } + + public void setFramePolicy(long minimumFrameTime, long maximumFrameTime, boolean bWaitForRender) { + this.minimumFrameTime = minimumFrameTime; + this.maximumFrameTime = maximumFrameTime; + this.bWaitForRender = bWaitForRender; + } + + public void run() { + if (bWaitForRender) { + // �����_�����O�̏I���Ɠ������ăQ�[����i�߂� + ScheduleManager.getInstance().getController("rendering").waitForActivation(); + } + mainFrame.doRender(); + long curTime = System.currentTimeMillis(); + long interval; + if (prevTime == 0L) { + interval = minimumFrameTime; + } else { + interval = curTime - prevTime; + if (interval > maximumFrameTime) { + interval = maximumFrameTime; + } + } + prevTime = curTime; + // ���̃Q�[����Ԃ�update���ĂԁB + getCurrentGameState().update(mainFrame.getVirtualController(), interval); + } + + protected void activateState(IGameState s) { + s.init(mainFrame); + if(s.useTimer()){ + timerRun(); + } + } + + protected void deactivateState(IGameState s) { + if(s.useTimer()){ + timerCancel(); + } + } + + private void timerCancel() { + if (t != null) t.shutdownNow(); + } + + private void timerRun() { + t = new ScheduledThreadPoolExecutor(1); + // scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) + t.scheduleWithFixedDelay(this, minimumFrameTime, minimumFrameTime, TimeUnit.MILLISECONDS); + } +} \ No newline at end of file diff --git a/src/main/java/framework/gameMain/AbstractGameState.java b/src/main/java/framework/gameMain/AbstractGameState.java new file mode 100644 index 0000000..f41976b --- /dev/null +++ b/src/main/java/framework/gameMain/AbstractGameState.java @@ -0,0 +1,55 @@ +package framework.gameMain; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.util.ArrayList; +import java.util.Timer; +import java.util.TimerTask; + +import javax.media.j3d.GraphicsConfigTemplate3D; + +import com.sun.j3d.utils.universe.SimpleUniverse; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTVirtualController; +import framework.model3D.Universe; + +public abstract class AbstractGameState implements IGameState { + protected RWTContainer container; + + public void init(RWTFrame3D frame) { + if (container == null) { + container = createContainer(); + } + frame.setContentPane(container); + GraphicsConfiguration gc = null; + if (frame.isShadowCasting()) { + // �e��t����ꍇ + // �X�e���V���o�b�t�@���g�p���� GraphicsConfiguration �̐��� + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); + gct3D.setStencilSize(8); + gc = gd.getBestConfiguration(gct3D); + } + container.build(gc); + } + + public abstract RWTContainer createContainer(); + /* (non-Javadoc) + * @see IGameState#useTimer() + */ + public abstract boolean useTimer(); + /* (non-Javadoc) + * @see IGameState#progress(RWTVirtualController) + */ + public abstract void update(RWTVirtualController virtualController, long interval); + + public RWTCanvas3D getRWTCanvas3D() { + if (container == null) return null; + return container.getPrimaryRWTCanvas3D(); + } +} diff --git a/src/main/java/framework/gameMain/AbstractManager.java b/src/main/java/framework/gameMain/AbstractManager.java new file mode 100644 index 0000000..ca9a1d3 --- /dev/null +++ b/src/main/java/framework/gameMain/AbstractManager.java @@ -0,0 +1,208 @@ +package framework.gameMain; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +public abstract class AbstractManager { + + private DataBox data = new DataBox(); + private BufferedReader reader = null; + private String seekFilename; + + protected void addSeekFile(String filename) { + seekFilename = filename; + } + + protected void seek(String d) { + File file = new File(d); + //�f�B���N�g���̂Ƃ� + if(file.isDirectory()) { + openDirectory(file.listFiles()); + } + //�t�@�C���̂Ƃ� + else { + openFile(file); + } + } + + //�f�B���N�g���������� + private void openDirectory(File[] fileList) { + File file; + for(int i = 0; i < fileList.length; i++) { + file = fileList[i]; + //�f�B���N�g���̂Ƃ� + if(file.isDirectory()) { + openDirectory(file.listFiles()); + } + //�t�@�C���̂Ƃ� + else { + openFile(file); + } + } + } + //�t�@�C���������� + private void openFile(File file) { + if(file.getName().equals(seekFilename)) { + data.removeAll(); + + try { + reader = new BufferedReader(new FileReader(file)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + findFile(file); + + try { + reader.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /** + * setBufferedReader(File file)�����邱�� + */ + protected String readLine() { + if(reader != null) { + try { + return reader.readLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + protected void setTags(ArrayList tags) { + for(int i = 0; i < tags.size(); i++) { + data.setTag(tags.get(i)); + } + } + protected void setTag(String tag) { + data.setTag(tag); + } + + protected void findFile(File file) { + String str; + while(true) { + str = readLine(); + if(str == null) { + break; + } + String[] strings = str.split(":"); + if(strings.length >= 2) { + data.setData(strings[0], strings[1]); + } + } + create(); + } + + protected String getData(String tag) { + return data.getData(tag); + } + + public boolean hasData(String tag){ + if(data.getData(tag) == null) + return false; + else if(data.getData(tag) == "") + return false; + else return true; + } + + abstract protected void create(); + + private class DataBox { + private ArrayList dataList = new ArrayList(); + + public void setTag(String tag) { + dataList.add(new Data(tag)); + } + + public void setData(String tag, String data) { + for(int i = 0; i < dataList.size(); i++) { + if(dataList.get(i).getTag().equals(tag)) { + dataList.get(i).addData(data); + } + } + } + + /** + * ����key�̃f�[�^��Ԃ��B + * @param key �^�O�� + * @return + */ + public String getData(String tag) { + for(int i = 0; i < dataList.size(); i++) { + if(dataList.get(i).getTag().equals(tag)) { + if(dataList.get(i).getData().size() > 0) { + return dataList.get(i).getData().get(0); + } + else { + break; + } + } + } + return ""; + } + + public ArrayList getDatas(String tag) { + for(int i = 0; i < dataList.size(); i++) { + if(dataList.get(i).getTag().equals(tag)) { + return dataList.get(i).getData(); + } + } + return new ArrayList(); + } + + /** + * ���̃^�O�����݂��邩�B + * @param tag + * @return + */ + public boolean isExist(String tag) { + for(int i = 0; i < dataList.size(); i++) { + if(dataList.get(i).getTag().equals(tag)) { + return true; + } + } + return false; + } + + public void removeAll() { + for(int i = 0; i < dataList.size(); i++) { + dataList.get(i).removeData(); + } + } + } + + private class Data { + private String tag; + private ArrayList data = new ArrayList(); + + public Data(String tag) { + this.tag = tag; + } + + public String getTag() { + return tag; + } + + public void addData(String d) { + data.add(d); + } + + public ArrayList getData() { + return data; + } + + public void removeData() { + data = new ArrayList(); + } + } +} diff --git a/src/main/java/framework/gameMain/Actor.java b/src/main/java/framework/gameMain/Actor.java new file mode 100644 index 0000000..ff0cf29 --- /dev/null +++ b/src/main/java/framework/gameMain/Actor.java @@ -0,0 +1,348 @@ +package framework.gameMain; + + +import java.util.ArrayList; + +import javax.media.j3d.Transform3D; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Vector3d; + +import framework.animation.Animation3D; +import framework.model3D.CollisionResult; +import framework.model3D.GeometryUtility; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; +import framework.physics.Velocity3D; + +/** + * �Q�[�����̓o�ꕨ�S�� + * @author �V�c���� + * + */ +public abstract class Actor extends Animatable { + protected Vector3d direction = new Vector3d(1.0, 0.0, 0.0); + protected Mode mode; + // �ȉ��ȃ��������̂��ߗ\�߃C���X�^���X�𐶐� + protected Mode modeFreeFall = new ModeFreeFall(); + protected Mode modeOnGround = new ModeOnGround(); + + public Actor(Object3D body, Animation3D animation) { + super(new Solid3D(body), animation); + mode = modeOnGround; + } + + public Actor(Solid3D body, Animation3D animation) { + super(body, animation); + mode = modeOnGround; + } + + public Actor(ActorModel model) { + super(model.createBody(), model.getAnimation()); + mode = modeOnGround; + } + + /** + * �P�ʎ��Ԃ��Ƃ̓���i�Փ˔��菈���͍s��Ȃ��j + * @param interval --- �O��Ăяo���ꂽ�Ƃ�����̌o�ߎ��ԁi�~���b�P�ʁj + */ + public void motion(long interval){ + // 1. �ʒu�𓮂��� + ((Solid3D)body).move(interval, getGravity(), getGravityCenter()); + super.motion(interval); + } + + /** + * �P�ʎ��Ԃ��Ƃ̓���i�Փ˔��菈�����s���j + * @param interval --- �O��Ăяo���ꂽ�Ƃ�����̌o�ߎ��ԁi�~���b�P�ʁj + * @param ground --- �n�ʁi�\�����j + */ + public void motion(long interval, Ground ground) { + + // 1. �ʒu�𓮂��� + ((Solid3D)body).move(interval, getGravity(), getGravityCenter()); + + if (animation != null) { + // 2. �A�j���[�V���������s + if (animation.progress(interval) == false) { + onEndAnimation(); + } + + // 3. �p����ς��� + body.apply(animation.getPose(), false); + } + + // 4. �Փ˔��� + CollisionResult cr = PhysicsUtility.doesIntersect((Solid3D)body, ground); + + // 5. �Փˉ��� + if (cr != null) { + // �\�����ɂԂ‚������A�܂��͐ڐG���Ă��鎞 + if (cr.normal.dot(PhysicsUtility.vertical) > GeometryUtility.TOLERANCE) { + // ������̖ʁi���n�ʁj�ɂԂ‚������A�܂��͐ڐG���Ă��鎞 + if (cr.length <= GeometryUtility.TOLERANCE) { + // �n�ʂɏ���Ă��� + if (!(mode instanceof ModeOnGround)) { + // �����Ă��Ē��x����� + mode = modeOnGround; + ((ModeOnGround)mode).setNormal(cr.normal); + onEndFall(); + } + } else { + // �n�ʂɂ߂荞�� + // 5.1. �����߂� + onIntersect(cr, interval); + if (!(mode instanceof ModeOnGround)) { + // �����Ă��Ă߂荞�� + // 6. �n�ʃ��[�h�ɂ��� + mode = modeOnGround; + ((ModeOnGround)mode).setNormal(cr.normal); + onEndFall(); + } else { + // �����Ă���r���ŁA�A�j���[�V�����̊֌W�ň�u�����߂荞�� + // �܂��́A�����Ă���r���ŎΖʂɍ����|������ + ((ModeOnGround)mode).setNormal(cr.normal); + } + } + } else if (cr.normal.dot(PhysicsUtility.vertical) >= -GeometryUtility.TOLERANCE) { + // �����ǂɂ߂荞�� + // 5.1. �����߂� + onIntersect(cr, interval); + } else { + // ������Ԃ‚������A�܂��͐ڐG����(�����Ԃ‚���) + if (cr.length > GeometryUtility.TOLERANCE) { + // 5.1. �����߂� + onIntersect(cr, interval); + } + } + cr = null; + } else { + // �n�ʂƂԂ‚����Ă��ڐG���Ă����Ȃ��� + // 6. �������[�h�ɂ��� + mode = modeFreeFall; + } + } + + public void motion(long interval, Ground ground,ArrayList forces, + ArrayList appPoints) { + + forces.add(getGravity()); + appPoints.add(getGravityCenter()); + + // 1. �ʒu�𓮂��� + ((Solid3D)body).move(interval, forces, appPoints); + + if (animation != null) { + // 2. �A�j���[�V���������s + if (animation.progress(interval) == false) { + onEndAnimation(); + } + + // 3. �p����ς��� + body.apply(animation.getPose(), false); + } + + // 4. �Փ˔��� + CollisionResult cr = PhysicsUtility.doesIntersect((Solid3D)body, ground); + + // 5. �Փˉ��� + if (cr != null) { + // �\�����ɂԂ‚������A�܂��͐ڐG���Ă��鎞 + if (cr.normal.dot(PhysicsUtility.vertical) > GeometryUtility.TOLERANCE) { + // ������̖ʁi���n�ʁj�ɂԂ‚������A�܂��͐ڐG���Ă��鎞 + if (cr.length <= GeometryUtility.TOLERANCE) { + // �n�ʂɏ���Ă��� + if (!(mode instanceof ModeOnGround)) { + // �����Ă��Ē��x����� + mode = modeOnGround; + ((ModeOnGround)mode).setNormal(cr.normal); + onEndFall(); + } + } else { + // �n�ʂɂ߂荞�� + // 5.1. �����߂� + onIntersect(cr, interval); + if (!(mode instanceof ModeOnGround)) { + // �����Ă��Ă߂荞�� + // 6. �n�ʃ��[�h�ɂ��� + mode = modeOnGround; + ((ModeOnGround)mode).setNormal(cr.normal); + onEndFall(); + } else { + // �����Ă���r���ŁA�A�j���[�V�����̊֌W�ň�u�����߂荞�� + // �܂��́A�����Ă���r���ŎΖʂɍ����|������ + ((ModeOnGround)mode).setNormal(cr.normal); + } + } + } else if (cr.normal.dot(PhysicsUtility.vertical) >= -GeometryUtility.TOLERANCE) { + // �����ǂɂ߂荞�� + // 5.1. �����߂� + onIntersect(cr, interval); + } else { + // ������Ԃ‚������A�܂��͐ڐG����(�����Ԃ‚���) + if (cr.length > GeometryUtility.TOLERANCE) { + // 5.1. �����߂� + onIntersect(cr, interval); + } + } + cr = null; + } else { + // �n�ʂƂԂ‚����Ă��ڐG���Ă����Ȃ��� + // 6. �������[�h�ɂ��� + mode = modeFreeFall; + } + } + + public void setInitialDirection(Vector3d dir) { + direction = dir; + } + + public Vector3d getInitialDirection() { + return direction; + } + + /** + * �w�肵�������Ɍ������� + * @param vec �V�������� + */ + public void setDirection(Vector3d vec) { + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + v1.cross(direction, GeometryUtility.Y_AXIS); + v2.cross(vec, GeometryUtility.Y_AXIS); + if (v2.length() < GeometryUtility.TOLERANCE) return; + v1.normalize(); + v2.normalize(); + double cos = v1.dot(v2); + v1.cross(v1, v2); + double sin = v1.dot(GeometryUtility.Y_AXIS); + double angle = Math.atan2(sin, cos); + AxisAngle4d axisAngle = new AxisAngle4d(GeometryUtility.Y_AXIS, angle); + Quaternion3D quat = new Quaternion3D(axisAngle); + ((Solid3D)body).apply(quat, false); + } + + /** + * �w�肵�������Ɍ������� + * @param vec �V�������� + */ + public void setDirection3D(Vector3d vec) { + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + v1.cross(direction, GeometryUtility.Y_AXIS); + double angle = Math.PI / 2.0 - Math.acos(vec.dot(GeometryUtility.Y_AXIS)); + AxisAngle4d axisAngle2 = new AxisAngle4d(v1, angle); + v2.cross(vec, GeometryUtility.Y_AXIS); + if (v2.length() < GeometryUtility.TOLERANCE) return; + v1.normalize(); + v2.normalize(); + double cos = v1.dot(v2); + v1.cross(v1, v2); + double sin = v1.dot(GeometryUtility.Y_AXIS); + angle = Math.atan2(sin, cos); + AxisAngle4d axisAngle = new AxisAngle4d(GeometryUtility.Y_AXIS, angle); + Quaternion3D quat = new Quaternion3D(axisAngle); + Quaternion3D quat2 = new Quaternion3D(axisAngle2); + quat.mul(quat2); + ((Solid3D)body).apply(quat, false); + } + + /** + * ���݌����Ă���������擾���� + * @return ���݂̌��� + */ + public Vector3d getDirection() { + Vector3d dir = new Vector3d(direction); + Transform3D trans = new Transform3D(); + trans.set(((Solid3D)body).getQuaternion().getAxisAngle()); + trans.transform(dir); + return dir; + } + + /** + * �ړ����x�x�N�g����ݒ肷�� + * @param vel �V�����ړ����x�x�N�g�� + */ + public void setVelocity(Velocity3D vel) { + ((Solid3D)body).apply(vel, false); + } + + /** + * �ړ����x�x�N�g�����擾���� + * @return ���݂̈ړ����x�x�N�g�� + */ + public Velocity3D getVelocity() { + return ((Solid3D)body).getVelocity(); + } + + /** + * X���𒆐S�ɉ�]���� + * @param angle ��]�p�i�����v���, �P��:���W�A���j + */ + public void rotX(double angle) { + Quaternion3D curQuat = body.getQuaternion(); + curQuat.add(new AxisAngle4d(GeometryUtility.X_AXIS, angle)); + body.apply(curQuat, false); + } + + /** + * Y���𒆐S�ɉ�]���� + * @param angle ��]�p�i�����v���, �P��:���W�A���j + */ + public void rotY(double angle) { + Quaternion3D curQuat = body.getQuaternion(); + curQuat.add(new AxisAngle4d(GeometryUtility.Y_AXIS, angle)); + body.apply(curQuat, false); + } + + /** + * Z���𒆐S�ɉ�]���� + * @param angle ��]�p�i�����v���, �P��:���W�A���j + */ + public void rotZ(double angle) { + Quaternion3D curQuat = body.getQuaternion(); + curQuat.add(new AxisAngle4d(GeometryUtility.Z_AXIS, angle)); + body.apply(curQuat, false); + } + + /** + * ������Ă���d�͂��擾���� + * @return �d�� + */ + public Force3D getGravity() { + return mode.getForce((Solid3D)body); + } + + /** + * �d�S���擾���� + * @return �d�S�ʒu + */ + public Position3D getGravityCenter() { + return ((Solid3D)body).getGravityCenter(); + } + + /** + * �n�ʂɏ���Ă����Ԃ��ۂ����擾���� + * @return true --- �n�ʂɏ���Ă���, false --- �n�ʂɏ���Ă��Ȃ��i�󒆂ɂ���j + */ + public boolean isOnGround() { + return (mode instanceof ModeOnGround); + } + + /** + * �n�ʁi�\�����j�ɗ��������u�ԂɌĂяo����� + */ + public abstract void onEndFall(); + + /** + * �n�ʁi�\�����j�ɏՓ˂����u�ԂɌĂяo����� + * @param normal --- �n�ʂ̖@�������x�N�g�� + * @param interval --- �O��̓��삩��̌o�ߎ��ԁi�~���b�P�ʁj + */ + public abstract void onIntersect(CollisionResult normal, long interval); + +} diff --git a/src/main/java/framework/gameMain/ActorModel.java b/src/main/java/framework/gameMain/ActorModel.java new file mode 100644 index 0000000..1ef7b5a --- /dev/null +++ b/src/main/java/framework/gameMain/ActorModel.java @@ -0,0 +1,14 @@ +package framework.gameMain; +import framework.physics.Solid3D; + + +public abstract class ActorModel extends GameModel { + + public ActorModel(String fileName) { + super(fileName); + } + + public Solid3D createBody() { + return new Solid3D(getModel().createObject()); + } +} diff --git a/src/main/java/framework/gameMain/Animatable.java b/src/main/java/framework/gameMain/Animatable.java new file mode 100644 index 0000000..8258207 --- /dev/null +++ b/src/main/java/framework/gameMain/Animatable.java @@ -0,0 +1,57 @@ +package framework.gameMain; + +import javax.media.j3d.TransformGroup; + +import framework.animation.Animation3D; +import framework.model3D.BaseObject3D; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Placeable; + +public abstract class Animatable implements Placeable { + public Object3D body; + public Animation3D animation; + + public Animatable(Object3D body, Animation3D animation) { + this.body = body; + this.animation = animation; + } + + /** + * �P�ʎ��Ԃ��Ƃ̓���i�A�j���[�V���������j + * @param interval --- �O��Ăяo���ꂽ�Ƃ�����̌o�ߎ��ԁi�~���b�P�ʁj + */ + public void motion(long interval) { + if (animation != null) { + // 1. �A�j���[�V���������s + if (animation.progress(interval) == false) { + onEndAnimation(); + } + + // 2. �p����ς��� + body.apply(animation.getPose(), false); + } + } + + public TransformGroup getTransformGroupToPlace() { + return getBody().getTransformGroupToPlace(); + } + + public BaseObject3D getBody() { + return body; + } + + /** + * �A�j���[�V�������I�����邽�тɌĂ΂�� + */ + public abstract void onEndAnimation(); + + public Position3D getPosition() { + return body.getPosition3D(); + } + + public void setPosition(Position3D p) { + body.apply(p, false); + } + +} \ No newline at end of file diff --git a/src/main/java/framework/gameMain/BaseGame.java b/src/main/java/framework/gameMain/BaseGame.java new file mode 100644 index 0000000..604f6bc --- /dev/null +++ b/src/main/java/framework/gameMain/BaseGame.java @@ -0,0 +1,50 @@ +package framework.gameMain; + +import java.util.Stack; +import java.util.Timer; +import java.util.TimerTask; + +/** + * ��ʓI�ȃQ�[���p�̃N���X�i��ԑJ�ڂ����‚��Ƃ��ł���j + * @author �V�c���� + * + */ +public abstract class BaseGame extends AbstractGame { + Stack gameStateStack = new Stack(); + + public abstract AbstractGameState getInitialGameState(); + public abstract boolean canGoPrevGameState(); + public abstract AbstractGameState changeNextGameState(); + + public BaseGame() { + super(); + pushNewGameState(getInitialGameState()); + } + + protected AbstractGameState getCurrentGameState() { + return gameStateStack.peek(); + } + + public void goNextGameState(){ + deactivateState(getCurrentGameState()); + AbstractGameState g = changeNextGameState(); + pushNewGameState(g); + activateState(g); + } + + public void goPrevGameState(){ + if(canGoPrevGameState()){ + deactivateState(getCurrentGameState()); + popGameState(); + activateState(getCurrentGameState()); + } + } + + private void pushNewGameState(AbstractGameState g) { + gameStateStack.push(g); + } + + private void popGameState() { + gameStateStack.pop(); + } +} diff --git a/src/main/java/framework/gameMain/BaseScenarioGameContainer.java b/src/main/java/framework/gameMain/BaseScenarioGameContainer.java new file mode 100644 index 0000000..fe4a9bd --- /dev/null +++ b/src/main/java/framework/gameMain/BaseScenarioGameContainer.java @@ -0,0 +1,52 @@ +package framework.gameMain; + +import java.awt.GraphicsConfiguration; + +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTLabel; +import framework.scenario.ScenarioManager; + +/** + * �V�i���I�Q�[���p��� + * @author Nitta + * + */ +abstract public class BaseScenarioGameContainer extends RWTContainer { + protected RWTCanvas3D canvas; + protected RWTLabel dialog; + protected ScenarioManager scenario; + + public BaseScenarioGameContainer(ScenarioManager scenario) { + this.scenario = scenario; + } + + @Override + public void build(GraphicsConfiguration gc) { + if (gc != null) { + canvas = new RWTCanvas3D(gc); + } else { + canvas = new RWTCanvas3D(); + } + dialog = new RWTLabel(); + } + + public void dialogOpen() { + dialog.setVisible(true); + repaint(); + } + + public void dialogClose() { + dialog.setVisible(false); + repaint(); + } + + public void dialogMessage(String message) { + dialog.setString(message); + repaint(); + } + + public boolean isDialogOpen() { + return dialog.isVisible(); + } +} diff --git a/src/main/java/framework/gameMain/GameModel.java b/src/main/java/framework/gameMain/GameModel.java new file mode 100644 index 0000000..6033169 --- /dev/null +++ b/src/main/java/framework/gameMain/GameModel.java @@ -0,0 +1,29 @@ +package framework.gameMain; +import framework.animation.Animation3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; + +public class GameModel { + + private Model3D model = null; + private String fileName; + + public GameModel(String fileName) { + this.fileName = fileName; + } + + public Animation3D getAnimation() { + return new Animation3D(); + } + + public Model3D getModel() { + if(model == null && fileName != null) { + model = ModelFactory.loadModel(fileName, false, true); + } + return model; + } + + public void clearModel(){ + model = null; + } +} \ No newline at end of file diff --git a/src/main/java/framework/gameMain/IGameState.java b/src/main/java/framework/gameMain/IGameState.java new file mode 100644 index 0000000..267cee5 --- /dev/null +++ b/src/main/java/framework/gameMain/IGameState.java @@ -0,0 +1,9 @@ +package framework.gameMain; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTVirtualController; + +public interface IGameState { + public abstract void init(RWTFrame3D frame); + public abstract boolean useTimer(); + public abstract void update(RWTVirtualController virtualController, long interval); +} \ No newline at end of file diff --git a/src/main/java/framework/gameMain/Mode.java b/src/main/java/framework/gameMain/Mode.java new file mode 100644 index 0000000..e7ebe1a --- /dev/null +++ b/src/main/java/framework/gameMain/Mode.java @@ -0,0 +1,10 @@ +package framework.gameMain; +import framework.physics.Force3D; +import framework.physics.Solid3D; + + +public abstract class Mode { + + abstract Force3D getForce(Solid3D body); + +} diff --git a/src/main/java/framework/gameMain/ModeFreeFall.java b/src/main/java/framework/gameMain/ModeFreeFall.java new file mode 100644 index 0000000..97c4b95 --- /dev/null +++ b/src/main/java/framework/gameMain/ModeFreeFall.java @@ -0,0 +1,11 @@ +package framework.gameMain; +import framework.physics.Force3D; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; + + +public class ModeFreeFall extends Mode { + Force3D getForce(Solid3D body) { + return PhysicsUtility.getGravity(body); + } +} diff --git a/src/main/java/framework/gameMain/ModeOnGround.java b/src/main/java/framework/gameMain/ModeOnGround.java new file mode 100644 index 0000000..f28a6aa --- /dev/null +++ b/src/main/java/framework/gameMain/ModeOnGround.java @@ -0,0 +1,24 @@ +package framework.gameMain; + +import javax.vecmath.Vector3d; + +import framework.physics.Force3D; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; + + +public class ModeOnGround extends Mode { + private Vector3d normal = PhysicsUtility.vertical; + + public Force3D getForce(Solid3D body) { + return Force3D.ZERO; + } + + public void setNormal(Vector3d normal) { + this.normal = normal; + } + + public Vector3d getNormal() { + return normal; + } +} diff --git a/src/main/java/framework/gameMain/MultiViewGame.java b/src/main/java/framework/gameMain/MultiViewGame.java new file mode 100644 index 0000000..25b2de5 --- /dev/null +++ b/src/main/java/framework/gameMain/MultiViewGame.java @@ -0,0 +1,102 @@ +package framework.gameMain; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.BranchGroup; +import javax.media.j3d.GraphicsConfigTemplate3D; + +import com.sun.j3d.utils.universe.SimpleUniverse; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +/** + * ��ԑJ�ڂ̂Ȃ��Q�[���p�̃N���X + * @author �V�c���� + * + */ +public abstract class MultiViewGame extends AbstractGame implements IGameState { + protected Universe universe; + protected Camera3D camera1; + protected Camera3D camera2; + protected RWTContainer container; + + public abstract void init(Universe universe, Camera3D camera1, Camera3D camera2); + public abstract void progress(RWTVirtualController virtualController, long interval); + + @Override + protected IGameState getCurrentGameState() { + return this; + } + + @Override + public boolean useTimer() { + return true; + } + + @Override + public void init(RWTFrame3D frame) { + container = new RWTContainer() { + @Override + public void build(GraphicsConfiguration gc) { + RWTCanvas3D canvas1, canvas2; + if (gc != null) { + canvas1 = new RWTCanvas3D(gc); + canvas2 = new RWTCanvas3D(gc); + } else { + canvas1 = new RWTCanvas3D(); + canvas2 = new RWTCanvas3D(); + } + canvas1.setRelativePosition(0.0f, 0.0f); + canvas1.setRelativeSize(0.5f, 1.0f); + canvas2.setRelativePosition(0.5f, 0.0f); + canvas2.setRelativeSize(0.5f, 1.0f); + addCanvas(canvas1); + addCanvas(canvas2); + + repaint(); + } + // RWT���ł̓C�x���g���������Ȃ� + @Override + public void keyPressed(RWTVirtualKey key) {} + @Override + public void keyReleased(RWTVirtualKey key) {} + @Override + public void keyTyped(RWTVirtualKey key) {} + }; + frame.setContentPane(container); + GraphicsConfiguration gc = null; + if (frame.isShadowCasting()) { + // �e��t����ꍇ + // �X�e���V���o�b�t�@���g�p���� GraphicsConfiguration �̐��� + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); + gct3D.setStencilSize(8); + gc = gd.getBestConfiguration(gct3D); + } + container.build(gc); + + universe = new Universe(); + camera1 = new Camera3D(universe); + camera2 = new Camera3D(universe); + init(universe, camera1, camera2); + container.getRWTCanvas3D(0).attachCamera(camera1); + container.getRWTCanvas3D(1).attachCamera(camera2); + universe.compile(); + } + + @Override + public void update(RWTVirtualController virtualController, long interval) { + progress(virtualController, interval); + camera1.adjust(interval); + camera2.adjust(interval); + } +} diff --git a/src/main/java/framework/gameMain/OvergroundActor.java b/src/main/java/framework/gameMain/OvergroundActor.java new file mode 100644 index 0000000..7b609d2 --- /dev/null +++ b/src/main/java/framework/gameMain/OvergroundActor.java @@ -0,0 +1,51 @@ +package framework.gameMain; + +import javax.vecmath.Vector3d; + +import framework.animation.Animation3D; +import framework.model3D.CollisionResult; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.physics.Solid3D; +import framework.physics.Velocity3D; + +/** + * �n�ʂ̏���ړ�������́i�W�����v�⎩�R���������邱�Ƃ��”\�j + * @author �V�c���� + * + */ +public class OvergroundActor extends Actor { + + public OvergroundActor(Object3D body, Animation3D animation) { + super(body, animation); + } + + public OvergroundActor(Solid3D body, Animation3D animation) { + super(body, animation); + } + + public OvergroundActor(ActorModel model) { + super(model); + } + + public void onIntersect(CollisionResult cr, long interval) { + // �߂荞�񂾂�i�߂荞�񂾖ʂ̖@�������Ɂj�����߂� + Vector3d back = (Vector3d) cr.normal.clone(); + back.scale(cr.length * 2.0); + body.apply(new Position3D(body.getPosition3D().add(back)), false); + + // ���x�̖ʂ̖@�������̐����� 0 �ɂ��� + Vector3d v = (Vector3d) ((Solid3D)body).getVelocity().getVector3d().clone(); + double d = v.dot(cr.normal); + v.scaleAdd(-d, cr.normal, v); + body.apply(new Velocity3D(v), false); + } + + @Override + public void onEndFall() { + } + + @Override + public void onEndAnimation() { + } +} \ No newline at end of file diff --git a/src/main/java/framework/gameMain/SimpleGame.java b/src/main/java/framework/gameMain/SimpleGame.java new file mode 100644 index 0000000..cb6950f --- /dev/null +++ b/src/main/java/framework/gameMain/SimpleGame.java @@ -0,0 +1,100 @@ +package framework.gameMain; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.GraphicsConfigTemplate3D; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +/** + * ��ԑJ�ڂ̂Ȃ��Q�[���p�̃N���X + * @author �V�c���� + * + */ +public abstract class SimpleGame extends AbstractGame implements IGameState { + protected Universe universe; + protected Camera3D camera; + private IGameState currentState = this; + + public abstract void init(Universe universe, Camera3D camera); + public abstract void progress(RWTVirtualController virtualController, long interval); + + @Override + protected IGameState getCurrentGameState() { + return currentState; + } + + protected void setCurrentGameState(IGameState state) { + currentState = state; + } + + @Override + public boolean useTimer() { + return true; + } + + @Override + public void init(RWTFrame3D frame) { + RWTContainer container = createRWTContainer(); + frame.setContentPane(container); + GraphicsConfiguration gc = null; + if (frame.isShadowCasting()) { + // �e��t����ꍇ + // �X�e���V���o�b�t�@���g�p���� GraphicsConfiguration �̐��� + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); + gct3D.setStencilSize(8); + gc = gd.getBestConfiguration(gct3D); + } + container.build(gc); + + universe = new Universe(); + camera = new Camera3D(universe); +// universe.setCamera(camera); +// SceneGraph root = new SceneGraph(); +// universe.setRoot(root); + init(universe, camera); + container.getPrimaryRWTCanvas3D().attachCamera(camera); + universe.compile(); + } + + @Override + public void update(RWTVirtualController virtualController, long interval) { + progress(virtualController, interval); + camera.adjust(interval); + } + + protected RWTContainer createRWTContainer() { + return new RWTContainer() { + @Override + public void build(GraphicsConfiguration gc) { + RWTCanvas3D canvas; + if (gc != null) { + canvas = new RWTCanvas3D(gc); + } else { + canvas = new RWTCanvas3D(); + } + canvas.setRelativePosition(0.0f, 0.0f); + canvas.setRelativeSize(1.0f, 1.0f); + addCanvas(canvas); + repaint(); + } + // RWT���ł̓C�x���g���������Ȃ� + @Override + public void keyPressed(RWTVirtualKey key) {} + @Override + public void keyReleased(RWTVirtualKey key) {} + @Override + public void keyTyped(RWTVirtualKey key) {} + }; + } +} diff --git a/src/main/java/framework/gameMain/SimpleScenarioGame.java b/src/main/java/framework/gameMain/SimpleScenarioGame.java new file mode 100644 index 0000000..7384e36 --- /dev/null +++ b/src/main/java/framework/gameMain/SimpleScenarioGame.java @@ -0,0 +1,42 @@ +package framework.gameMain; + +import framework.scenario.IWorld; +import framework.scenario.ScenarioManager; + +/** + * �V�i���I�쓮�^�Q�[���̂��߂̃e���v���[�g + * @author �V�c���� + * + */ +abstract public class SimpleScenarioGame extends SimpleGame implements IWorld { + protected BaseScenarioGameContainer container; + protected ScenarioManager scenario; + + @Override + public void dialogOpen() { + container.dialogOpen(); + } + + @Override + public void dialogClose() { + container.dialogClose(); + } + + @Override + public void dialogMessage(String message) { + container.dialogMessage(message); + } + + @Override + public void showOption(int n, String option) { + } + + @Override + public boolean isDialogOpen() { + return container.isDialogOpen(); + } + + public void setScenario(String scenarioFile) { + scenario = new ScenarioManager(scenarioFile, this); + } +} diff --git a/src/main/java/framework/gameMain/Water.java b/src/main/java/framework/gameMain/Water.java new file mode 100644 index 0000000..3573405 --- /dev/null +++ b/src/main/java/framework/gameMain/Water.java @@ -0,0 +1,210 @@ +package framework.gameMain; + +import javax.media.j3d.Appearance; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DistanceLOD; +import javax.media.j3d.IndexedQuadArray; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Switch; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.Texture; +import javax.media.j3d.TransparencyAttributes; +import javax.vecmath.Color3f; +import javax.vecmath.Color4f; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; +import javax.vecmath.Vector4f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.animation.Animation3D; +import framework.animation.PartAnimation; +import framework.model3D.BumpMapGenerator; +import framework.model3D.FresnelsReflectionMapGenerator; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.ReflectionMapGenerator; + +/** + * ���ʂ�\������I�u�W�F�N�g�B + * �g�̓����̓o���v�}�b�s���O���X�N���[�������ĕ\�����Ă���B + * ���˂ł̓t���l�����ʂ��������Ă���B + * Java3D�ł́A���_�Ԃ̔��˃x�N�g���͐��`��Ԃł������߂Ă��Ȃ����߁A + * ���x���グ�邽�߂ɁALOD���g���Đ��ʂ̎��_�ɋ߂������̓��b�V���������ׂ������Ă���B + * @author Nitta + * + */ +public class Water extends Animatable { + private static int DEFAULT_FIRST_LEVEL_MESH_SIZE = 25; + private static int DEFAULT_SECOND_LEVEL_MESH_SIZE = 1; + private static int DEFAULT_THIRD_LEVEL_MESH_SIZE = 40; + + public Water(double minX, double minZ, double maxX, double maxZ, double height, boolean bUseLOD) { + this(minX, minZ, maxX, maxZ, height, 0.5f, bUseLOD); + } + + public Water(double minX, double minZ, double maxX, double maxZ, double height, float transparency, boolean bUseLOD) { + this(minX, minZ, maxX, maxZ, height, transparency, 0.3f, bUseLOD); + } + + public Water(double minX, double minZ, double maxX, double maxZ, double height, float transparency, float reflection, boolean bUseLOD) { + this(minX, minZ, maxX, maxZ, height, transparency, reflection, new Color3f(0.2f, 0.5f, 1.0f), bUseLOD); + } + + public Water(double minX, double minZ, double maxX, double maxZ, double height, + float transparency, float reflection, Color3f waterColor, boolean bUseLOD) { + this(minX, minZ, maxX, maxZ, height, transparency, reflection, new Color3f(0.2f, 0.5f, 1.0f), + DEFAULT_FIRST_LEVEL_MESH_SIZE, DEFAULT_SECOND_LEVEL_MESH_SIZE, DEFAULT_THIRD_LEVEL_MESH_SIZE, bUseLOD); + } + + public Water(double minX, double minZ, double maxX, double maxZ, double height, float transparency, float reflection, + int firstLevelMeshSize, int secondLevelMeshSize, int thirdLevelMeshSize, boolean bUseLOD) { + this(minX, minZ, maxX, maxZ, height, transparency, reflection, new Color3f(0.2f, 0.5f, 1.0f), + firstLevelMeshSize, secondLevelMeshSize, thirdLevelMeshSize, bUseLOD); + } + + public Water(double minX, double minZ, double maxX, double maxZ, double height, float transparency, float reflection, Color3f waterColor, + int firstLevelMeshSize, int secondLevelMeshSize, int thirdLevelMeshSize, boolean bUseLOD) { + super(null, null); + + int firstLevelMeshSizeX = firstLevelMeshSize; + int firstLevelMeshSizeZ = firstLevelMeshSize; + int secondLevelMeshSizeX = secondLevelMeshSize; + int secondLevelMeshSizeZ = secondLevelMeshSize; + int thirdLevelMeshSizeX = thirdLevelMeshSize; + int thirdLevelMeshSizeZ = thirdLevelMeshSize; + + + // ���ʂ̃W�I���g���̍쐬 + IndexedQuadArray coarseWaterGeometry = + new IndexedQuadArray((secondLevelMeshSizeX + 1) * (secondLevelMeshSizeZ + 1), + IndexedQuadArray.COORDINATES | IndexedQuadArray.NORMALS, 4 * secondLevelMeshSizeX * secondLevelMeshSizeZ); + + IndexedQuadArray fineWaterGeometry = + new IndexedQuadArray((secondLevelMeshSizeX * thirdLevelMeshSizeX + 1) * (secondLevelMeshSizeZ * thirdLevelMeshSizeZ + 1), + IndexedQuadArray.COORDINATES | IndexedQuadArray.NORMALS, 4 * secondLevelMeshSizeX * thirdLevelMeshSizeX * secondLevelMeshSizeZ * thirdLevelMeshSizeZ); + + double unitSizeX1 = (maxX - minX) / firstLevelMeshSizeX; + double unitSizeZ1 = (maxZ - minZ) / firstLevelMeshSizeZ; + double unitSizeX2 = unitSizeX1 / secondLevelMeshSizeX; + double unitSizeZ2 = unitSizeZ1 / secondLevelMeshSizeZ; + double unitSizeX3 = unitSizeX2 / thirdLevelMeshSizeX; + double unitSizeZ3 = unitSizeZ2 / thirdLevelMeshSizeZ; + double baseX = -(maxX - minX) / firstLevelMeshSizeX / 2.0; + double baseZ = -(maxZ - minZ) / firstLevelMeshSizeZ / 2.0; + + // ���A��O���x���� LOD �Ő؂�ւ� + for (int z2 = 0; z2 < secondLevelMeshSizeZ + 1; z2++) { + for (int x2 = 0; x2 < secondLevelMeshSizeX + 1; x2++) { + int indexX2 = x2; + int indexZ2 = z2; + int index20 = indexZ2 * secondLevelMeshSizeX + indexX2; + int index21 = indexZ2 * (secondLevelMeshSizeX + 1) + indexX2; + int index22 = (indexZ2 + 1) * (secondLevelMeshSizeX + 1) + indexX2; + double xx2 = baseX + unitSizeX2 * indexX2; + double zz2 = baseZ + unitSizeZ2 * indexZ2; + coarseWaterGeometry.setCoordinate(index21, new Point3d(xx2, 0.0, zz2)); + coarseWaterGeometry.setNormal(index21, new Vector3f(0.0f, 1.0f, 0.0f)); + if (indexX2 < secondLevelMeshSizeX && indexZ2 < secondLevelMeshSizeZ) { + coarseWaterGeometry.setCoordinateIndices(index20 * 4, new int[]{index22, index22 + 1, index21 + 1, index21}); + if (bUseLOD) { + for (int z3 = 0; z3 < thirdLevelMeshSizeZ + 1; z3++) { + for (int x3 = 0; x3 < thirdLevelMeshSizeX + 1; x3++) { + int indexX3 = x2 * thirdLevelMeshSizeX + x3; + int indexZ3 = z2 * thirdLevelMeshSizeZ + z3; + int index30 = indexZ3 * (secondLevelMeshSizeX * thirdLevelMeshSizeX) + indexX3; + int index31 = indexZ3 * (secondLevelMeshSizeX * thirdLevelMeshSizeX + 1) + indexX3; + int index32 = (indexZ3 + 1) * (secondLevelMeshSizeX * thirdLevelMeshSizeX + 1) + indexX3; + double xx3 = baseX + unitSizeX3 * indexX3; + double zz3 = baseZ + unitSizeZ3 * indexZ3; + fineWaterGeometry.setCoordinate(index31, new Point3d(xx3, 0.0, zz3)); + fineWaterGeometry.setNormal(index31, new Vector3f(0.0f, 1.0f, 0.0f)); + if (indexX3 < secondLevelMeshSizeX * thirdLevelMeshSizeX + && indexZ3 < secondLevelMeshSizeZ * thirdLevelMeshSizeZ) { + fineWaterGeometry.setCoordinateIndices(index30 * 4, new int[]{index32, index32 + 1, index31 + 1, index31}); + } + } + } + } + } + } + } + + // ��ꃌ�x���� Object3D �̏W���ō\�� + Object3D children[] = new Object3D[firstLevelMeshSizeX * firstLevelMeshSizeZ]; + TextureLoader loaderWater = new TextureLoader("data\\texture\\waternormalMap.jpg", + TextureLoader.BY_REFERENCE, + null); + Texture textureWater = loaderWater.getTexture(); + // ���ʂ̕\�ʑ����̍쐬�i�S�̂ŋ��L����j + Appearance a = new Appearance(); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + Material m1 = new Material(); + m1.setDiffuseColor(waterColor); // ���̐F + m1.setSpecularColor(0.0f, 0.0f, 0.0f); + a.setMaterial(m1); + ColoringAttributes ca = new ColoringAttributes(); + ca.setShadeModel(ColoringAttributes.NICEST); + a.setColoringAttributes(ca); + + TransparencyAttributes ta = new TransparencyAttributes(); + ta.setTransparency(transparency); // �����x + ta.setTransparencyMode(TransparencyAttributes.BLENDED); + a.setTransparencyAttributes(ta); + // �g���\�ʑ����i�S�̂ŋ��L����j + TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_3); + tcg.setPlaneS(new Vector4f(0.1f, 0.0f, 0.0f, 0.0f)); + tcg.setPlaneT(new Vector4f(0.0f, 0.0f, 0.1f, 0.0f)); + BumpMapGenerator bumpMapGenerator = new BumpMapGenerator(textureWater, tcg, true); // �e�N�X�`�����j�b�g��1�Žg�p + FresnelsReflectionMapGenerator fresnelsReflectionMapGenerator = + new FresnelsReflectionMapGenerator(new Color4f(reflection, reflection, reflection, 1.0f), true); // �e�N�X�`�����j�b�g��2�Žg�p + + for (int z1 = 0; z1 < firstLevelMeshSizeZ; z1++) { + for (int x1 = 0; x1 < firstLevelMeshSizeX; x1++) { + double xx1 = minX + (maxX - minX) / firstLevelMeshSizeX * x1; + double zz1 = minZ + (maxZ - minZ) / firstLevelMeshSizeZ * z1; + Object3D waterSurfaceUnit; + if (bUseLOD) { + DistanceLOD lod = new DistanceLOD(); + Switch surfaceSwitch = new Switch(); + surfaceSwitch.addChild(new Shape3D(fineWaterGeometry, a)); + surfaceSwitch.addChild(new Shape3D(coarseWaterGeometry, a)); + lod.addSwitch(surfaceSwitch); + lod.setDistance(0, unitSizeX1 / 2.0); + lod.setPosition(new Point3f(0.0f, 0.0f, 0.0f)); + waterSurfaceUnit = new Object3D("waterUnit", lod); + } else { + waterSurfaceUnit = new Object3D("waterUnit", new Shape3D(coarseWaterGeometry, a)); + } + waterSurfaceUnit.apply(new Position3D(xx1, height, zz1), false); + + // �g���\�ʑ�����ݒ� + waterSurfaceUnit.setBumpMapping(bumpMapGenerator); + waterSurfaceUnit.setReflectionMapping(fresnelsReflectionMapGenerator); + + children[z1 * firstLevelMeshSizeX + x1] = waterSurfaceUnit; + } + } + + // �S�̃I�u�W�F�N�g���\�� + Object3D waterSurface = new Object3D("water", children); + + body = waterSurface; + + // �A�j���[�V�����̍쐬 + Animation3D waveAnimation = new Animation3D(); + PartAnimation pa = new PartAnimation("waterUnit", 0); + pa.addTexture(0L, new Position3D(0.0, 0.0, 0.0)); + pa.addTexture(10000L, new Position3D(1.0, -1.0, 0.0)); + waveAnimation.addPartAnimation(pa); + animation = waveAnimation; + } + + @Override + public void onEndAnimation() { + } +} diff --git a/src/main/java/framework/model3D/BackgroundBox.java b/src/main/java/framework/model3D/BackgroundBox.java new file mode 100644 index 0000000..bef8956 --- /dev/null +++ b/src/main/java/framework/model3D/BackgroundBox.java @@ -0,0 +1,154 @@ +package framework.model3D; + +import javax.media.j3d.Appearance; +import javax.media.j3d.Background; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.QuadArray; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Texture; +import javax.vecmath.Point3d; +import javax.vecmath.TexCoord2f; + + +public class BackgroundBox extends Background { + Texture northTex; + Texture westTex; + Texture southTex; + Texture eastTex; + Texture topTex; + Texture bottomTex; + + public BackgroundBox(Texture northTex, Texture westTex, Texture southTex, Texture eastTex, Texture topTex, Texture bottomTex) { + this.northTex = northTex; + this.westTex = westTex; + this.southTex = southTex; + this.eastTex = eastTex; + this.topTex = topTex; + this.bottomTex = bottomTex; + Point3d p0 = new Point3d(-1.0,-1.0,-1.0); + Point3d p1 = new Point3d(-1.0,-1.0, 1.0); + Point3d p2 = new Point3d(-1.0, 1.0,-1.0); + Point3d p3 = new Point3d(-1.0, 1.0, 1.0); + Point3d p4 = new Point3d( 1.0, 1.0,-1.0); + Point3d p5 = new Point3d( 1.0, 1.0, 1.0); + Point3d p6 = new Point3d( 1.0,-1.0,-1.0); + Point3d p7 = new Point3d( 1.0,-1.0, 1.0); + QuadArray top = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + top.setCoordinate(0, p4); + top.setCoordinate(1, p5); + top.setCoordinate(2, p3); + top.setCoordinate(3, p2); + top.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + top.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + top.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + top.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + QuadArray bottom = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + bottom.setCoordinate(0, p7); + bottom.setCoordinate(1, p6); + bottom.setCoordinate(2, p0); + bottom.setCoordinate(3, p1); + bottom.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + bottom.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + bottom.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + bottom.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + QuadArray north = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + north.setCoordinate(0, p4); + north.setCoordinate(1, p6); + north.setCoordinate(2, p7); + north.setCoordinate(3, p5); + north.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + north.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + north.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + north.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + QuadArray south = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + south.setCoordinate(0, p3); + south.setCoordinate(1, p1); + south.setCoordinate(2, p0); + south.setCoordinate(3, p2); + south.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + south.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + south.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + south.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + QuadArray east = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + east.setCoordinate(0, p2); + east.setCoordinate(1, p0); + east.setCoordinate(2, p6); + east.setCoordinate(3, p4); + east.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + east.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + east.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + east.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + QuadArray west = new QuadArray(4, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); + west.setCoordinate(0, p5); + west.setCoordinate(1, p7); + west.setCoordinate(2, p1); + west.setCoordinate(3, p3); + west.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f)); + west.setTextureCoordinate(0, 1, new TexCoord2f(1.0f, 1.0f)); + west.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 1.0f)); + west.setTextureCoordinate(0, 3, new TexCoord2f(0.0f, 0.0f)); + Appearance apTop = new Appearance(); + apTop.setTexture(topTex); + Shape3D shapeTop = new Shape3D(top, apTop); + + Appearance apBottom = new Appearance(); + apBottom.setTexture(bottomTex); + Shape3D shapeBottom = new Shape3D(bottom, apBottom); + + Appearance apNorth = new Appearance(); + apNorth.setTexture(northTex); + Shape3D shapeNorth = new Shape3D(north, apNorth); + + Appearance apSouth = new Appearance(); + apSouth.setTexture(southTex); + Shape3D shapeSouth = new Shape3D(south, apSouth); + + Appearance apWest = new Appearance(); + apWest.setTexture(westTex); + Shape3D shapeWest = new Shape3D(west, apWest); + + Appearance apEast = new Appearance(); + apEast.setTexture(eastTex); + Shape3D shapeEast = new Shape3D(east, apEast); + + BranchGroup bg = new BranchGroup(); + bg.addChild(shapeTop); + bg.addChild(shapeBottom); + bg.addChild(shapeNorth); + bg.addChild(shapeSouth); + bg.addChild(shapeWest); + bg.addChild(shapeEast); + + setGeometry(bg); + } + + public ImageComponent2D getNorthImage() { + return (ImageComponent2D)northTex.getImage(0); + } + + + public ImageComponent2D getSouthImage() { + return (ImageComponent2D)southTex.getImage(0); + } + + + public ImageComponent2D getEastImage() { + return (ImageComponent2D)eastTex.getImage(0); + } + + + public ImageComponent2D getWestImage() { + return (ImageComponent2D)westTex.getImage(0); + } + + + public ImageComponent2D getTopImage() { + return (ImageComponent2D)topTex.getImage(0); + } + + + public ImageComponent2D getBottomImage() { + return (ImageComponent2D)bottomTex.getImage(0); + } +} diff --git a/src/main/java/framework/model3D/BaseObject3D.java b/src/main/java/framework/model3D/BaseObject3D.java new file mode 100644 index 0000000..957c87b --- /dev/null +++ b/src/main/java/framework/model3D/BaseObject3D.java @@ -0,0 +1,489 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Enumeration; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingPolytope; +import javax.media.j3d.Geometry; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.IndexedTriangleFanArray; +import javax.media.j3d.IndexedTriangleStripArray; +import javax.media.j3d.Light; +import javax.media.j3d.Node; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.TriangleArray; +import javax.media.j3d.TriangleFanArray; +import javax.media.j3d.TriangleStripArray; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; + +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.Cone; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Primitive; +import com.sun.j3d.utils.geometry.Sphere; + +public class BaseObject3D implements Placeable { + public TransformGroup center; + + protected BoundingSurface[] boundingSurfaces = null; + private ArrayList shadowVolumes = new ArrayList(); + + private BumpMapGenerator bumpMapGenerator = null; + private ReflectionMapGenerator reflectionMapGenerator = null; + protected boolean bBumpMapApplied = false; + protected boolean bReflectionMapApplied = false; + + public BaseObject3D() { + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + } + + public BaseObject3D(Geometry g, Appearance a) { + init(g, a); + } + + // �R�s�[�R���X�g���N�^ + public BaseObject3D(BaseObject3D obj) { + Transform3D transCenter = new Transform3D(); + obj.center.getTransform(transCenter); + this.center = new TransformGroup(transCenter); + this.center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + this.center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Enumeration nodes = obj.getPrimitiveNodes(); + for (; nodes.hasMoreElements();) { + Node node = nodes.nextElement(); + if (node != null && node instanceof Shape3D) { + Shape3D shape = (Shape3D)node; + shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + Appearance a = (Appearance)shape.getAppearance().cloneNodeComponent(true); + a.setCapability(Appearance.ALLOW_TEXTURE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + this.center.addChild(new Shape3D((Geometry) shape + .getAllGeometries().nextElement(), a)); + } else if (node != null && node instanceof Primitive) { + Primitive primitive = (Primitive)node; + primitive = (Primitive)primitive.cloneTree(); + primitive.setCapability(Primitive.ENABLE_APPEARANCE_MODIFY); + this.center.addChild(primitive); + } + } + if (obj.boundingSurfaces != null) { + this.boundingSurfaces = obj.boundingSurfaces; + } + this.bumpMapGenerator = obj.bumpMapGenerator; + this.reflectionMapGenerator = obj.reflectionMapGenerator; + this.bBumpMapApplied = obj.bBumpMapApplied; + this.bReflectionMapApplied = obj.bReflectionMapApplied; + } + + // �����𕡐�����i�N���[�������j + public BaseObject3D duplicate() { + BaseObject3D obj = new BaseObject3D(this); + return obj; + } + + public void init(Geometry g, Appearance a) { + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + Shape3D shape = new Shape3D(g, a); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + center.addChild(shape); + } + + public void updateGeometry(Geometry g) { + Node node = getPrimitiveNode(); + if (node != null && node instanceof Shape3D) { + ((Shape3D)node).removeAllGeometries(); + ((Shape3D)node).addGeometry(g); + boundingSurfaces = null; + } + } + + @Override + public TransformGroup getTransformGroupToPlace() { + return getBody().center; + } + + public BaseObject3D getBody() { + return this; + } + +// public void placeFirst(RWTUniverse universe) { +// universe.getRoot().insertChild(this.center, 0); +// } +// +// public void placeLast(RWTUniverse universe) { +// universe.getRoot().addChild(this.center); +// } +// + public Node getPrimitiveNode() { + return (Node)center.getChild(0); + } + + public Enumeration getPrimitiveNodes() { + return (Enumeration)center.getAllChildren(); + } + + public Appearance getAppearance() { + Appearance ap = null; + Node node = getPrimitiveNode(); + if (node != null && node instanceof Shape3D) { + Shape3D shape = (Shape3D)node; + ap = shape.getAppearance(); + if (ap == null) { + ap = new Appearance(); + shape.setAppearance(ap); + } + } else if (node != null && node instanceof Primitive) { + Primitive primitive = (Primitive)node; + ap = primitive.getAppearance(); + if (ap == null) { + ap = new Appearance(); + primitive.setAppearance(ap); + } + } + return ap; + } + + public ArrayList getAppearances() { + ArrayList appearances = new ArrayList(); + appearances.add(getAppearance()); + return appearances; + } + + /** + * �Փ˔���p�̃{�����[���i�|���S���Ƒe������p�̑��p���j���擾���� + * @return�@�Փ˔���p�̃{�����[���� + */ + public BoundingSurface[] getBoundingSurfaces() { + if (boundingSurfaces == null) { + Node node = getPrimitiveNode(); + if (node == null) return null; + + ArrayList vertex3DList = null; + if (node instanceof Box) { + // Box�̏ꍇ + Box box = ((Box)node); + // ���_����擾���� + vertex3DList = getVertexList(box.getShape(Box.BACK).getGeometry()); + vertex3DList.addAll(getVertexList(box.getShape(Box.BOTTOM).getGeometry())); + vertex3DList.addAll(getVertexList(box.getShape(Box.FRONT).getGeometry())); + vertex3DList.addAll(getVertexList(box.getShape(Box.LEFT).getGeometry())); + vertex3DList.addAll(getVertexList(box.getShape(Box.RIGHT).getGeometry())); + vertex3DList.addAll(getVertexList(box.getShape(Box.TOP).getGeometry())); + } else if (node instanceof Cylinder) { + // Cylinder�̏ꍇ + Cylinder cylinder = ((Cylinder)node); + // ���_����擾���� + vertex3DList = getVertexList(cylinder.getShape(Cylinder.BODY).getGeometry()); + vertex3DList.addAll(getVertexList(cylinder.getShape(Cylinder.BOTTOM).getGeometry())); + vertex3DList.addAll(getVertexList(cylinder.getShape(Cylinder.TOP).getGeometry())); + } else if (node instanceof Cone) { + // Cone�̏ꍇ + Cone cone = ((Cone)node); + // ���_����擾���� + vertex3DList = getVertexList(cone.getShape(Cone.BODY).getGeometry()); + vertex3DList.addAll(getVertexList(cone.getShape(Cone.CAP).getGeometry())); + } else if (node instanceof Sphere) { + // Sphere�̏ꍇ + Sphere sphere = ((Sphere)node); + // ���_����擾���� + vertex3DList = getVertexList(sphere.getShape(Sphere.BODY).getGeometry()); + } else if (node instanceof Shape3D) { + // Shape3D�̏ꍇ + Shape3D shape = (Shape3D)node; + // ���_����擾���� + vertex3DList = getVertexList(shape.getGeometry()); + } + if (vertex3DList == null) return null; + + BoundingSurface[] surfaces = new BoundingSurface[vertex3DList.size() / 3]; + + for (int i = 0; i < vertex3DList.size(); i += 3) { + Vector3d v1 = vertex3DList.get(i); + Vector3d v2 = vertex3DList.get(i + 1); + Vector3d v3 = vertex3DList.get(i + 2); + BoundingSurface bSurface = new BoundingSurface(); + bSurface.addVertex((Vector3d)v1.clone()); + bSurface.addVertex((Vector3d)v2.clone()); + bSurface.addVertex((Vector3d)v3.clone()); + bSurface.setBounds(createBoundingPolytope(v1, v2, v3)); + surfaces[i / 3] = bSurface; + } + boundingSurfaces = surfaces; + } + return boundingSurfaces; + } + + private ArrayList getVertexList(Geometry g) { + ArrayList vertex3DList = new ArrayList(); + double coordinate1[] = new double[3]; + if (g instanceof IndexedTriangleArray) { + // IndexedTriangleArray �̏ꍇ + IndexedTriangleArray triArray = (IndexedTriangleArray)g; + + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă����B + for (int i = 0; i < triArray.getIndexCount(); i++) { + triArray.getCoordinates(triArray.getCoordinateIndex(i), coordinate1); + vertex3DList.add(new Vector3d(coordinate1)); + } + } else if (g instanceof TriangleArray) { + // TriangleArray �̏ꍇ + TriangleArray triArray = (TriangleArray)g; + + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă����B + for (int i = 0; i < triArray.getVertexCount(); i++) { + triArray.getCoordinates(i, coordinate1); + vertex3DList.add(new Vector3d(coordinate1)); + } + } else if (g instanceof IndexedTriangleStripArray) { + // IndexedTriangleStripArray �̏ꍇ + IndexedTriangleStripArray triStripAttay = (IndexedTriangleStripArray)g; + int stripVertexCounts[] = new int[triStripAttay.getNumStrips()]; + triStripAttay.getStripIndexCounts(stripVertexCounts); + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă��� + int index = 0; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = new double[3]; + for (int i = 0; i < triStripAttay.getNumStrips(); i++) { + for (int j = 0; j < stripVertexCounts[i]; j += 2) { + triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index), coordinate1); + triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+1), coordinate2); + triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+2), coordinate3); + triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+3), coordinate4); + vertex3DList.add(new Vector3d(coordinate1)); //1�‚߂̎O�p�` + vertex3DList.add(new Vector3d(coordinate2)); + vertex3DList.add(new Vector3d(coordinate3)); + vertex3DList.add(new Vector3d(coordinate2)); //2�‚߂̎O�p�` + vertex3DList.add(new Vector3d(coordinate4)); + vertex3DList.add(new Vector3d(coordinate3)); + index += 2; + } + } + } else if (g instanceof TriangleStripArray) { + // TriangleStripArray �̏ꍇ + TriangleStripArray triStripAttay = (TriangleStripArray)g; + int stripVertexCounts[] = new int[triStripAttay.getNumStrips()]; + triStripAttay.getStripVertexCounts(stripVertexCounts); + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă��� + int index = 0; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = new double[3]; + for (int i = 0; i < triStripAttay.getNumStrips(); i++) { + for (int j = 0; j < stripVertexCounts[i]; j += 2) { + triStripAttay.getCoordinates(index, coordinate1); + triStripAttay.getCoordinates(index+1, coordinate2); + triStripAttay.getCoordinates(index+2, coordinate3); + triStripAttay.getCoordinates(index+3, coordinate4); + vertex3DList.add(new Vector3d(coordinate1)); //1�‚߂̎O�p�` + vertex3DList.add(new Vector3d(coordinate2)); + vertex3DList.add(new Vector3d(coordinate3)); + vertex3DList.add(new Vector3d(coordinate2)); //2�‚߂̎O�p�` + vertex3DList.add(new Vector3d(coordinate4)); + vertex3DList.add(new Vector3d(coordinate3)); + index += 2; + } + } + } else if (g instanceof IndexedTriangleFanArray) { + // IndexedTriangleFanArray �̏ꍇ + IndexedTriangleFanArray triFanAttay = (IndexedTriangleFanArray)g; + int stripVertexCounts[] = new int[triFanAttay.getNumStrips()]; + triFanAttay.getStripIndexCounts(stripVertexCounts); + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă��� + int index = 0; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = null; + for (int i = 0; i < triFanAttay.getNumStrips(); i++) { + triFanAttay.getCoordinates(triFanAttay.getCoordinateIndex(index), coordinate1); // ���S�_ + triFanAttay.getCoordinates(triFanAttay.getCoordinateIndex(index+1), coordinate2); + index += 2; + for (int j = 2; j < stripVertexCounts[i]; j++) { + triFanAttay.getCoordinates(triFanAttay.getCoordinateIndex(index), coordinate3); + vertex3DList.add(new Vector3d(coordinate1)); + vertex3DList.add(new Vector3d(coordinate2)); + vertex3DList.add(new Vector3d(coordinate3)); + coordinate4 = coordinate2; + coordinate2 = coordinate3; + coordinate3 = coordinate4; + index++; + } + } + } else if (g instanceof TriangleFanArray) { + // TriangleFanArray �̏ꍇ + TriangleFanArray triFanAttay = (TriangleFanArray)g; + int stripVertexCounts[] = new int[triFanAttay.getNumStrips()]; + triFanAttay.getStripVertexCounts(stripVertexCounts); + // �S���_��3D��̒��_��vertex3DList�ɓ���Ă��� + int index = 0; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = null; + for (int i = 0; i < triFanAttay.getNumStrips(); i++) { + triFanAttay.getCoordinates(index, coordinate1); // ���S�_ + triFanAttay.getCoordinates(index + 1, coordinate2); + index += 2; + for (int j = 2; j < stripVertexCounts[i]; j++) { + triFanAttay.getCoordinates(index, coordinate3); + vertex3DList.add(new Vector3d(coordinate1)); + vertex3DList.add(new Vector3d(coordinate2)); + vertex3DList.add(new Vector3d(coordinate3)); + coordinate4 = coordinate2; + coordinate2 = coordinate3; + coordinate3 = coordinate4; + index++; + } + } + } else { + // QuadArray�n���͖��Ή� + return null; + } + return vertex3DList; + } + + protected BoundingPolytope createBoundingPolytope(Vector3d vertex1, + Vector3d vertex2, Vector3d vertex3) { + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + Vector3d v3 = new Vector3d(); + Vector3d v4 = new Vector3d(); + Vector3d v5 = new Vector3d(); + Vector3d v6 = new Vector3d(); + Vector3d cv1 = new Vector3d(); + Vector3d cv2 = new Vector3d(); + cv1.sub(vertex3, vertex1); + cv2.sub(vertex2, vertex1); + Vector3d cv = new Vector3d(); + cv.cross(cv1, cv2); + cv.normalize(); + cv.scale(0.01); + v1.set(vertex1); + v2.set(vertex2); + v3.set(vertex3); + v4.set(vertex1); + v4.add(cv); + v5.set(vertex2); + v5.add(cv); + v6.set(vertex3); + v6.add(cv); + + Vector3d pv1 = new Vector3d(); + Vector3d pv2 = new Vector3d(); + Vector3d pv3 = new Vector3d(); + Vector3d pn = new Vector3d(); + Vector4d[] plane = new Vector4d[5]; + + // 0 + pv1 = v1; + pv2.sub(v2, v1); + pv3.sub(v3, v1); + + pn.cross(pv2, pv3); + pn.normalize(); + plane[0] = new Vector4d(pn.x, pn.y, pn.z, -pn.dot(pv1)); + + // 1 + pv1 = v1; + pv2.sub(v4, v1); + pv3.sub(v2, v1); + + pn.cross(pv2, pv3); + pn.normalize(); + plane[1] = new Vector4d(pn.x, pn.y, pn.z, -pn.dot(pv1)); + + // 2 + pv1 = v1; + pv2.sub(v3, v1); + pv3.sub(v4, v1); + + pn.cross(pv2, pv3); + pn.normalize(); + plane[2] = new Vector4d(pn.x, pn.y, pn.z, -pn.dot(pv1)); + + // 3 + pv1 = v6; + pv2.sub(v3, v6); + pv3.sub(v5, v6); + + pn.cross(pv2, pv3); + pn.normalize(); + plane[3] = new Vector4d(pn.x, pn.y, pn.z, -pn.dot(pv1)); + + // 4 + pv1 = v6; + pv2.sub(v5, v6); + pv3.sub(v4, v6); + + pn.cross(pv2, pv3); + pn.normalize(); + plane[4] = new Vector4d(pn.x, pn.y, pn.z, -pn.dot(pv1)); + + return new BoundingPolytope(plane); + } + + public void createShadowVolume(ArrayList lights, double shadowDepth, Transform3D localToWorld) { + for (int n = 0; n < lights.size(); n++) { + shadowVolumes.add(new ShadowVolume(this, lights.get(n), shadowDepth, localToWorld)); + } + } + + public void updateShadowVolume(Transform3D localToWorld) { + for (int n = 0; n < shadowVolumes.size(); n++) { + shadowVolumes.get(n).update(localToWorld); + } + } + + public void setBumpMapping(BumpMapGenerator g) { + bumpMapGenerator = g; + bBumpMapApplied = true; + } + + public BumpMapGenerator getBumpMappingInfo() { + return bumpMapGenerator; + } + + public boolean isBumpMappingApplied() { + return bBumpMapApplied; + } + + public void setReflectionMapping(ReflectionMapGenerator g) { + reflectionMapGenerator = g; + bReflectionMapApplied = true; + } + + public ReflectionMapGenerator getReflectionMappingInfo() { + return reflectionMapGenerator; + } + + public boolean isReflectionMappingApplied() { + return bReflectionMapApplied; + } + + public boolean hasAppearancePrepared() { + if (bumpMapGenerator != null && !bumpMapGenerator.hasMapped()) return false; + if (reflectionMapGenerator != null && !reflectionMapGenerator.hasMapped()) return false; + return true; + } +} \ No newline at end of file diff --git a/src/main/java/framework/model3D/BoundingSurface.java b/src/main/java/framework/model3D/BoundingSurface.java new file mode 100644 index 0000000..c5383ed --- /dev/null +++ b/src/main/java/framework/model3D/BoundingSurface.java @@ -0,0 +1,128 @@ +package framework.model3D; +import java.util.ArrayList; + +import javax.media.j3d.BoundingPolytope; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Bounds; +import javax.media.j3d.Transform3D; +import javax.vecmath.Matrix4d; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; + + +public class BoundingSurface implements Cloneable { + private Bounds bounds = null; // �e���Փ˔���p�i�e���n�ʗp�j + private ArrayList children = new ArrayList(); + private ArrayList vertexList = new ArrayList(); + private static Vector4d plane[] = { new Vector4d(), new Vector4d(), new Vector4d(), + new Vector4d(), new Vector4d() }; + + public Object clone() { + BoundingSurface s = new BoundingSurface(); + if (bounds != null) { + s.setBounds((Bounds)bounds.clone()); + } + for (int i = 0; i < children.size(); i++) { + s.children.add((BoundingSurface)children.get(i).clone()); + } + for (int i = 0; i < vertexList.size(); i++) { + s.vertexList.add((Vector3d)vertexList.get(i).clone()); + } + return s; + } + + public void setBounds(Bounds bounds) { + this.bounds = bounds; + } + + public Bounds getBounds() { + return bounds; + } + + public void addVertex(Vector3d v) { + vertexList.add(v); + } + + public void addChild(BoundingSurface bs, boolean bCombineBounds) { + children.add(bs); + if (bCombineBounds) { + if (bounds == null) { + bounds = (Bounds)bs.bounds.clone(); + } else { + bounds.combine(bs.bounds); + } + } + } + + public void transform(Transform3D transform3D) { + bounds.transform(transform3D); + for (int i = 0; i < vertexList.size(); i++) { + Matrix4d mat4d = new Matrix4d(); + transform3D.get(mat4d); + double x = mat4d.m00 * vertexList.get(i).x + mat4d.m01 + * vertexList.get(i).y + mat4d.m02 * vertexList.get(i).z + + mat4d.m03; + double y = mat4d.m10 * vertexList.get(i).x + mat4d.m11 + * vertexList.get(i).y + mat4d.m12 * vertexList.get(i).z + + mat4d.m13; + double z = mat4d.m20 * vertexList.get(i).x + mat4d.m21 + * vertexList.get(i).y + mat4d.m22 * vertexList.get(i).z + + mat4d.m23; + vertexList.get(i).x = x; + vertexList.get(i).y = y; + vertexList.get(i).z = z; + } + } + + /** + * BoundingSphere�Ƃ̑e���Փ˔��� + * @param bs �Փ˔���̑Ώ� + * @return �Փ˂��Ă���BoundingSurface�̃��X�g�inull��Ԃ����Ƃ͂Ȃ��j + */ + public ArrayList intersect(BoundingSphere bs) { + ArrayList results = new ArrayList(); + if (children == null || children.size() == 0) { + if (bounds.intersect(bs)) { + results.add(this); + } + } else { + if (bounds == null || bounds.intersect(bs)) { + for (int n = 0; n < children.size(); n++) { + results.addAll(children.get(n).intersect(bs)); + } + } + } + return results; + } + + /** + * OBB�Ƃ̏ڍׂȏՓ˔��� + * @param obb �Փ˔���̑Ώ� + * @return�@�Փ˔���̌��� + */ + public CollisionResult intersect(OBB obb) { + if (children == null || children.size() == 0) { + // �t�̏ꍇ�́A�ʃ|���S���𗧂��グ���������p�� + if (bounds instanceof BoundingPolytope) { + ((BoundingPolytope)bounds).getPlanes(plane); + CollisionResult cr = obb.intersect(plane[0]); // obb����ʂ��܂ޖ������ʂƌ�����Ă��邩�H + if (cr != null) { + // �������ʂƌ�����Ă���ꍇ�A�������ʂƂ̏Փ˓_���ʃ|���S���̓����Ɉʒu���邩�H + if (GeometryUtility.inside(vertexList, cr.collisionPoint.getVector3d(), cr.normal)) { + return cr; + } + } + } + return null; + } else { + for (int n = 0; n < children.size(); n++) { + CollisionResult cr = children.get(n).intersect(obb); + if (cr != null) { + return cr; + } + } + return null; + } + } +} diff --git a/src/main/java/framework/model3D/BumpMapGenerator.java b/src/main/java/framework/model3D/BumpMapGenerator.java new file mode 100644 index 0000000..04a9ad0 --- /dev/null +++ b/src/main/java/framework/model3D/BumpMapGenerator.java @@ -0,0 +1,29 @@ +package framework.model3D; + +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.Texture; +import javax.vecmath.Color4f; + +public class BumpMapGenerator extends MapGenerator { + private Texture bumpMap = null; + private TexCoordGeneration texCoorgGen = null; + private boolean bHorizontal = false; + + public BumpMapGenerator(Texture bumpMap, TexCoordGeneration texCoorgGen, boolean bHorizontal) { + this.bumpMap = bumpMap; + this.texCoorgGen = texCoorgGen; + this.bHorizontal = bHorizontal; + } + + public Texture getBumpMap() { + return bumpMap; + } + + public TexCoordGeneration getTexCoordGeneration() { + return texCoorgGen; + } + + public boolean isHorizontal() { + return bHorizontal; + } +} diff --git a/src/main/java/framework/model3D/CollisionResult.java b/src/main/java/framework/model3D/CollisionResult.java new file mode 100644 index 0000000..e95cd8a --- /dev/null +++ b/src/main/java/framework/model3D/CollisionResult.java @@ -0,0 +1,13 @@ +package framework.model3D; +import java.util.ArrayList; + +import javax.vecmath.Vector3d; + + + +public class CollisionResult { + public Position3D collisionPoint = new Position3D(); + public ArrayList collisionPoints; + public Vector3d normal = new Vector3d(); + public double length = 0.0; +} diff --git a/src/main/java/framework/model3D/ContainerModel.java b/src/main/java/framework/model3D/ContainerModel.java new file mode 100644 index 0000000..db3f8ea --- /dev/null +++ b/src/main/java/framework/model3D/ContainerModel.java @@ -0,0 +1,42 @@ +package framework.model3D; + +import javax.media.j3d.Transform3D; + +/** + * �q�������ƒ��f�� + * @author �V�c���� + * + */ +public class ContainerModel extends Model3D { + private Model3D[] children; + private Transform3D defaultTransform = null; + + public ContainerModel(String name,Model3D[] children) { + this.children = children; + this.name = name; + this.defaultTransform = null; + } + + public ContainerModel(String name, Model3D[] children, + Transform3D transform) { + this.children = children; + this.name = name; + this.defaultTransform = transform; + } + + public Object3D createObject() { + Object3D[] objChild = new Object3D[children.length]; + for(int i = 0;i < children.length;i++){ + objChild[i] = (Object3D) children[i].createObject(); + } + return new Object3D(name, objChild, defaultTransform); + } + + public Object3D createObjectSharingAppearance() { + Object3D[] objChild = new Object3D[children.length]; + for(int i = 0;i < children.length;i++){ + objChild[i] = (Object3D) children[i].createObjectSharingAppearance(); + } + return new Object3D(name, objChild, defaultTransform); + } +} diff --git a/src/main/java/framework/model3D/FresnelsReflectionMapGenerator.java b/src/main/java/framework/model3D/FresnelsReflectionMapGenerator.java new file mode 100644 index 0000000..1825bfe --- /dev/null +++ b/src/main/java/framework/model3D/FresnelsReflectionMapGenerator.java @@ -0,0 +1,16 @@ +package framework.model3D; + +import javax.vecmath.Color4f; + +public class FresnelsReflectionMapGenerator extends ReflectionMapGenerator { + private boolean bTransparent = true; + + public FresnelsReflectionMapGenerator(Color4f blendColor, boolean bTransparent) { + super(blendColor); + this.bTransparent = bTransparent; + } + + public boolean isTransparent() { + return bTransparent; + } +} diff --git a/src/main/java/framework/model3D/GeometryCollector.java b/src/main/java/framework/model3D/GeometryCollector.java new file mode 100644 index 0000000..ef92d8d --- /dev/null +++ b/src/main/java/framework/model3D/GeometryCollector.java @@ -0,0 +1,131 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Stack; + +import javax.media.j3d.Geometry; +import javax.media.j3d.IndexedGeometryArray; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.IndexedTriangleStripArray; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; + +import com.sun.j3d.utils.geometry.GeometryInfo; +import com.sun.j3d.utils.geometry.Stripifier; + +public class GeometryCollector extends ObjectVisitor{ + private int totalVertexCount = 0; + private int totalIndexCount = 0; + private ArrayList geometryList = new ArrayList(); // �t�̂Ƃ��AGeometry��ۑ� + IndexedGeometryArray geometry = null; +// private Stack transforms = new Stack(); + + int i=0; + int j=0; + + //�R���X�g���N�^ +// public GeometryCollector() { +// Transform3D t = new Transform3D(); +// transforms.push(t); +// } + + @Override + public void preVisit(Object3D obj) { + // TODO Auto-generated method stub + if(obj.hasChildren()){ +// System.out.println("pre"+i); +// i++; + }else{ +// System.out.println("pre"+i+" Leaf"); +// i++; + Geometry g = ((Shape3D)obj.getBody().getPrimitiveNode()).getGeometry(); + geometryList.add(g); + totalVertexCount += ((IndexedGeometryArray)g).getVertexCount(); + totalIndexCount += ((IndexedGeometryArray)g).getIndexCount(); + } + + + } + + @Override + public void postVisit(Object3D obj) { + // TODO Auto-generated method stub + if(obj.hasChildren()){ +// System.out.println("post"+j); + j++; + }else{ +// System.out.println("post"+j+" Leaf"); + j++; + } + } + + public Geometry getGeometry(){ + if (geometry == null) { + // ���X�g���̕����� Geometry ��1�‚ɂ܂Ƃ߂� + int coordinateOfs = 0; + int indexOfs = 0; + double coodinates[] = new double[totalVertexCount * 3]; + int indicies[] = new int[totalIndexCount]; + for (int n = 0; n < geometryList.size(); n++) { + IndexedGeometryArray geometry = (IndexedGeometryArray)geometryList.get(n); + double tmpCoordinates[] = new double[geometry.getVertexCount() * 3]; + geometry.getCoordinates(0, tmpCoordinates); + System.arraycopy(tmpCoordinates, 0, coodinates, coordinateOfs * 3, geometry.getVertexCount() * 3); + int tmpIndicies[] = new int[geometry.getIndexCount()]; + geometry.getCoordinateIndices(0, tmpIndicies); + for (int m = 0; m < geometry.getIndexCount(); m++) { + tmpIndicies[m] += coordinateOfs; + } + System.arraycopy(tmpIndicies, 0, indicies, indexOfs, geometry.getIndexCount()); + coordinateOfs += geometry.getVertexCount(); + indexOfs += geometry.getIndexCount(); + } + geometry = new IndexedTriangleArray(totalVertexCount, IndexedTriangleArray.COORDINATES, totalIndexCount); + geometry.setCoordinates(0, coodinates); + geometry.setCoordinateIndices(0, indicies); + + // �d�����Ă��钸�_��1�‚ɂ܂Ƃ߂� + GeometryUtility.compressGeometry(geometry); + +// // IndexedTriangleStripArray�@�ɕϊ��i�d�����Ă��钸�_��1�‚ɂ܂Ƃ߂邽�߁j +// GeometryInfo gi = new GeometryInfo(geometry); +// Stripifier sf = new Stripifier(); +// sf.stripify(gi); +// geometry = gi.getIndexedGeometryArray(); // IndexedTriangleStripArray ���Ԃ���� +// +// // IndexedTriangleArray �ɕϊ��iGeometryGraph �� IndexedTriangleStripArray �ɖ��Ή��̂��߁j +// if (geometry instanceof IndexedTriangleStripArray) { +// int numStrips = ((IndexedTriangleStripArray)geometry).getNumStrips(); +// int indexCounts[] = new int[numStrips]; +// ((IndexedTriangleStripArray)geometry).getStripIndexCounts(indexCounts); +// int dstIndicies[] = new int[(((IndexedTriangleStripArray)geometry).getIndexCount() - numStrips * 2) * 3]; +// int dstOfs = 0; +// int srcOfs = 0; +// for (int s = 0; s < numStrips; s++) { +// for (int i = 2; i < indexCounts[s]; i += 2) { +// dstIndicies[dstOfs] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 2); +// dstIndicies[dstOfs + 1] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 1); +// dstIndicies[dstOfs + 2] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i); +// dstOfs += 3; +// if (i + 1 < indexCounts[s]) { +// dstIndicies[dstOfs] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i); +// dstIndicies[dstOfs + 1] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 1); +// dstIndicies[dstOfs + 2] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i + 1); +// dstOfs += 3; +// } +// } +// srcOfs += indexCounts[s]; +// } +// +// int vertexCount = ((IndexedTriangleStripArray)geometry).getVertexCount(); +// coodinates = new double[vertexCount * 3]; +// ((IndexedTriangleStripArray)geometry).getCoordinates(0, coodinates); +// +// geometry = new IndexedTriangleArray(vertexCount, IndexedTriangleArray.COORDINATES, dstIndicies.length); +// geometry.setCoordinates(0, coodinates); +// geometry.setCoordinateIndices(0, dstIndicies); +// } + } + return geometry; + } +} diff --git a/src/main/java/framework/model3D/GeometryUtility.java b/src/main/java/framework/model3D/GeometryUtility.java new file mode 100644 index 0000000..a00cd04 --- /dev/null +++ b/src/main/java/framework/model3D/GeometryUtility.java @@ -0,0 +1,292 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Hashtable; + +import javax.media.j3d.IndexedGeometryArray; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Matrix3d; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; + +public class GeometryUtility { + public static final double TOLERANCE = 0.0000002; + public static final Vector3d X_AXIS = new Vector3d(1.0, 0.0, 0.0); + public static final Vector3d Y_AXIS = new Vector3d(0.0, 1.0, 0.0); + public static final Vector3d Z_AXIS = new Vector3d(0.0, 0.0, 1.0); + + public static ProjectionResult projection3D( + ArrayList vertex3Dlist, Vector3d axis) { + double k = 0.0; + int i = 0; + + ProjectionResult pr = new ProjectionResult(); + + axis.normalize(); + + for (i = 0; i < vertex3Dlist.size(); i++) { + Vector3d p = vertex3Dlist.get(i); + Vector3d p1 = new Vector3d(); + + k = p.dot(axis); + p1.scaleAdd(-k, axis, p); + + if (i == 0 || k >= pr.max) { + pr.max = k; + } else if (i == 0 || k <= pr.min) { + pr.min = k; + } + pr.vertexList.add(p1); + } + return pr; + } + + public static ProjectionResult projection2D( + ArrayList vertex2Dlist, Vector3d axis) { + int i = 0; + double k = 0.0; + // System.out.println("point3�F"+axis); + if (axis.x != 0 || axis.y != 0 || axis.z != 0) { + axis.normalize(); + } + // System.out.println("point3_1�F"+axis); + ProjectionResult pr = new ProjectionResult(); + + for (i = 0; i < vertex2Dlist.size(); i++) { + Vector3d p = vertex2Dlist.get(i); + + k = p.dot(axis); + // System.out.println("k�F"+k); + // System.out.println("point3�F"+axis); + if (i == 0 || k >= pr.max) { + pr.max = k; + } else if (i == 0 || k <= pr.min) { + pr.min = k; + } + } + return pr; + } + + // �ȉ��A���_�̕\���̔��胁�\�b�h + public static boolean inside(Vector3d v, Vector4d plane) { + // System.out.println("vertex:" + v.x + "," + v.y + "," + v.z); + // System.out.println("plane:" + plane.x + "," + plane.y + "," + plane.z + // + "," + plane.w); + Vector3d pv = new Vector3d(plane.x, plane.y, plane.z); + // Vector3d nv = (Vector3d)pv.clone(); + // nv.scaleAdd(plane.w / pv.lengthSquared(),v); + if (pv.dot(v) + plane.w <= TOLERANCE) { + // System.out.println("��������I�I"+nv.dot(pv)); + pv = null; + return true; + } + // System.out.println("�O������I�I"+nv.dot(pv)); + pv = null; + return false; + } + + /** + * 3�_��ʂ镽�ʂ��쐬����i�������Av1, v2, v3�̓��e��������������̂Œ��Ӂj + * + * @param v1 + * --- 1�_�ڂ̍��W + * @param v2 + * --- 2�_�ڂ̍��W + * @param v3 + * --- 3�_�ڂ̍��W + * @return�@v1, v2, v3��ʂ镽�� + */ + public static Vector4d createPlane(Vector3d v1, Vector3d v2, Vector3d v3) { + v2 = (Vector3d)v2.clone(); + v3 = (Vector3d)v3.clone(); + v2.sub(v1); + v3.sub(v1); + v2.cross(v2, v3); + if (v2.length() < TOLERANCE) return null; + v2.normalize(); + return new Vector4d(v2.x, v2.y, v2.z, -v2.dot(v1)); + } + + /** + * + * ���ʂƒ����̌�_�����߂� + * + * @param plane + * ���� + * @param v1 + * ������̓_1 + * @param v2 + * ������̓_2 + * @return ��_ + */ + public static Vector3d intersect(Vector4d plane, Vector3d v1, Vector3d v2) { + Vector3d n = new Vector3d(plane.x, plane.y, plane.z); + Vector3d v21 = (Vector3d) v2.clone(); + v21.sub(v1); + double s = n.dot(v21); + if (Math.abs(s) < TOLERANCE) return null; + v21.scale((-plane.w - n.dot(v1)) / s); + v21.add(v1); + return v21; + } + + /** + * + * �^����ꂽ�_�ɍł��߂�������̓_�����߂� + * + * @param src ����(����)�̎n�_ + * @param dst ����(����)�̏I�_ + * @param pos �Ώۂ̓_ + * @return src��dst��ʂ钼�����pos�ɍł��߂��_ + */ + public static Vector3d nearest(Vector3d src, Vector3d dst, Vector3d pos) { + Vector3d dir = (Vector3d)dst.clone(); + dir.sub(src); + dir.normalize(); + Vector3d p = (Vector3d)pos.clone(); + p.sub(src); + dir.scale(p.dot(dir)); + dir.add(src); + return dir; + } + + /** + * + * �w�肳�ꂽ�_���ʃ|���S���̓����ɕ�܂���Ă��邩�H + * + * @param vertexList + * �ʃ|���S���̒��_�� + * @param point + * �w��_ + * @return true --- ��܂���Ă���, false --- ��܂���Ă��Ȃ� + */ + public static boolean inside(ArrayList vertexList, Vector3d point, Vector3d normal) { + boolean inside = true; + for (int i = 0; i < vertexList.size(); i++) { + // �|���S���̊e�ӂɑ΂��ďՓ˓_���E�����������H + Vector3d center = (Vector3d) point.clone(); + Vector3d v2 = (Vector3d) (vertexList.get((i + 1) + % vertexList.size()).clone()); + Vector3d v1 = (Vector3d) vertexList.get(i).clone(); + center.sub(v1); + v2.sub(v1); + v1.cross(v2, center); + if (normal.dot(v1) < -GeometryUtility.TOLERANCE) { + inside = false; + break; + } + } + // ���ׂĉE���A�܂��͂��ׂč����������ꍇ�A�ʃ|���S���̓����Ɉʒu�����ƍl���� + return inside; + } + + // IndexedGeometryArray�̃C���f�b�N�X�̂����A�������W�������C���f�b�N�X��u�������� + public static void compressGeometry(IndexedGeometryArray g) { + // �@Hashtable�����Ȃ���Arepresentation[]����� + Hashtable> h = new Hashtable>(); + Point3d p = new Point3d(); + Point3d p2 = new Point3d(); + double hash; + ArrayList list; + int[] representation = new int[g.getVertexCount()]; + + for (int i = 0; i < g.getVertexCount(); i++) { + g.getCoordinate(i, p); + + hash = p.getX() + p.getY() + p.getZ(); + + list = h.get(new Double(hash)); + + if (list == null) {// hash�ɑΉ�����v�f���Ȃ��ꍇ + // Hashtable����� + list = new ArrayList(); + list.add(new Integer(i)); + h.put(new Double(hash), list); + // representation[]����� + representation[i] = i; + } else { + boolean bFound = false; + for (int j = 0; j < list.size(); j++) { + g.getCoordinate(list.get(j).intValue(), p2); + if (p.getX() == p2.getX() && p.getY() == p2.getY() + && p.getZ() == p2.getZ()) { + representation[i] = list.get(j).intValue(); + bFound = true; + break; + } + } + if (!bFound) { + list.add(new Integer(i)); + // representation[]����� + representation[i] = i; + } + } + } + + // �Aindex�̒u������ + for (int i = 0; i < g.getIndexCount(); i++) { + int index = representation[g.getCoordinateIndex(i)]; + g.setCoordinateIndex(i, index); + + } + + } + + public static Matrix3d calcRotationForView(Vector3d viewLine) { + Vector3d v1 = (Vector3d)viewLine.clone(); + v1.normalize(); + Vector3d v2 = new Vector3d(); + v2.cross(v1, Y_AXIS); + double angle2 = Math.atan2(-v2.z, v2.x); + double angle1 = Math.PI / 2.0 - Math.acos(v1.dot(Y_AXIS)); + Matrix3d rot1 = new Matrix3d(); + rot1.rotX(angle1); + Matrix3d rot2 = new Matrix3d(); + rot2.rotY(angle2); + rot2.mul(rot1); + return rot2; + } + + public static Quaternion3D calcQuaternionForView(Vector3d viewLine) { + Vector3d v1 = (Vector3d)viewLine.clone(); + v1.normalize(); + Vector3d v2 = new Vector3d(); + v2.cross(v1, Y_AXIS); + double angle2 = Math.atan2(-v2.z, v2.x); + double angle1 = Math.PI / 2.0 - Math.acos(v1.dot(Y_AXIS)); + Quaternion3D quat1 = new Quaternion3D(new AxisAngle4d(X_AXIS, angle1)); + Quaternion3D quat2 = new Quaternion3D(new AxisAngle4d(Y_AXIS, angle2)); + + return quat1.mul(quat2); + } + + public static Quaternion3D calcQuaternionFromSrcToDst(Vector3d src, Vector3d dst) { + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + v1.cross(src, Y_AXIS); + v2.cross(dst, Y_AXIS); + Quaternion3D quat1; + Quaternion3D quat2; + double angle2 = Math.acos(Y_AXIS.dot(src) / src.length()) - Math.acos(Y_AXIS.dot(dst) / dst.length()); + if (Math.abs(v2.length()) < TOLERANCE) { + v1.normalize(); + quat1 = new Quaternion3D(); + quat2 = new Quaternion3D(new AxisAngle4d(v1, angle2)); + } else { + if (Math.abs(v1.length()) < TOLERANCE) { + quat1 = new Quaternion3D(); + } else { + v1.normalize(); + v2.normalize(); + double cos1 = v1.dot(v2); + v1.cross(v1, v2); + double sin1 = v1.dot(Y_AXIS); + double angle1 = Math.atan2(sin1, cos1); + quat1 = new Quaternion3D(new AxisAngle4d(Y_AXIS, angle1)); + } + quat2 = new Quaternion3D(new AxisAngle4d(v2, angle2)); + } + return quat1.mul(quat2); + } +} \ No newline at end of file diff --git a/src/main/java/framework/model3D/IViewer3D.java b/src/main/java/framework/model3D/IViewer3D.java new file mode 100644 index 0000000..fa6b1f0 --- /dev/null +++ b/src/main/java/framework/model3D/IViewer3D.java @@ -0,0 +1,16 @@ +package framework.model3D; + +import java.util.ArrayList; + +import javax.media.j3d.GraphicsContext3D; +import javax.media.j3d.Light; +import javax.media.j3d.Transform3D; + + + +public interface IViewer3D { + public abstract void update(ArrayList lights, BackgroundBox skyBox); + public abstract void setGraphicsContext3D(GraphicsContext3D graphicsContext3D); + public abstract void setModelTransform(Transform3D t); + public abstract void draw(BaseObject3D obj); +} diff --git a/src/main/java/framework/model3D/LeafModel.java b/src/main/java/framework/model3D/LeafModel.java new file mode 100644 index 0000000..c5d3a72 --- /dev/null +++ b/src/main/java/framework/model3D/LeafModel.java @@ -0,0 +1,31 @@ +package framework.model3D; +import javax.media.j3d.Appearance; +import javax.media.j3d.Geometry; + + +public class LeafModel extends Model3D{ + + private Geometry g; + private Appearance a; + + public LeafModel(String name,Geometry g,Appearance a){ + this.name = name; + this.g = g; + this.a = a; + } + + public Object3D createObject(){ + Appearance a2 = (Appearance)a.cloneNodeComponent(true); + a2.setCapability(Appearance.ALLOW_TEXTURE_READ); + a2.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + Object3D obj = new Object3D(name,g,a2); + return obj; + } + + public Object3D createObjectSharingAppearance(){ + Object3D obj = new Object3D(name,g,a); + return obj; + } +} diff --git a/src/main/java/framework/model3D/MapGenerator.java b/src/main/java/framework/model3D/MapGenerator.java new file mode 100644 index 0000000..cd226ac --- /dev/null +++ b/src/main/java/framework/model3D/MapGenerator.java @@ -0,0 +1,17 @@ +package framework.model3D; + +public abstract class MapGenerator { + private boolean bMapped = false; + + public MapGenerator() { + super(); + } + + public void setMapped() { + bMapped = true; + } + + public boolean hasMapped() { + return bMapped; + } +} \ No newline at end of file diff --git a/src/main/java/framework/model3D/Model3D.java b/src/main/java/framework/model3D/Model3D.java new file mode 100644 index 0000000..88dd9ff --- /dev/null +++ b/src/main/java/framework/model3D/Model3D.java @@ -0,0 +1,9 @@ +package framework.model3D; + + + +public abstract class Model3D { + String name; + public abstract Object3D createObject(); + public abstract Object3D createObjectSharingAppearance(); +} diff --git a/src/main/java/framework/model3D/ModelFactory.java b/src/main/java/framework/model3D/ModelFactory.java new file mode 100644 index 0000000..b28607d --- /dev/null +++ b/src/main/java/framework/model3D/ModelFactory.java @@ -0,0 +1,1036 @@ +package framework.model3D; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; + +import javax.media.j3d.Appearance; +import javax.media.j3d.Canvas3D; +import javax.media.j3d.GeometryArray; +import javax.media.j3d.IndexedGeometryArray; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransparencyAttributes; +import javax.media.j3d.TriangleArray; +import javax.media.j3d.View; +import javax.vecmath.Vector2f; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.geometry.GeometryInfo; +import com.sun.j3d.utils.geometry.NormalGenerator; +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.universe.SimpleUniverse; + +import cv97.SceneGraph; +import cv97.j3d.IndexedFaceSetNodeObject; +import cv97.j3d.SceneGraphJ3dObject; +import cv97.j3d.TransformNodeObject; +import cv97.node.AppearanceNode; +import cv97.node.IndexedFaceSetNode; +import cv97.node.Node; +import cv97.node.ShapeNode; +import cv97.node.TransformNode; +import cv97.util.LinkedListNode; +import framework.schedule.ScheduleManager; +import framework.schedule.TaskController; + +/** + * 3�������f���𐶐����邽�߂̃N���X + * @author �V�c���� + * + */ +public class ModelFactory { + private static Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + public static final String STL_FILE_EXTENSION = ".stl"; + public static final String OBJ_FILE_EXTENSION = ".obj"; + + /** + * 3�������f�����K�w�\���Ɗe���̖��̂ƂƂ��Ƀt�@�C������ǂݍ��� + * @param fileName �t�@�C���� + * @return + */ + public static Model3D loadModel(String fileName){ + return loadModel(fileName, false, false); + } + + /** + * 3�������f�����K�w�\���Ɗe���̖��̂ƂƂ��Ƀt�@�C������ǂݍ��ށi�����e�N�X�`���̗L���̎w��t���j + * @param fileName �t�@�C���� + * @param bTransparent �����e�N�X�`�������邩�ۂ� + * @param bCalcNormal TODO + * @return + */ + public static Model3D loadModel(String fileName, boolean bTransparent, boolean bCalcNormal){ +// System.out.println(fileName); + if (fileName.toLowerCase().endsWith(STL_FILE_EXTENSION)) { + // STL�t�@�C���ǂݍ��� + try { + return loadStlFile(fileName, null, bCalcNormal); + } catch (IOException | ModelFileFormatException e) { + e.printStackTrace(); + } + } else if (fileName.toLowerCase().endsWith(OBJ_FILE_EXTENSION)) { + // OBJ�t�@�C���ǂݍ��� + try { + return loadObjFile(fileName, bCalcNormal); + } catch (IOException | ModelFileFormatException e) { + e.printStackTrace(); + } + } + + SceneGraph sg = new SceneGraph(SceneGraph.NORMAL_GENERATION); + + // �t�@�C���ǂݍ��ݎ��Ƀ����_�����O���s����̂ŁA�I�t�X�N���[�������_�����O���֎~���� + TaskController renderingController = ScheduleManager.getInstance().getController("rendering"); + renderingController.waitForActivation(); + renderingController.activate(); + + // �t�@�C���ǂݍ��� + View view = canvas.getView(); + if (view != null) view.removeCanvas3D(canvas); + SceneGraphJ3dObject sgObject = new SceneGraphJ3dObject(canvas, sg); + sg.setObject(sgObject); + sg.load(fileName); + + // �I�t�X�N���[�������_�����O�̋��� + renderingController.deactivate(); + + // Model3D�ւ̕ϊ� + Model3D model= loadModel(sg, bTransparent, bCalcNormal); + + return model; + } + + private static Model3D loadModel(LinkedListNode node, boolean bTransparent, boolean bCalcNormal){ +// System.out.println(node.getClass()); + + if( ! (node instanceof ShapeNode) ){ + Node childNodes; + String name = ""; + if (node instanceof SceneGraph) { + childNodes = ((SceneGraph)node).getNodes(); + } else { + childNodes = ((Node)node).getChildNodes(); + name = ((Node)node).getName(); + } + if(childNodes != null) { + ArrayList list = new ArrayList(); + for(Node n = childNodes;n != null;n = n.next()){ + Model3D model; + if((model = loadModel(n, bTransparent, bCalcNormal)) != null){ + list.add(model); + } + + //�Z��Ŗ������[�v�ɂȂ�Ȃ��悤�ɂ��鏈�� + Node dummy = n; + dummy = dummy.next(); + if(n == dummy){ + break; + } + } + + if(!list.isEmpty()){ + Model3D modelList[] = new Model3D[list.size()]; + for(int i = 0;i < list.size();i++){ + modelList[i] = list.get(i); + } + if (node instanceof TransformNode) { + // �e�K�w�Œ�`����Ă���ϊ������ꏏ�ɕێ����Ă��� + TransformNode transformNode = (TransformNode)node; + TransformNodeObject transformNodeObj = (TransformNodeObject)transformNode.getObject(); + Transform3D transform = new Transform3D(); + transformNodeObj.getTransform(transform); + return new ContainerModel(name, modelList, transform); + } + return new ContainerModel(name, modelList); + } + } + return null; + } else{ + //�W�I���g���f�[�^�Ȃ�t�m�[�h�ɂ�����Model3D�f�[�^������Č��ʂ�Ԃ� + + String name = ((Node)node).getName(); + ShapeNode sp = (ShapeNode)node; + + //�W�I���g���f�[�^�̎擾 + IndexedFaceSetNode indexfsNode = sp.getIndexedFaceSetNodes(); + + if(indexfsNode ==null){ + return null; + } + IndexedFaceSetNodeObject indexfsNodeObj = (IndexedFaceSetNodeObject) + indexfsNode.getObject(); + + IndexedGeometryArray newGeom; + if (bCalcNormal) { + GeometryInfo gInfo = new GeometryInfo(indexfsNodeObj); + NormalGenerator ng = new NormalGenerator(); + ng.generateNormals(gInfo); + // Stripifier st = new Stripifier(); + // st.stripify(gInfo); + newGeom = gInfo.getIndexedGeometryArray(); + } else { + newGeom = indexfsNodeObj; + } + + //�A�s�A�����X�f�[�^�̎擾 + AppearanceNode appearNodes = (AppearanceNode)sp.getAppearanceNodes(); + + Appearance appearObj = null; + if(appearNodes != null){ + appearObj = (Appearance)appearNodes.getObject(); + appearObj = (Appearance)appearObj.cloneNodeComponent(true); + TextureAttributes ta = appearObj.getTextureAttributes(); + if (ta == null) { + ta = new TextureAttributes(); + } + ta.setTextureMode(TextureAttributes.MODULATE); // �V�F�[�f�B���O�ƃe�N�X�`������������ + appearObj.setTextureAttributes(ta); + if (bTransparent) { + // �����e�N�X�`�����\���Ă���ꍇ + TransparencyAttributes tra = appearObj.getTransparencyAttributes(); + if (tra == null) { + tra = new TransparencyAttributes(); + } + tra.setTransparencyMode(TransparencyAttributes.FASTEST); + appearObj.setTransparencyAttributes(tra); + } +// Texture tex = appearObj.getTexture(); +// if (tex != null) { +// ImageComponent ic[] = tex.getImages(); +// for (int n = 0; n < ic.length; n++) { +// boolean b = ic[n].isYUp(); +// ic[n].setYUp(!b); +// } +// tex.setImages(ic); +// appearObj.setTexture(tex); +// } + } + + //���[�t���f���̍쐬 + return new LeafModel(name,newGeom,appearObj); + } + } + + /** + * STL�t�@�C��(�A�X�L�[�A�o�C�i��)�̓ǂݍ��� + * @param res ���\�[�X + * @param fileName �t�@�C���� + * @param ap 3D���f���ɓK�p����\�ʑ��� + * @param bCalcNormal �@���̍Čv�Z���s���� + * @return �ǂݍ���3D���f�� + * @throws IOException + * @throws ModelFileFormatException + */ + public static Model3D loadStlFile(String fileName, Appearance ap, boolean bCalcNormal) throws IOException, ModelFileFormatException { + // STL�t�@�C���ǂݍ��� + FileInputStream in = new FileInputStream(fileName); + BufferedInputStream bis = new BufferedInputStream(in); + byte[] headerBin = new byte[80]; + int n = bis.read(headerBin); + if (headerBin[0] == 's' && + headerBin[1] == 'o' && + headerBin[2] == 'l' && + headerBin[3] == 'i' && + headerBin[4] == 'd' && + headerBin[5] == ' ') { + bis.close(); + + // STL�̓e�L�X�g�t�@�C�� + File file = new File(fileName); + FileReader filereader = new FileReader(file); + BufferedReader br = new BufferedReader(filereader); + Model3D model = loadStlAsciiFile(br, ap, bCalcNormal); + br.close(); + return model; + } else if (n == 80) { + // STL�̓o�C�i���t�@�C�� + Model3D model = loadStlBinaryFile(bis, headerBin, ap, bCalcNormal); + bis.close(); + return model; + } + return null; + } + + private static Model3D loadStlAsciiFile(BufferedReader br, Appearance ap, boolean bCalcNormal) throws IOException, ModelFileFormatException { + // �w�b�_�ǂݍ��� + String header = br.readLine(); + if (header == null) { + br.close(); + throw new ModelFileFormatException(); + } + header.trim(); + String headerContents[] = header.split(" "); + String name; + if (headerContents.length > 0 && headerContents[0].equals("solid")) { + if (headerContents.length > 1) name = headerContents[1]; + else name = ""; + } else { + System.out.println("STL file's header error!!"); + br.close(); + throw new ModelFileFormatException(); + } + + // Facet�ǂݍ��� + ArrayList verticies = new ArrayList(); + String line; + while ((line = br.readLine()) != null && !line.startsWith("endsolid ")) { + // facet normal ... + line.trim(); + String[] data = line.split(" "); + if (data.length < 1 || !data[0].equals("facet")) { + System.out.println("Expected facet normal ..."); + br.close(); + throw new ModelFileFormatException(); + } + + // outer loop + line = br.readLine(); + if (line == null) { + System.out.println("Expected outer loop"); + br.close(); + throw new ModelFileFormatException(); + } + line.trim(); + if (!line.equals("outer loop")) { + System.out.println("Expected outer loop"); + br.close(); + throw new ModelFileFormatException(); + } + + // vertex * 3 + for (int i = 0; i < 3; i++) { + line = br.readLine(); + if (line == null) { + System.out.println("Expected vertex x y z"); + br.close(); + throw new ModelFileFormatException(); + } + line.trim(); + data = line.split(" "); + if (data.length < 4 || !data[0].equals("vertex")) { + System.out.println("Expected vertex x y z"); + br.close(); + throw new ModelFileFormatException(); + } + double[] vertex = new double[]{ + Double.parseDouble(data[1]), // X���W + Double.parseDouble(data[2]), // Y���W + Double.parseDouble(data[3]) // Z���W + }; + verticies.add(vertex); // Z���W + } + + // endloop + line = br.readLine(); + if (line == null) { + System.out.println("Expected endloop"); + br.close(); + throw new ModelFileFormatException(); + } + line.trim(); + if (!line.equals("endloop")) { + System.out.println("Expected endloop"); + br.close(); + throw new ModelFileFormatException(); + } + + // endfacet + line = br.readLine(); + if (line == null) { + System.out.println("Expected endfacet"); + br.close(); + throw new ModelFileFormatException(); + } + line.trim(); + if (!line.equals("endfacet")) { + System.out.println("Expected endfacet"); + br.close(); + throw new ModelFileFormatException(); + } + } + + TriangleArray triArray = new TriangleArray(verticies.size(), TriangleArray.COORDINATES); + for (int n = 0; n < verticies.size(); n++) { + triArray.setCoordinate(n, verticies.get(n)); + } + if (ap == null) ap = new Appearance(); + return new LeafModel(name, triArray, ap); + } + + private static Model3D loadStlBinaryFile(BufferedInputStream bis, byte[] header, Appearance ap, boolean bCalcNormal) throws IOException, ModelFileFormatException { + // Facet���ǂݍ��� + Integer numTri = readInt(bis); + if (numTri == null) { + System.out.println("Expected vertex count"); + bis.close(); + throw new ModelFileFormatException(); + } + + // Facet�ǂݍ��� + ArrayList verticies = new ArrayList(); + ArrayList normals = new ArrayList(); + Vector3f[] vertex = new Vector3f[] { + new Vector3f(), + new Vector3f(), + new Vector3f() + }; + + for (int n = 0; n < numTri; n++) { + Float nx = readFloat(bis); // �@��X���� + if (nx == null) { + System.out.println("Expected normal"); + bis.close(); + throw new ModelFileFormatException(); + } + + Float ny = readFloat(bis); // �@��Y���� + if (ny == null) { + System.out.println("Expected normal"); + bis.close(); + throw new ModelFileFormatException(); + } + + Float nz = readFloat(bis); // �@��Z���� + if (nz == null) { + System.out.println("Expected normal"); + bis.close(); + throw new ModelFileFormatException(); + } + + for (int i = 0; i < 3; i++) { + Float x = readFloat(bis); // X���W + if (x == null) { + System.out.println("Expected vertex" + (i + 1)); + bis.close(); + throw new ModelFileFormatException(); + } + + Float y = readFloat(bis); // Y���W + if (y == null) { + System.out.println("Expected vertex" + (i + 1)); + bis.close(); + throw new ModelFileFormatException(); + } + + Float z = readFloat(bis); // Z���W + if (z == null) { + System.out.println("Expected vertex" + (i + 1)); + bis.close(); + throw new ModelFileFormatException(); + } + + verticies.add(new float[]{x, y, z}); + vertex[i].x = x; + vertex[i].y = y; + vertex[i].z = z; + } + if (bCalcNormal) { + vertex[1].sub(vertex[0]); + vertex[2].sub(vertex[0]); + vertex[1].normalize(); + vertex[2].normalize(); + vertex[0].cross(vertex[1], vertex[2]); + nx = vertex[0].x; + ny = vertex[0].y; + nz = vertex[0].z; + } + normals.add(new float[]{nx, ny, nz}); + normals.add(new float[]{nx, ny, nz}); + normals.add(new float[]{nx, ny, nz}); + + byte[] optionBin = new byte[2]; + if (bis.read(optionBin) < 2) { + System.out.println("Expected option"); + bis.close(); + throw new ModelFileFormatException(); + } + } + + TriangleArray triArray = new TriangleArray(verticies.size(), TriangleArray.COORDINATES | TriangleArray.NORMALS); + for (int n = 0; n < verticies.size(); n++) { + triArray.setCoordinate(n, verticies.get(n)); + triArray.setNormal(n, normals.get(n)); + } + + if (ap == null) ap = new Appearance(); + return new LeafModel(new String(header), triArray, ap); + } + + /** + * OBJ�t�@�C���̓ǂݍ��� + * @param res ���\�[�X + * @param fileName �t�@�C���� + * @param bCalcNormal �@���̍Čv�Z���s���� + * @return �ǂݍ���3D���f�� + * @throws IOException + * @throws ModelFileFormatException + */ + public static Model3D loadObjFile(String fileName, boolean bCalcNormal) throws IOException, ModelFileFormatException { + File file = new File(fileName); + FileReader filereader = new FileReader(file); + BufferedReader br = new BufferedReader(filereader); + + HashMap appearances = new HashMap(); + ArrayList objects = new ArrayList(); + ArrayList groups = new ArrayList(); + ArrayList subGroups = new ArrayList(); + ArrayList objCoordinates = new ArrayList(); + ArrayList objTexCoordinates = new ArrayList(); + ArrayList objNormals = new ArrayList(); + ArrayList> subGroupCoordinateIndicies = new ArrayList>(); + ArrayList> subGroupTexCoordIndicies = new ArrayList>(); + ArrayList> subGroupNormalIndicies = new ArrayList>(); + String objectName = ""; + String groupName = ""; + String subGroupName = ""; + Appearance subGroupAp = null; + + String line = null; + while ((line = br.readLine()) != null) { + line.trim(); + String data[] = line.split(" "); + if (data[0].equals("#")) { + // �R�����g + } else if (data[0].equals("mtllib")) { + // �ގ��t�@�C���̎w�� + String dir = new File(fileName).getParent(); + String mtlFileName = line.substring(line.indexOf(" ") + 1); + String mtlFilePath = new File(dir, mtlFileName).getPath(); + appearances = loadMtlFile(mtlFilePath); + } else if (data[0].equals("o")) { + // �I�u�W�F�N�g�̊J�n + if (groups.size() > 0 || subGroups.size() > 0 || subGroupCoordinateIndicies.size() > 0) { + // �O�̃I�u�W�F�N�g�̃O���[�v�̎c��A�T�u�O���[�v�̎c��A�X�g���b�v�̎c���V�����I�u�W�F�N�g�Ƃ��Ēlj� + Model3D newObject = createRemainingObject(objectName, groups, groupName, objCoordinates, + objTexCoordinates, objNormals, subGroups, subGroupName, subGroupAp, + subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + objects.add(newObject); + groups.clear(); + } + + if (data.length < 1) { + System.out.println("Expected object's name"); + throw new ModelFileFormatException(); + } + objectName = data[1]; + } else if (data[0].equals("g")) { + // �O���[�v�̊J�n + if (subGroups.size() > 0 || subGroupCoordinateIndicies.size() > 0) { + // �O�̃O���[�v�̃T�u�O���[�v�̎c��A�X�g���b�v�̎c���V�����O���[�v�Ƃ��Ēlj� + Model3D newGroup = createRemainingGroup(groupName, objCoordinates, objTexCoordinates, objNormals, subGroups, + subGroupName, subGroupAp, subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + groups.add(newGroup); + subGroups.clear(); + } + + if (data.length < 1) { + System.out.println("Expected group's name"); + throw new ModelFileFormatException(); + } + groupName = data[1]; + } else if (data[0].equals("usemtl")) { + // �ގ��̎g�p(�T�u�O���[�v�̊J�n) + if (subGroupCoordinateIndicies.size() > 0) { + // �O�̃T�u�O���[�v�̃X�g���b�v�̎c���V�����T�u�O���[�v�Ƃ��Ēlj� + Model3D newSubGroup = createRemainingSubGroup(objCoordinates, objTexCoordinates, objNormals, + subGroupName, subGroupAp, subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + subGroups.add(newSubGroup); + subGroupCoordinateIndicies.clear(); + subGroupTexCoordIndicies.clear(); + subGroupNormalIndicies.clear(); + } + + if (data.length < 1) { + System.out.println("Expected mtl file's name"); + throw new ModelFileFormatException(); + } + subGroupAp = appearances.get(data[1]); + subGroupName = groupName + "_" + data[1] + subGroups.size(); // ���T�u�O���[�v�̖��O���d�����Ȃ��悤�ɂ��鏈�� + } else if (data[0].equals("v")) { + // ���_���W�f�[�^ + if (data.length < 4) { + System.out.println("Expected vertex coordinate"); + throw new ModelFileFormatException(); + } + float x = Float.parseFloat(data[1]); + float y = Float.parseFloat(data[2]); + float z = Float.parseFloat(data[3]); + Vector3f v = new Vector3f(x, y, z); + objCoordinates.add(v); + } else if (data[0].equals("vt")) { + // �e�N�X�`�����W�f�[�^ + if (data.length < 3) { + System.out.println("Expected texture coordinate"); + throw new ModelFileFormatException(); + } + float x = Float.parseFloat(data[1]); + float y = Float.parseFloat(data[2]); + Vector2f v = new Vector2f(x, y); + objTexCoordinates.add(v); + } else if (data[0].equals("vn")) { + // �@���x�N�g���f�[�^ + if (data.length < 4) { + System.out.println("Expected normal vector"); + throw new ModelFileFormatException(); + } + float x = Float.parseFloat(data[1]); + float y = Float.parseFloat(data[2]); + float z = Float.parseFloat(data[3]); + Vector3f v = new Vector3f(x, y, z); + objNormals.add(v); + } else if (data[0].equals("f")) { + // �|���S��(�X�g���b�v)�f�[�^ + if (data.length < 4) { + System.out.println("At least 3 verticies are needed"); + throw new ModelFileFormatException(); + } + ArrayList coordinateIndicies = new ArrayList(); + ArrayList texCoordIndicies = new ArrayList(); + ArrayList normalIndicies = new ArrayList(); + for (int n = 1; n < data.length; n++) { + String elements[] = data[n].split("/"); + if (elements.length >= 1) { + // ���_���W�C���f�b�N�X + coordinateIndicies.add(Integer.parseInt(elements[0]) - 1); + if (elements.length >= 2) { + // �e�N�X�`�����W�C���f�b�N�X + if (elements[0].length() > 0) { + // "v//vn"�̏ꍇ�����邽�� + texCoordIndicies.add(Integer.parseInt(elements[1]) - 1); + } + if (elements.length >= 3) { + // �@���x�N�g���C���f�b�N�X + normalIndicies.add(Integer.parseInt(elements[2]) - 1); + } + } + } + } + subGroupCoordinateIndicies.add(coordinateIndicies); + subGroupTexCoordIndicies.add(texCoordIndicies); + subGroupNormalIndicies.add(normalIndicies); + } + } + + // �t�@�C���ǂݍ��݌�̏��� + if (groups.size() > 0 || subGroups.size() > 0 || subGroupCoordinateIndicies.size() > 0) { + // �X�g���b�v�̎c��A�T�u�O���[�v�̎c��A�O���[�v�̎c����Ō�̃I�u�W�F�N�g�Ƃ��Ēlj� + Model3D newObject = createRemainingObject(objectName, groups, + groupName, objCoordinates, objTexCoordinates, objNormals, subGroups, + subGroupName, subGroupAp, subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + objects.add(newObject); + } + br.close(); + + if (objects.size() == 0) { + System.out.println("No polygon is included"); + throw new ModelFileFormatException(); + } else if (objects.size() == 1) { + if (groups.size() == 0) { + System.out.println("No polygon is included"); + throw new ModelFileFormatException(); + } else if (groups.size() == 1) { + // �O���[�v��������‚̏ꍇ + return groups.get(0); + } else { + // �I�u�W�F�N�g��������‚̏ꍇ + return objects.get(0); + } + } else { + // �I�u�W�F�N�g�������̏ꍇ + return new ContainerModel(fileName, (Model3D [])objects.toArray(new Model3D []{})); + } + } + + /** + * �O���[�v�̎c���V�����I�u�W�F�N�g�Ƃ��Ēlj� + * @param objectName �V�����I�u�W�F�N�g�̖��O + * @param groups�@�V�����I�u�W�F�N�g���\������O���[�v + * @param groupName + * @param groupCoordinates + * @param groupTexCoordinates + * @param groupNormals + * @param subGroups + * @param subGroupName + * @param subGroupAp + * @param subGroupCoordinateIndicies + * @param subGroupTexCoordIndicies + * @param subGroupNormalIndicies + * @return + */ + private static Model3D createRemainingObject(String objectName, ArrayList groups, + String groupName, ArrayList groupCoordinates, ArrayList groupTexCoordinates, + ArrayList groupNormals, ArrayList subGroups, + String subGroupName, Appearance subGroupAp, + ArrayList> subGroupCoordinateIndicies, + ArrayList> subGroupTexCoordIndicies, + ArrayList> subGroupNormalIndicies) { + if (subGroups.size() > 0 || subGroupCoordinateIndicies.size() > 0) { + // �X�g���b�v�̎c��A�T�u�O���[�v�̎c���V�����O���[�v�Ƃ��Ēlj� + Model3D newGroup = createRemainingGroup(groupName, groupCoordinates, groupTexCoordinates, groupNormals, subGroups, + subGroupName, subGroupAp, subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + groups.add(newGroup); + subGroups.clear(); + } + + // �O���[�v�̎c���V�����I�u�W�F�N�g�Ƃ��č쐬 + Model3D newObject = new ContainerModel(objectName, (Model3D [])groups.toArray(new Model3D []{})); + return newObject; + } + + /** + * �T�u�O���[�v�̎c���V�����O���[�v�Ƃ��č쐬 + * @param groupName�@�V�����O���[�v�̖��O + * @param groupCoordinates�@���_���W�̒l�̃��X�g + * @param groupTexCoordinates�@�e�N�X�`�����W�̒l�̃��X�g + * @param groupNormals�@�@���x�N�g���̒l�̃��X�g + * @param subGroups �V�����O���[�v���\������T�u�O���[�v + * @param subGroupName + * @param subGroupAp + * @param subGroupCoordinateIndicies + * @param subGroupTexCoordIndicies + * @param subGroupNormalIndicies + * @return + */ + private static Model3D createRemainingGroup(String groupName, + ArrayList groupCoordinates, ArrayList groupTexCoordinates, ArrayList groupNormals, + ArrayList subGroups, + String subGroupName, Appearance subGroupAp, + ArrayList> subGroupCoordinateIndicies, + ArrayList> subGroupTexCoordIndicies, + ArrayList> subGroupNormalIndicies) { + if (subGroupCoordinateIndicies.size() > 0) { + // �X�g���b�v�̎c���V�����T�u�O���[�v�Ƃ��Ēlj� + Model3D newSubGroup = createRemainingSubGroup(groupCoordinates, groupTexCoordinates, groupNormals, + subGroupName, subGroupAp, subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + subGroups.add(newSubGroup); + subGroupCoordinateIndicies.clear(); + subGroupTexCoordIndicies.clear(); + subGroupNormalIndicies.clear(); + } + + // �T�u�O���[�v�̎c���V�����O���[�v�Ƃ��č쐬 + return new ContainerModel(groupName, (Model3D [])subGroups.toArray(new Model3D []{})); + } + + /** + * �X�g���b�v�̎c���V�����T�u�O���[�v�Ƃ��č쐬 + * @param groupCoordinates + * @param groupTexCoordinates + * @param groupNormals + * @param subGroupName �V�����T�u�O���[�v�̖��O + * @param subGroupAp �V�����T�u�O���[�v�̕\�ʑ��� + * @param subGroupCoordinateIndicies�@���_���W�ւ̃C���f�b�N�X + * @param subGroupTexCoordIndicies �e�N�X�`�����W�ւ̃C���f�b�N�X + * @param subGroupNormalIndicies�@�@���x�N�g���ւ̃C���f�b�N�X + * @return + */ + private static Model3D createRemainingSubGroup(ArrayList groupCoordinates, + ArrayList groupTexCoordinates, ArrayList groupNormals, + String subGroupName, Appearance subGroupAp, ArrayList> subGroupCoordinateIndicies, + ArrayList> subGroupTexCoordIndicies, + ArrayList> subGroupNormalIndicies) { + // �X�g���b�v�̎c���V�����T�u�O���[�v�Ƃ��č쐬 + // Geometry �̍쐬 + GeometryArray geometry = createGeometryArray(groupCoordinates, groupTexCoordinates, groupNormals, + subGroupCoordinateIndicies, subGroupTexCoordIndicies, subGroupNormalIndicies); + // Object3D �̍쐬 + return new LeafModel(subGroupName, geometry, subGroupAp); + } + + /** + * �X�g���b�v�̃C���f�b�N�X��񂩂�W�I���g���[���쐬 + * @param groupCoordinates ���_���W�̒l�̃��X�g + * @param groupTexCoordinates �e�N�X�`�����W�̒l�̃��X�g + * @param groupNormals �@���x�N�g���̒l�̃��X�g + * @param subGroupCoordinateIndicies ���_���W�ւ̃C���f�b�N�X + * @param subGroupTexCoordIndicies �e�N�X�`�����W�ւ̃C���f�b�N�X + * @param subGroupNormalIndicies �@���x�N�g���ւ̃C���f�b�N�X + * @return �쐬�����W�I���g���[ + */ + private static GeometryArray createGeometryArray( + ArrayList groupCoordinates, + ArrayList groupTexCoordinates, + ArrayList groupNormals, + ArrayList> subGroupCoordinateIndicies, + ArrayList> subGroupTexCoordIndicies, + ArrayList> subGroupNormalIndicies) { + int vertexCount = 0; + int indexCount = 0; + for (int n = 0; n < subGroupCoordinateIndicies.size(); n++) { + ArrayList coordinateIndicies = subGroupCoordinateIndicies.get(n); + vertexCount += coordinateIndicies.size(); + indexCount += (coordinateIndicies.size() - 2) * 3; + } + int vertexFormat = IndexedGeometryArray.COORDINATES; + if (subGroupTexCoordIndicies.size() > 0) { + vertexFormat |= IndexedGeometryArray.TEXTURE_COORDINATE_2; + } + if (subGroupNormalIndicies.size() > 0) { + vertexFormat |= IndexedGeometryArray.NORMALS; + } + IndexedGeometryArray geometry = new IndexedTriangleArray(vertexCount, vertexFormat, indexCount); + int vertexNum = 0; + int index = 0; + for (int n = 0; n < subGroupCoordinateIndicies.size(); n++) { + ArrayList coordinateIndicies = subGroupCoordinateIndicies.get(n); + ArrayList texCoordIndicies = subGroupTexCoordIndicies.get(n); + ArrayList normalIndicies = subGroupNormalIndicies.get(n); + Vector3f c = groupCoordinates.get(coordinateIndicies.get(0)); + geometry.setCoordinate(vertexNum, new float[]{c.x, c.y, c.z}); + c = groupCoordinates.get(coordinateIndicies.get(1)); + geometry.setCoordinate(vertexNum + 1, new float[]{c.x, c.y, c.z}); + if (texCoordIndicies.size() > 0) { + Vector2f t = groupTexCoordinates.get(texCoordIndicies.get(0)); + geometry.setTextureCoordinate(vertexNum, new float[]{t.x, t.y}); + t = groupTexCoordinates.get(texCoordIndicies.get(1)); + geometry.setTextureCoordinate(vertexNum + 1, new float[]{t.x, t.y}); + } + if (normalIndicies.size() > 0) { + Vector3f nr = groupNormals.get(normalIndicies.get(0)); + geometry.setNormal(vertexNum, nr); + nr = groupNormals.get(normalIndicies.get(1)); + geometry.setNormal(vertexNum + 1, nr); + } + int firstCount = vertexNum; + vertexNum += 2; + for (int i = 2; i < coordinateIndicies.size(); i++) { + c = groupCoordinates.get(coordinateIndicies.get(i)); + geometry.setCoordinate(vertexNum, new float[]{c.x, c.y, c.z}); + geometry.setCoordinateIndex(index, firstCount); + geometry.setCoordinateIndex(index + 1, vertexNum - 1); + geometry.setCoordinateIndex(index + 2, vertexNum); + if (texCoordIndicies.size() > 0) { + Vector2f t = groupTexCoordinates.get(texCoordIndicies.get(i)); + geometry.setTextureCoordinate(vertexNum, new float[]{t.x, t.y}); + geometry.setTextureCoordinateIndex(index, firstCount); + geometry.setTextureCoordinateIndex(index + 1, vertexNum - 1); + geometry.setTextureCoordinateIndex(index + 2, vertexNum); + } + if (normalIndicies.size() > 0) { + Vector3f nr = groupNormals.get(normalIndicies.get(i)); + geometry.setNormal(vertexNum, nr); + geometry.setNormalIndex(index, firstCount); + geometry.setNormalIndex(index + 1, vertexNum - 1); + geometry.setNormalIndex(index + 2, vertexNum); + } + vertexNum += 1; + index += 3; + } + } + return geometry; +// ArrayList coordinateIndiciesMap = new ArrayList(); +// ArrayList texCoordIndiciesMap = new ArrayList(); +// ArrayList normalIndiciesMap = new ArrayList(); +// int indexCount = 0; +// int[] stripIndexCounts = new int[subGroupCoordinateIndicies.size()]; +// for (int n = 0; n < subGroupCoordinateIndicies.size(); n++) { +// ArrayList coordinateIndicies = subGroupCoordinateIndicies.get(n); +// ArrayList texCoordIndicies = subGroupTexCoordIndicies.get(n); +// ArrayList normalIndicies = subGroupNormalIndicies.get(n); +// indexCount += coordinateIndicies.size(); +// stripIndexCounts[n] = coordinateIndicies.size(); +// for (int i = 0; i < coordinateIndicies.size(); i++) { +// int c = coordinateIndicies.get(i); +// int coordinateIndex = coordinateIndiciesMap.indexOf(c); +// if (coordinateIndex == -1) { +// coordinateIndex = coordinateIndiciesMap.size(); +// coordinateIndiciesMap.add(c); +// } +// coordinateIndicies.set(i, coordinateIndex); +// if (texCoordIndicies.size() > 0) { +// int t = texCoordIndicies.get(i); +// int texCoordIndex = texCoordIndiciesMap.indexOf(t); +// if (texCoordIndex == -1) { +// texCoordIndex = texCoordIndiciesMap.size(); +// texCoordIndiciesMap.add(t); +// } +// texCoordIndicies.set(i, texCoordIndex); +// } +// if (normalIndicies.size() > 0) { +// int nr = normalIndicies.get(i); +// int normalIndex = normalIndiciesMap.indexOf(nr); +// if (normalIndex == -1) { +// normalIndex = normalIndiciesMap.size(); +// normalIndiciesMap.add(nr); +// } +// normalIndicies.set(i, normalIndex); +// } +// } +// } +// int vertexCount = coordinateIndiciesMap.size(); +// int vertexFormat = IndexedGeometryArray.COORDINATES; +// if (texCoordIndiciesMap.size() > 0) { +// if (vertexCount < texCoordIndiciesMap.size()) vertexCount = texCoordIndiciesMap.size(); +// vertexFormat |= IndexedGeometryArray.TEXTURE_COORDINATE_2; +// } +// if (normalIndiciesMap.size() > 0) { +// if (vertexCount < normalIndiciesMap.size()) vertexCount = normalIndiciesMap.size(); +// vertexFormat |= IndexedGeometryArray.NORMALS; +// } +// IndexedGeometryArray geometry = new IndexedTriangleFanArray(vertexCount, vertexFormat, indexCount, stripIndexCounts); +// for (int n = 0; n < coordinateIndiciesMap.size(); n++) { +// Vector3f c = groupCoordinates.get(coordinateIndiciesMap.get(n)); +// geometry.setCoordinate(n, new float[]{c.x, c.y, c.z}); +// } +// for (int n = 0; n < texCoordIndiciesMap.size(); n++) { +// Vector2f t = groupTexCoordinates.get(texCoordIndiciesMap.get(n)); +// geometry.setTextureCoordinate(n, new float[]{t.x, t.y}); +// } +// for (int n = 0; n < normalIndiciesMap.size(); n++) { +// Vector3f nr = groupNormals.get(normalIndiciesMap.get(n)); +// geometry.setNormal(n, nr); +// } +// int index = 0; +// for (int n = 0; n < subGroupCoordinateIndicies.size(); n++) { +// ArrayList coordinateIndicies = subGroupCoordinateIndicies.get(n); +// ArrayList texCoordIndicies = subGroupTexCoordIndicies.get(n); +// ArrayList normalIndicies = subGroupNormalIndicies.get(n); +// for (int i = 0; i < coordinateIndicies.size(); i++) { +// geometry.setCoordinateIndex(index, coordinateIndicies.get(i)); +// if (texCoordIndicies.size() > 0) { +// geometry.setTextureCoordinateIndex(index, texCoordIndicies.get(i)); +// } +// if (normalIndicies.size() > 0) { +// geometry.setNormalIndex(index, normalIndicies.get(i)); +// } +// index++; +// } +// } +// return geometry; + } + + /** + * MTL�t�@�C���̓ǂݍ��� + * @param res ���\�[�X + * @param fileName �t�@�C���� + * @return�@�ގ�������\�ʑ����I�u�W�F�N�g�ւ̃}�b�s���O + * @throws IOException + * @throws ModelFileFormatException + */ + private static HashMap loadMtlFile(String fileName) throws IOException, ModelFileFormatException { + File file = new File(fileName); + FileReader filereader = new FileReader(file); + BufferedReader br = new BufferedReader(filereader); + + HashMap appearances = new HashMap(); + String materialName; + Appearance ap = null; + Material m = null; + + String line = null; + while ((line = br.readLine()) != null) { + line.trim(); + String data[] = line.split(" "); + if (data[0].equals("newmtl")) { + if (data.length < 1) { + System.out.println("Expected material's name"); + throw new ModelFileFormatException(); + } + materialName = data[1]; + m = new Material(); + ap = new Appearance(); + ap.setMaterial(m); + appearances.put(materialName, ap); + } else if (data[0].equals("Kd")) { + if (data.length < 4) { + System.out.println("Expected diffuse color"); + throw new ModelFileFormatException(); + } + float r = Float.parseFloat(data[1]); + float g = Float.parseFloat(data[2]); + float b = Float.parseFloat(data[3]); + m.setDiffuseColor(r, g, b); + } else if (data[0].equals("Ka")) { + if (data.length < 4) { + System.out.println("Expected ambient color"); + throw new ModelFileFormatException(); + } + float r = Float.parseFloat(data[1]); + float g = Float.parseFloat(data[2]); + float b = Float.parseFloat(data[3]); + m.setAmbientColor(r, g, b); + } else if (data[0].equals("Ks")) { + if (data.length < 4) { + System.out.println("Expected specular color"); + throw new ModelFileFormatException(); + } + float r = Float.parseFloat(data[1]); + float g = Float.parseFloat(data[2]); + float b = Float.parseFloat(data[3]); + m.setSpecularColor(r, g, b); + } else if (data[0].equals("Tr")) { + if (data.length < 4) { + System.out.println("Expected emissive color"); + throw new ModelFileFormatException(); + } + float r = Float.parseFloat(data[1]); + float g = Float.parseFloat(data[2]); + float b = Float.parseFloat(data[3]); + m.setEmissiveColor(r, g, b); + } else if (data[0].equals("Ns")) { + if (data.length < 2) { + System.out.println("Expected shiness value"); + throw new ModelFileFormatException(); + } + float s = Float.parseFloat(data[1]); + m.setShininess(s); + } else if (data[0].equals("map_Kd")) { + if (data.length < 2) { + System.out.println("Expected texture file's name"); + throw new ModelFileFormatException(); + } + String dir = new File(fileName).getParent(); + String texFileName = line.substring(line.indexOf(" ") + 1); + String texFilePath = new File(dir, texFileName).getPath(); + TextureLoader texLoader = new TextureLoader(texFilePath, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); + ap.setTexture(texLoader.getTexture()); + } + } + return appearances; + } + + private static Integer readInt(BufferedInputStream bis) throws IOException { + byte[] intBin = new byte[4]; + if (bis.read(intBin, 3, 1) < 1) { + return null; + } + if (bis.read(intBin, 2, 1) < 1) { + return null; + } + if (bis.read(intBin, 1, 1) < 1) { + return null; + } + if (bis.read(intBin, 0, 1) < 1) { + return null; + } + return ByteBuffer.wrap(intBin).getInt(); + } + + private static Float readFloat(BufferedInputStream bis) throws IOException { + byte[] floatBin = new byte[4]; + if (bis.read(floatBin, 3, 1) < 1) { + return null; + } + if (bis.read(floatBin, 2, 1) < 1) { + return null; + } + if (bis.read(floatBin, 1, 1) < 1) { + return null; + } + if (bis.read(floatBin, 0, 1) < 1) { + return null; + } + return ByteBuffer.wrap(floatBin).getFloat(); + } +} diff --git a/src/main/java/framework/model3D/ModelFileFormatException.java b/src/main/java/framework/model3D/ModelFileFormatException.java new file mode 100644 index 0000000..d6b359b --- /dev/null +++ b/src/main/java/framework/model3D/ModelFileFormatException.java @@ -0,0 +1,5 @@ +package framework.model3D; + +public class ModelFileFormatException extends Exception { + +} diff --git a/src/main/java/framework/model3D/OBB.java b/src/main/java/framework/model3D/OBB.java new file mode 100644 index 0000000..f8dd6af --- /dev/null +++ b/src/main/java/framework/model3D/OBB.java @@ -0,0 +1,620 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import javax.media.j3d.BoundingPolytope; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Transform3D; +import javax.vecmath.Matrix4d; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; + +public class OBB implements Cloneable { + private ArrayList vertexList = new ArrayList(); + private Vector4d[] plane; + private BoundingPolytope bp = null; + private static int edges[][] = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 }, + { 0, 4 }, { 1, 5 }, { 3, 7 }, { 2, 6 }, + { 4, 5 }, { 4, 6 }, { 5, 7 }, { 6, 7 } }; + private static Integer planes[][] = { {0, 2, 3, 1}, {0, 1, 5, 4}, + {1, 3, 7, 5}, {4, 5, 7, 6}, + {0, 4, 6, 2}, {2, 6, 7, 3}}; + private static boolean[][] inside = new boolean[8][6]; + + public OBB() { + } + + public OBB(Vector3d v1, Vector3d v2, Vector3d v3, Vector3d v4, + Vector3d v5, Vector3d v6, Vector3d v7, Vector3d v8) { + vertexList.add(v1); + vertexList.add(v2); + vertexList.add(v3); + vertexList.add(v4); + vertexList.add(v5); + vertexList.add(v6); + vertexList.add(v7); + vertexList.add(v8); + createPlanes(); + } + + public void addVertex(Vector3d v) { + vertexList.add(v); + } + + public Vector3d getVertex(int i) { + return vertexList.get(i); + } + + public BoundingPolytope getBoundingPolytope() { + return bp; + } + + public BoundingSphere getBoundingSphere() { + double radius = 0.0; + Point3d p = new Point3d(); + Vector3d cv = new Vector3d(); + for (int i = 0; i < vertexList.size() - 1; i++) { + for (int j = i + 1; j < vertexList.size(); j++) { + Vector3d v = new Vector3d(); + v.sub(vertexList.get(i), vertexList.get(j)); + if (radius < v.length()) { + radius = v.length(); + cv.add(vertexList.get(i), vertexList.get(j)); + cv.scale(0.5); + p.x = cv.x; + p.y = cv.y; + p.z = cv.z; + } + } + } + BoundingSphere s = new BoundingSphere(p, radius / 2); + return s; + } + + /** + * ���_�������ɖʂ���ы��E���ʑ̂𐶐����� + */ + public void createPlanes() { + // �ʂ̍쐬 + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + Vector3d v3 = new Vector3d(); + Vector4d[] plane = new Vector4d[6]; + + // 0231 + v1 = getVertex(0); + v2.sub(getVertex(2), getVertex(0)); + v3.sub(getVertex(1), getVertex(0)); + Vector3d n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[0] = new Vector4d(); + plane[0].set(n.x, n.y, n.z, -n.dot(v1)); + + + // 0154 + v1 = getVertex(0); + v2.sub(getVertex(1), getVertex(0)); + v3.sub(getVertex(4), getVertex(0)); + n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[1] = new Vector4d(); + plane[1].set(n.x, n.y, n.z, -n.dot(v1)); + + // 1375 + v1 = getVertex(1); + v2.sub(getVertex(3), getVertex(1)); + v3.sub(getVertex(5), getVertex(1)); + n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[2] = new Vector4d(); + plane[2].set(n.x, n.y, n.z, -n.dot(v1)); + + // 4576 + v1 = getVertex(6); + v2.sub(getVertex(4), getVertex(6)); + v3.sub(getVertex(7), getVertex(6)); + n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[3] = new Vector4d(); + plane[3].set(n.x, n.y, n.z, -n.dot(v1)); + + // 0462 + v1 = getVertex(6); + v2.sub(getVertex(2), getVertex(6)); + v3.sub(getVertex(4), getVertex(6)); + n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[4] = new Vector4d(); + plane[4].set(n.x, n.y, n.z, -n.dot(v1)); + + // 2673 + v1 = getVertex(6); + v2.sub(getVertex(7), getVertex(6)); + v3.sub(getVertex(2), getVertex(6)); + n = new Vector3d(); + n.cross(v2, v3); + n.normalize(); + plane[5] = new Vector4d(); + plane[5].set(n.x, n.y, n.z, -n.dot(v1)); + + this.plane = plane; + + bp = new BoundingPolytope(); + bp.setPlanes(plane); + } + + /** + * ���ʂƂ̏Փ˔��� + * @param plane �Փ˔���̑ΏۂƂȂ镽�� + * @return �Փ˔���̌��ʁi�Փ˂��Ă��Ȃ��ꍇ��null�j + */ + public CollisionResult intersect(Vector4d plane) { + int i = 0; + boolean inside = false; + boolean outside = false; + int count = 0; + Vector3d center = new Vector3d(0, 0, 0); + ArrayList collisionPoints = new ArrayList(); + double l = Math.sqrt(plane.x * plane.x + plane.y * plane.y + plane.z * plane.z); + double length; + double deepest = 0.0; + Vector3d v; + for (i = 0; i < vertexList.size(); i++) { + v = vertexList.get(i); + if (GeometryUtility.inside(v, plane)) { + inside = true; + length = -(v.x * plane.x + v.y * plane.y + v.z * plane.z + plane.w) / l; + if (length > deepest + GeometryUtility.TOLERANCE) { + center.set(v); + collisionPoints.clear(); + collisionPoints.add(v); + count = 1; + deepest = length; + } else if (length >= deepest - GeometryUtility.TOLERANCE) { + center.add(v); + collisionPoints.add(v); + count++; + } + } else { + outside = true; + } + } + + if (!inside || !outside) { + // �S���_���O�����S���_�������̏ꍇ + return null; + } + + center.scale(1.0 / count); + + CollisionResult cr = new CollisionResult(); + cr.length = deepest; + cr.collisionPoint.setVector3d(center); + cr.collisionPoints = collisionPoints; + cr.normal.setX(plane.x / l); + cr.normal.setY(plane.y / l); + cr.normal.setZ(plane.z / l); + + return cr; + } + + /** + * OBB�Ƃ̏Փ˔��� + * @param another �Փ˔���̑ΏۂƂȂ�OBB + * @return �Փ˔���̌��ʁi�Փ˂��Ă��Ȃ��ꍇ��null�j + */ + public CollisionResult intersect(OBB another) { + // another�̊e���_��this�̊e�ʂ̓����ɂ��邩�𒲂ׂ� + // i�Fanother�̒��_, j�Fthis�̖� + OBB o1 = this; + OBB o2 = another; + for (int i = 0; i < o2.vertexList.size(); i++) { + for (int j = 0; j < o1.plane.length; j++) { + inside[i][j] = GeometryUtility.inside(o2.vertexList.get(i), o1.plane[j]); + } + } + + int v = 0; + boolean bCollides = false; + + // another�̊e���_��this�ɕ�܂���Ă��邩�H + Vector3d contactCenter = new Vector3d(); + int count = 0; + for (int i = 0; i < o2.vertexList.size(); i++) { + boolean f1 = false; + for (int p = 0; p < o1.plane.length; p++) { + f1 = inside[i][p]; + if (!f1) break; // ��܂���Ă��Ȃ� + } + if (f1) { + // this�̂��ׂĂ̖ʂ̓��� �� this�ɕ�܂���Ă��� + if (!bCollides) { + bCollides = true; + v = i; + } + contactCenter.add(o2.vertexList.get(i)); + count++; + } + } + if (!bCollides) { + // this�̊e���_��another�̊e�ʂ̓����ɂ��邩�𒲂ׂ� + o1 = another; + o2 = this; + for (int i = 0; i < o2.vertexList.size(); i++) { + for (int j = 0; j < o1.plane.length; j++) { + inside[i][j] = GeometryUtility.inside(o2.vertexList.get(i), o1.plane[j]); + } + } + // this�̊e���_��another�ɕ�܂���Ă��邩�H + for (int i = 0; i < o2.vertexList.size(); i++) { + boolean f1 = false; + for (int p = 0; p < o1.plane.length; p++) { + f1 = inside[i][p]; + if (!f1) break; // ��܂���Ă��Ȃ� + } + if (f1) { + // another�̂��ׂĂ̖ʂ̓��� �� another�ɕ�܂���Ă��� + if (!bCollides) { + bCollides = true; + v = i; + } + contactCenter.add(o2.vertexList.get(i)); + count++; + } + } + } + + CollisionResult cr = new CollisionResult(); + ArrayList collisionPoints = new ArrayList(); + if (bCollides) { + // �����ꂩ��OBB�̒��_v��������OBB�ɕ�܂���Ă����ꍇ(v�����‘���OBB��o2�A������o1�Ƃ���) + // o1�̂ǂ̖ʂƏՓ˂������𔻒肷�� + double lMin = 0; + int p1 = -1; + Vector3d normal = null; + contactCenter.scale(1.0 / (double)count); + for (int p = 0; p < o1.plane.length; p++) { + Vector3d n = new Vector3d(o1.plane[p].x, o1.plane[p].y, o1.plane[p].z); + double l = -(contactCenter.x * o1.plane[p].x + contactCenter.y * o1.plane[p].y + + contactCenter.z * o1.plane[p].z + o1.plane[p].w) / n.length(); + if (lMin > l || normal == null) { + lMin = l; + p1 = p; + normal = n; + } + } + + // o2���v���܂ޕӂ̂����Փ˖ʂ̖@���Ƌt�����Ɍ������Ă���ӂ�T��(���̂悤�ȕӂ̐��ɂ���ĐڐG�󋵂��ς��) + Vector3d collisionPoint = o2.vertexList.get(v); + Vector3d d1; + ArrayList contactEdges = new ArrayList(); + for (int e = 0; e < edges.length; e++) { + if (v == edges[e][0]) { + d1 = new Vector3d(o2.vertexList.get(edges[e][1])); + d1.sub(collisionPoint); + if (normal.dot(d1) < GeometryUtility.TOLERANCE) { + // �Փ˖ʂɐڂ��Ă���� + contactEdges.add(edges[e][1]); // v�̔��Α��̒[�_ + } + } else if (v == edges[e][1]) { + d1 = new Vector3d(o2.vertexList.get(edges[e][0])); + d1.sub(collisionPoint); + if (normal.dot(d1) < GeometryUtility.TOLERANCE) { + // �Փ˖ʂɐڂ��Ă���� + contactEdges.add(edges[e][0]); // v�̔��Α��̒[�_ + } + } + } + + // �ڐG�󋵂ɉ��������� + if (contactEdges.size() == 0) { + // a) ���_�ŐڐG + collisionPoints.add(collisionPoint); + cr.collisionPoint.setVector3d(collisionPoint); + } else if (contactEdges.size() == 1) { + // b) �ӂŐڐG + boolean f1 = true; + Vector3d otherPoint = o2.vertexList.get(contactEdges.get(0)); + Vector3d intersectionPoint = null; + double nearest = 0.0; + for (int p = 0; p < o1.plane.length; p++) { + if (!inside[contactEdges.get(0)][p]) { + // collisionPoint �Ɓ@otherPoint �̊Ԃ�ʂ镽�� + Vector3d ip = GeometryUtility.intersect(o1.plane[p], collisionPoint, otherPoint); + if (ip != null) { + f1 = false; // ��܂���Ă��Ȃ� + Vector3d ip2 = (Vector3d)ip.clone(); + ip2.sub(collisionPoint); + double d = ip2.length(); + if (intersectionPoint == null || d < nearest) { + intersectionPoint = ip; + nearest = d; + } + } + } + } + if (f1) { + // b-1) �ӑS�̂��ڐG���Ă��� + collisionPoints.add(collisionPoint); + collisionPoints.add(otherPoint); + Vector3d center = new Vector3d(collisionPoint); + center.add(otherPoint); + center.scale(0.5); + cr.collisionPoint.setVector3d(center); + } else { + // b-2) �ӂ̈ꕔ���ڐG���Ă��� + collisionPoints.add(collisionPoint); + collisionPoints.add(intersectionPoint); + Vector3d center = new Vector3d(collisionPoint); + center.add(intersectionPoint); + center.scale(0.5); + cr.collisionPoint.setVector3d(center); + } + } else { + // c) �ʂŐڐG + Vector3d center = new Vector3d(); + int v2 = contactEdges.get(0); + int v3 = contactEdges.get(1); + int p2; + for (p2 = 0; p2 < o2.plane.length; p2++) { + if (v == planes[p2][0] || v == planes[p2][1] || v == planes[p2][2] || v == planes[p2][3]) { + if (v2 == planes[p2][0] || v2 == planes[p2][1] || v2 == planes[p2][2] || v2 == planes[p2][3]) { + if (v3 == planes[p2][0] || v3 == planes[p2][1] || v3 == planes[p2][2] || v3 == planes[p2][3]) { + break; + } + } + } + } + // o1�̖�p1��o2�̖�p2���ڂ��Ă��� + // �ʂƖʂ̋��ʗ̈�����߂� + for (v2 = 0; v2 < 4; v2++) { + if (planes[p2][v2] == v) break; + } + Vector3d d2 = (Vector3d)o2.vertexList.get(planes[p2][(v2 + 1) % 4]).clone(); + d2.sub(collisionPoint); + d2.cross(normal, d2); + int sign = -1; + int v1; + for (v1 = 4; v1 >= 0; v1--) { + d1 = (Vector3d)o1.vertexList.get(planes[p1][v1 % 4]).clone(); + d1.sub(o1.vertexList.get(planes[p1][(v1 + 1) % 4])); + if (d2.dot(d1) > -GeometryUtility.TOLERANCE) { + sign = 1; + } else if (sign == 1) { + // ���ς̕����������畉�ɕς�����Ƃ� + v1 = (v1 + 1) % 4; + break; + } + } + Vector3d vp1, vp2, dst1, dst2, src1, src2, d3; + ArrayList contours = new ArrayList(); + for (int i = 0; i < 4; i++) { + dst1 = vp1 = (Vector3d)o1.vertexList.get(planes[p1][(v1 - i + 4) % 4]).clone(); + src2 = vp2 = (Vector3d)o2.vertexList.get(planes[p2][(v2 + i) % 4]).clone(); + src1 = (Vector3d)o1.vertexList.get(planes[p1][(v1 - i + 4 + 1) % 4]).clone(); + dst2 = (Vector3d)o2.vertexList.get(planes[p2][(v2 + i + 1) % 4]).clone(); + d1 = (Vector3d)dst1.clone(); + d1.sub(src1); + d2 = (Vector3d)dst2.clone(); + d2.sub(src2); + d3 = (Vector3d)vp2.clone(); + d3.sub(vp1); + d1.cross(d1, normal); + if (d1.dot(d3) < GeometryUtility.TOLERANCE) { + // o1�̕��́A���_vp2�̓����ɂ���̂ŁA���ʗ̈�̗֊s���\������ + contours.add(new Vector3d[]{src1, dst1}); + } + d3.negate(); + d2.cross(d2, normal); + if (d2.dot(d3) < GeometryUtility.TOLERANCE) { + // o2�̕��́A���_vp1�̓����ɂ���̂ŁA���ʗ̈�̗֊s���\������ + contours.add(new Vector3d[]{src2, dst2}); + } + } + Vector3d[] edge1, edge2; + Vector3d d; + Vector4d p; + for (int i = 0; i < contours.size(); i++) { + edge1 = contours.get(i); + edge2 = contours.get((i + 1) % contours.size()); + if (edge1[1].equals(edge2[0])) { + // edge1��edge2�͎n�_�ƏI�_�����L���Ă��� + if (!collisionPoints.contains(edge1[1])) { + collisionPoints.add(edge1[1]); + center.add(edge1[1]); + } + } else if (!edge1[0].equals(edge2[0]) && !edge1[1].equals(edge2[1])) { + // edge1��edge2�̌�_�����߂� + d = (Vector3d)edge2[1].clone(); + d.add(normal); + p = GeometryUtility.createPlane(edge2[0], edge2[1], d); + if (p != null) { + d = GeometryUtility.intersect(p, edge1[0], edge1[1]); + if (d != null && !collisionPoints.contains(d)) { + collisionPoints.add(d); + center.add(d); + } + } + } + } + if (collisionPoints.size() <= 2) return null; // �ʂŐڐG���Ă���͂���2�_�ȉ��ł���ꍇ�A�Փ˂��Ă��Ȃ� + center.scale(1.0 / (double)collisionPoints.size()); + cr.collisionPoint.setVector3d(center); + } + cr.length = lMin; + cr.collisionPoints = collisionPoints; + if (o2 == this) normal.negate(); + normal.normalize(); + cr.normal = normal; + return cr; + } else { + // another�̕ӂ�this�̖ʂƌ�����Ă��邩�H + Vector3d center = new Vector3d(); + Vector3d normal = new Vector3d(); + ArrayList intersections = new ArrayList(); + ArrayList contactPlanes = new ArrayList(); + for (int e = 0; e < edges.length; e++) { + // another�̊e��e�ɑ΂��ď��� + Vector3d intersection = null; + intersections.clear(); + contactPlanes.clear(); + for (int p = 0; p < this.plane.length; p++) { + if (inside[edges[e][0]][p] == !inside[edges[e][1]][p]) { + // another�̕�e���Athis�̖�p���т��Ă��� + Vector3d ip = GeometryUtility.intersect( + this.plane[p], + another.vertexList.get(edges[e][0]), + another.vertexList.get(edges[e][1])); + // e��p�̌�_��this�ɕ�܂���Ă��邩? + if (ip != null) { + intersection = ip; + boolean bInside = true; + for (int p2 = 0; p2 < 6; p2++) { + if (p != p2 + && !GeometryUtility.inside(intersection, this.plane[p2])) { + bInside = false; + break; + } + } + if (bInside) { + // e��p�ƌ�����Ă��� + contactPlanes.add(p); + intersections.add(intersection); + bCollides = true; + } + } + } + } + if (contactPlanes.size() == 1) { + // e�ƌ�����Ă���this�̖ʂ�1�� + collisionPoints.add(intersection); + center.add(intersection); + } else if (contactPlanes.size() == 2) { + // e�ƌ�����Ă���this�̖ʂ�2�� + int p1 = contactPlanes.get(0); + int p2 = contactPlanes.get(1); + ArrayList p1vs = new ArrayList(Arrays.asList(planes[p1])); + ArrayList p2vs = new ArrayList(Arrays.asList(planes[p2])); + p1vs.retainAll(p2vs); + if (p1vs.size() == 2) { + // p1��p2�ׂ͗荇����(another�̕�e��this�̂���ӂƐڐG���Ă���) + Vector3d v1 = this.vertexList.get(p1vs.get(0)); // p1��p2�̊Ԃ̕ӂ̎n�_ + Vector3d v2 = this.vertexList.get(p1vs.get(1)); // p1��p2�̊Ԃ̕ӂ̏I�_ + Vector3d d1 = (Vector3d)v1.clone(); + d1.sub(v2); + Vector3d d2 = (Vector3d)another.vertexList.get(edges[e][0]).clone(); + d2.sub(another.vertexList.get(edges[e][1])); + normal.cross(d1, d2); // ��e�ƁAp1��p2�̊Ԃ̕ӂ̗����ɐ����ȃx�N�g����@�������Ƃ��� + normal.normalize(); + Vector3d n1 = new Vector3d(this.plane[p1].x, this.plane[p1].y, this.plane[p1].z); + Vector3d n2 = new Vector3d(this.plane[p2].x, this.plane[p2].y, this.plane[p2].z); + n1.normalize(); + n2.normalize(); + n1.add(n2); + n1.scale(0.5); + if (n1.dot(normal) < -GeometryUtility.TOLERANCE) { + normal.negate(); + } + intersection = intersections.get(0); + intersection.add(intersections.get(1)); + intersection.scale(0.5); + center.add(intersection); // �Փ˓_��1�� + collisionPoints.add(intersection); + Vector3d c = GeometryUtility.nearest(v1, v2, center); + c.sub(center); + cr.length = c.length(); + cr.normal = normal; + } else { + // p1��p2�͌�����������(another�̕�e��this�̂���ʂƐڐG���Ă���) + center.add(intersections.get(0)); // �Փ˓_��2�� + center.add(intersections.get(1)); + collisionPoints.add(intersections.get(0)); + collisionPoints.add(intersections.get(1)); + // this�̂ǂ̖ʂƏՓ˂������𔻒肷�� + double lMin = 0; + normal = null; + Vector4d plane; + for (int p = 0; p < this.plane.length; p++) { + plane = this.plane[p]; + Vector3d n = new Vector3d(plane.x, plane.y, plane.z); + double l = -(center.x * plane.x + center.y * plane.y + center.z * plane.z + plane.w) / n.length(); + if (lMin > l || normal == null) { + lMin = l; + normal = n; + } + } + normal.normalize(); + cr.length = lMin; + cr.normal = normal; + } + } + } + if (!bCollides) return null; + center.scale(1.0 / (double)collisionPoints.size()); + cr.collisionPoint.setVector3d(center); + cr.collisionPoints = collisionPoints; + return cr; + } + } + + public Object clone() { + OBB obb = new OBB(); + obb.plane = new Vector4d[6]; + for (int i = 0; i < plane.length; i++) { + obb.plane[i] = (Vector4d) plane[i].clone(); + + } + for (int i = 0; i < vertexList.size(); i++) { + obb.vertexList.add((Vector3d) vertexList.get(i).clone()); + } + obb.bp = new BoundingPolytope(obb.plane); + + // System.out.println("veretexListSIZE:"+vertexList.size()); + return obb; + } + + public void transform(Transform3D t) { + // TODO Auto-generated method stub + bp.transform(t); + bp.getPlanes(plane); + // for(int i = 0; i" + plane[i].x + "," + plane[i].y + "," + + // plane[i].z + "," + plane[i].w); + // } + for (int i = 0; i < vertexList.size(); i++) { + // System.out.println("vertex"); + // System.out.print(vertexList.get(i).x + "," + vertexList.get(i).y + // + "," + vertexList.get(i).z); + Matrix4d mat4d = new Matrix4d(); + t.get(mat4d); + double x = mat4d.m00 * vertexList.get(i).x + mat4d.m01 + * vertexList.get(i).y + mat4d.m02 * vertexList.get(i).z + + mat4d.m03; + double y = mat4d.m10 * vertexList.get(i).x + mat4d.m11 + * vertexList.get(i).y + mat4d.m12 * vertexList.get(i).z + + mat4d.m13; + double z = mat4d.m20 * vertexList.get(i).x + mat4d.m21 + * vertexList.get(i).y + mat4d.m22 * vertexList.get(i).z + + mat4d.m23; + vertexList.get(i).x = x; + vertexList.get(i).y = y; + vertexList.get(i).z = z; + // t.transform(vertexList.get(i)); + // System.out.println("-->" + vertexList.get(i).x + "," + + // vertexList.get(i).y + "," + vertexList.get(i).z); + } + } +} diff --git a/src/main/java/framework/model3D/Object3D.java b/src/main/java/framework/model3D/Object3D.java new file mode 100644 index 0000000..f6b9dac --- /dev/null +++ b/src/main/java/framework/model3D/Object3D.java @@ -0,0 +1,734 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Geometry; +import javax.media.j3d.GeometryStripArray; +import javax.media.j3d.IndexedGeometryArray; +import javax.media.j3d.LOD; +import javax.media.j3d.Leaf; +import javax.media.j3d.Node; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.TriangleArray; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Quat4d; +import javax.vecmath.Vector3d; + +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.Cone; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Primitive; +import com.sun.j3d.utils.geometry.Sphere; + +/** + * �K�w�����ꖼ�O�t����ꂽ��{�I�u�W�F�N�g + * @author �V�c���� + * + */ +public class Object3D extends BaseObject3D { + public Object3D[] children = new Object3D[0]; + public String name; + public TransformGroup pos; + public TransformGroup rot; + public TransformGroup scale; + protected Position3D position = new Position3D(); + protected Quaternion3D quaternion; + + public BoundingSphere bs = null; + private OBB obb = null; + private UndoBuffer undoBuffer = new UndoBuffer(); + private boolean bLOD = false; + private LOD lodNode = null; + + // �R���X�g���N�^ + public Object3D(String name, Primitive node) { + if (name == null) name = ""; + this.name = new String(name); + pos = new TransformGroup(); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + rot = new TransformGroup(); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + scale = new TransformGroup(); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + pos.addChild(rot); + rot.addChild(scale); + scale.addChild(center); + center.addChild(node); + } + + public Object3D(String name, Leaf node) { + if (name == null) name = ""; + this.name = new String(name); + if (!(node instanceof LOD)) { + pos = new TransformGroup(); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + rot = new TransformGroup(); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + scale = new TransformGroup(); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + pos.addChild(rot); + rot.addChild(scale); + scale.addChild(center); + center.addChild(node); + } else { + // LOD �̏ꍇ + bLOD = true; + lodNode = (LOD)node; + pos = new TransformGroup(); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + rot = new TransformGroup(); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + scale = new TransformGroup(); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + pos.addChild(rot); + rot.addChild(scale); + scale.addChild(center); + BranchGroup lodRoot = new BranchGroup(); + lodRoot.addChild(lodNode); + lodRoot.addChild(lodNode.getSwitch(0)); + center.addChild(lodRoot); + } + } + + public Object3D(String name, Geometry g, Appearance a) { + if (name == null) name = ""; + this.name = new String(name); + pos = new TransformGroup(); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + rot = new TransformGroup(); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + scale = new TransformGroup(); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + Shape3D shape = new Shape3D(g, a); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + pos.addChild(rot); + rot.addChild(scale); + scale.addChild(center); + center.addChild(shape); + } + + // �R���X�g���N�^ + public Object3D(String name, Object3D[] children) { + if (name == null) + name = ""; + this.name = name; + this.children = children; + int n = children.length; + int i = 0; + + pos = new TransformGroup(); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + rot = new TransformGroup(); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + scale = new TransformGroup(); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + center = new TransformGroup(); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + pos.addChild(rot); + rot.addChild(scale); + scale.addChild(center); + + for (i = 0; i < n; i++) { + center.addChild(children[i].pos); + if (children[i].isBumpMappingApplied()) bBumpMapApplied = true; + if (children[i].isReflectionMappingApplied()) bReflectionMapApplied = true; + } + } + + public Object3D(String name, Object3D[] children, + Transform3D defaultTransform) { + this(name, children); + if (defaultTransform == null) return; + pos.setTransform(defaultTransform); + } + + // �R�s�[�R���X�g���N�^ + public Object3D(Object3D obj) { + this.name = new String(obj.name); + if (obj.position != null) { + this.position = new Position3D(obj.position); + } else { + this.position = new Position3D(); + } + if (obj.getQuaternion() != null) { + this.quaternion = new Quaternion3D(obj.getQuaternion()); + } else { + this.quaternion = new Quaternion3D(); + } + Transform3D transPos = new Transform3D(); + obj.pos.getTransform(transPos); + this.pos = new TransformGroup(transPos); + this.pos.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + this.pos.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Transform3D transRot = new Transform3D(); + obj.rot.getTransform(transRot); + this.rot = new TransformGroup(transRot); + this.rot.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + this.rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Transform3D transScale = new Transform3D(); + obj.scale.getTransform(transScale); + this.scale = new TransformGroup(transScale); + this.scale.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + this.scale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Transform3D transCenter = new Transform3D(); + obj.center.getTransform(transCenter); + this.center = new TransformGroup(transCenter); + this.center.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + this.center.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + this.pos.addChild(this.rot); + this.rot.addChild(this.scale); + this.scale.addChild(this.center); + this.bLOD = obj.bLOD; + if (obj.hasChildren()) { + this.children = new Object3D[obj.children.length]; + for (int i = 0; i < obj.children.length; i++) { + this.children[i] = new Object3D(obj.children[i]); + this.center.addChild(this.children[i].pos); + } + } else { + this.children = new Object3D[0]; + if (!bLOD) { + Enumeration nodes = obj.getPrimitiveNodes(); + while (nodes.hasMoreElements()) { + Node node = nodes.nextElement(); + if (node != null && node instanceof Shape3D) { + Shape3D shape = (Shape3D)node; + shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + Appearance a = (Appearance)shape.getAppearance().cloneNodeComponent(true); + a.setCapability(Appearance.ALLOW_TEXTURE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); + a.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + this.center.addChild(new Shape3D((Geometry) shape + .getAllGeometries().nextElement(), a)); + } else if (node != null && node instanceof Primitive) { + Primitive primitive = (Primitive)node; + primitive = (Primitive)primitive.cloneTree(); + primitive.setCapability(Primitive.ENABLE_APPEARANCE_MODIFY); + this.center.addChild(primitive); + } + } + } else { + // LOD �̏ꍇ + this.lodNode = (LOD)obj.lodNode.cloneTree(); + BranchGroup lodRoot = new BranchGroup(); + lodRoot.addChild(lodNode); + lodRoot.addChild(lodNode.getSwitch(0)); + this.center.addChild(lodRoot); + } + } + if (obj.obb != null) { + this.obb = obj.obb; + } + if (obj.bs != null) { + this.bs = obj.bs; + } + if (obj.boundingSurfaces != null) { + this.boundingSurfaces = obj.boundingSurfaces; + } + this.undoBuffer = new UndoBuffer(obj.undoBuffer); + } + + public Node getPrimitiveNode() { + if (hasChildren()) return null; + if (!bLOD) { + return (Node)center.getChild(0); + } else { + // LOD �̏ꍇ + return lodNode.getSwitch(0).getChild(0); + } + } + + public Enumeration getPrimitiveNodes() { + if (hasChildren()) return null; + if (!bLOD) { + return (Enumeration)center.getAllChildren(); + } else { + // LOD �̏ꍇ + return lodNode.getSwitch(0).getAllChildren(); + } + } + + public ArrayList getAppearances() { + ArrayList appearances = new ArrayList(); + if (!bLOD) { + if (!hasChildren()) { + appearances.add(getAppearance()); + } else { + for (int n = 0; n < children.length; n++) { + appearances.addAll(children[n].getAppearances()); + } + } + return appearances; + } else { + // LOD �̏ꍇ + Enumeration nodes = getPrimitiveNodes(); + while (nodes.hasMoreElements()) { + Node node = nodes.nextElement(); + Appearance ap = null; + if (node != null && node instanceof Shape3D) { + Shape3D shape = (Shape3D)node; + ap = shape.getAppearance(); + if (ap == null) { + ap = new Appearance(); + shape.setAppearance(ap); + } + } else if (node != null && node instanceof Primitive) { + Primitive primitive = (Primitive)node; + ap = primitive.getAppearance(); + if (ap == null) { + ap = new Appearance(); + primitive.setAppearance(ap); + } + } + appearances.add(ap); + } + return appearances; + } + } + + // ����part�i�����j�̃I�u�W�F�N�g��T�� + public Object3D getPart(String part) { + + int j = 0; + int N = children.length; + Object3D obj; + + // if(part == children[j].name) return this; + if (part.equals(this.name)) + return this; + + for (j = 0; j < N; j++) { + if (children[j] != null) { + obj = children[j].getPart(part); + if (obj != null) + return obj; + else + continue; + } + } + return null; + } + + @Override + public TransformGroup getTransformGroupToPlace() { + return pos; + } + + // Position3D �� applyTo() �ȊO����͌Ă΂Ȃ����� + void setPosition(Position3D p) { + position = (Position3D) p.clone(); + Vector3d v = new Vector3d(p.getX(), p.getY(), p.getZ()); + Transform3D trans = new Transform3D(); + trans.set(v); + pos.setTransform(trans); + } + + public void scale(double s) { + Transform3D trans = new Transform3D(); + trans.setScale(s); + scale.setTransform(trans); + } + + public void scale(double x, double y, double z) { + Transform3D trans = new Transform3D(); + trans.setScale(new Vector3d(x, y, z)); + scale.setTransform(trans); + } + + public Position3D getPosition3D() { + return (Position3D) position.clone(); + + } + + // �L�����N�^�[����]������ + public void rotate(double vx, double vy, double vz, double a) { + AxisAngle4d t = new AxisAngle4d(vx, vy, vz, a); + Transform3D trans = new Transform3D(); + trans.setRotation(t); + rot.setTransform(trans); + } + + private void rotate(Quat4d quat) { + Transform3D trans = new Transform3D(); + trans.setRotation(quat); + rot.setTransform(trans); + } + + // �L�����N�^�[��part(�̂̕���)����]������ + public void rotate(String part, double vx, double vy, double vz, double a) { + getPart(part).rotate(vx, vy, vz, a); + } + + public void apply(Property3D p, boolean enableUndo) { + if (enableUndo) { + undoBuffer.push(p); + } + p.applyTo(this); + } + + // �����𕡐�����i�N���[�������j + public Object3D duplicate() { + Object3D obj = new Object3D(this); + return obj; + } + + // v�i�K��ҁj�ɖK���������� + public void accept(ObjectVisitor v) { + int i; + v.preVisit(this); + if (children != null) { + for (i = 0; i < children.length; i++) + children[i].accept(v); + } else + ; + v.postVisit(this); + } + + // object�Ɏq�������邩�ǂ����𒲂ׂ� + public boolean hasChildren() { + if (this.children != null && this.children.length > 0) + return true; + else + return false; + } + + /* + * undo����|�C���g��ݒ肷��B + */ + public void setUndoMark() { + undoBuffer.setUndoMark(); + } + + /* + * undo����B + */ + public void undo() { + Iterator iterator = undoBuffer.undo().iterator(); + while (iterator.hasNext()) { + Property3D p = iterator.next(); + p.applyTo(this); + } + } + + /** + * �����蔻�菈���AOriented Bounding Box(OBB)������B 0:�ő�ʐϖ@�@1:�Œ��Ίp���@ + */ + public OBB getOBB(int pattern) { + if (obb == null) { + Node node = getPrimitiveNode(); + if (node == null) return null; + if (node instanceof Box) { + // Box�̏ꍇ + Box box = ((Box)node); + double xDim = box.getXdimension(); + double yDim = box.getYdimension(); + double zDim = box.getZdimension(); + obb = new OBB(new Vector3d(-xDim, -yDim, -zDim), + new Vector3d(-xDim, yDim, -zDim), + new Vector3d(-xDim, -yDim, zDim), + new Vector3d(-xDim, yDim, zDim), + new Vector3d(xDim, -yDim, -zDim), + new Vector3d(xDim, yDim, -zDim), + new Vector3d(xDim, -yDim, zDim), + new Vector3d(xDim, yDim, zDim)); + } else if (node instanceof Cylinder) { + // Cylinder�̏ꍇ + Cylinder cylinder = ((Cylinder)node); + double xDim = cylinder.getRadius(); + double yDim = cylinder.getHeight() / 2; + double zDim = cylinder.getRadius(); + obb = new OBB(new Vector3d(-xDim, -yDim, -zDim), + new Vector3d(-xDim, yDim, -zDim), + new Vector3d(-xDim, -yDim, zDim), + new Vector3d(-xDim, yDim, zDim), + new Vector3d(xDim, -yDim, -zDim), + new Vector3d(xDim, yDim, -zDim), + new Vector3d(xDim, -yDim, zDim), + new Vector3d(xDim, yDim, zDim)); + } else if (node instanceof Cone) { + // Cone�̏ꍇ + Cone cone = ((Cone)node); + double xDim = cone.getRadius(); + double yDim = cone.getHeight() / 2; + double zDim = cone.getRadius(); + obb = new OBB(new Vector3d(-xDim, -yDim, -zDim), + new Vector3d(-xDim, yDim, -zDim), + new Vector3d(-xDim, -yDim, zDim), + new Vector3d(-xDim, yDim, zDim), + new Vector3d(xDim, -yDim, -zDim), + new Vector3d(xDim, yDim, -zDim), + new Vector3d(xDim, -yDim, zDim), + new Vector3d(xDim, yDim, zDim)); + } else if (node instanceof Sphere) { + // Sphere�̏ꍇ + Sphere sphere = ((Sphere)node); + double xDim = sphere.getRadius(); + double yDim = sphere.getRadius(); + double zDim = sphere.getRadius(); + obb = new OBB(new Vector3d(-xDim, -yDim, -zDim), + new Vector3d(-xDim, yDim, -zDim), + new Vector3d(-xDim, -yDim, zDim), + new Vector3d(-xDim, yDim, zDim), + new Vector3d(xDim, -yDim, -zDim), + new Vector3d(xDim, yDim, -zDim), + new Vector3d(xDim, -yDim, zDim), + new Vector3d(xDim, yDim, zDim)); + } else { + if (!(node instanceof Shape3D)) return null; + // Shape3D�̏ꍇ + Shape3D shape = (Shape3D)node; + double coordinate[] = new double[3]; + + // OBB�̍쐬�ɗp���钸�_��̎擾 + ArrayList vertex3DList = new ArrayList(); + if (shape.getGeometry() instanceof IndexedGeometryArray) { + // IndexedGeometryArray�̏ꍇ + IndexedGeometryArray iga = (IndexedGeometryArray) shape.getGeometry(); + for (int i = 0; i < iga.getIndexCount() - 3; i++) { + iga.getCoordinates(iga.getCoordinateIndex(i), coordinate); + Vector3d p = new Vector3d(coordinate[0], coordinate[1], coordinate[2]); + vertex3DList.add(p); + } + } else if (shape.getGeometry() instanceof GeometryStripArray) { + // GeometryStripArray�̏ꍇ + GeometryStripArray gsa = (GeometryStripArray) shape.getGeometry(); + for (int i = 0; i < gsa.getVertexCount(); i++) { + gsa.getCoordinates(i, coordinate); + Vector3d p = new Vector3d(coordinate[0], coordinate[1], coordinate[2]); + vertex3DList.add(p); + } + } else if (shape.getGeometry() instanceof TriangleArray) { + // TriangleArray�̏ꍇ + TriangleArray tra = (TriangleArray) shape.getGeometry(); + for (int i = 0; i < tra.getVertexCount(); i++) { + tra.getCoordinates(i, coordinate); + Vector3d p = new Vector3d(coordinate[0], coordinate[1], coordinate[2]); + vertex3DList.add(p); + } + } + + if (pattern == 0) { + // �ő�ʐϖ@ + Vector3d cv1 = new Vector3d(); + Vector3d cv2 = new Vector3d(); + + double cvMax = 0.0; + Vector3d axis1 = new Vector3d(); // 3D���_���狁�߂��@���x�N�g�� + Vector3d axis2 = new Vector3d(); // 2D���_���狁�߂��@���x�N�g�� + Vector3d axis3 = new Vector3d(); // axis1,axis2�̊O�ς��狁�߂��@���x�N�g�� + + // �ʐς�3D���_���X�g���狁�߁A�@�������߂鏈�� + for (int i = 0; i < vertex3DList.size(); i += 3) { + cv1.sub(vertex3DList.get(i + 2), vertex3DList.get(i)); + cv2.sub(vertex3DList.get(i + 1), vertex3DList.get(i)); + Vector3d cv = new Vector3d(); + cv.cross(cv1, cv2); + if (i == 0 || cv.length() >= cvMax) { + cvMax = cv.length(); + axis1 = cv; + } + } + + ProjectionResult pr1 = GeometryUtility.projection3D(vertex3DList, axis1); + // �ӂ̂�2D���_���X�g���狁�߁A�@�������߂鏈�� + for (int i = 0; i < pr1.vertexList.size() - 1; i++) { + Vector3d cv = new Vector3d(); + cv.sub(vertex3DList.get(i + 1), vertex3DList.get(i)); + if (i == 0 || cv.length() >= cvMax) { + cvMax = cv.length(); + axis2 = cv; + } + } + + + ProjectionResult pr2 = GeometryUtility.projection2D(pr1.vertexList, axis2); + // axis1,axis2�ŊO�ς�axis3�����߂�B + axis3.cross(axis1, axis2); + + ProjectionResult pr3 = GeometryUtility.projection2D(pr1.vertexList, axis3); + AxisResult ar = new AxisResult(axis1, axis2, axis3); + + // ��������ő�ʐϖ@�ŋ��߂��_���擾���Ă������� + + // OBB�̐��� + obb = new OBB(); + + // No.1 + ar.axis1.scale(pr1.min); + ar.axis2.scale(pr2.min); + ar.axis3.scale(pr3.min); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.2 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.min); + ar.axis2.scale(pr2.max); + ar.axis3.scale(pr3.min); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.3 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.min); + ar.axis2.scale(pr2.min); + ar.axis3.scale(pr3.max); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.4 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.min); + ar.axis2.scale(pr2.max); + ar.axis3.scale(pr3.max); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.5 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.max); + ar.axis2.scale(pr2.min); + ar.axis3.scale(pr3.min); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.6 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.max); + ar.axis2.scale(pr2.max); + ar.axis3.scale(pr3.min); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.7 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.max); + ar.axis2.scale(pr2.min); + ar.axis3.scale(pr3.max); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // No.8 + ar = new AxisResult(axis1, axis2, axis3); + ar.axis1.scale(pr1.max); + ar.axis2.scale(pr2.max); + ar.axis3.scale(pr3.max); + ar.axis1.add(ar.axis2); + ar.axis3.add(ar.axis1); + obb.addVertex(ar.axis3); + + // �ʂ���ы��E���ʑ̂̐��� + obb.createPlanes(); + } else { + // AABB + double minX, maxX, minY, maxY, minZ, maxZ; + minX = maxX = vertex3DList.get(0).x; + minY = maxY = vertex3DList.get(0).y; + minZ = maxZ = vertex3DList.get(0).z; + for (int n = 1; n < vertex3DList.size(); n++) { + Vector3d v = vertex3DList.get(n); + if (minX > v.x) minX = v.x; + if (maxX < v.x) maxX = v.x; + if (minY > v.y) minY = v.y; + if (maxY < v.y) maxY = v.y; + if (minZ > v.z) minZ = v.z; + if (maxZ < v.z) maxZ = v.z; + } + obb = new OBB(new Vector3d(minX, minY, minZ), + new Vector3d(minX, maxY, minZ), + new Vector3d(minX, minY, maxZ), + new Vector3d(minX, maxY, maxZ), + new Vector3d(maxX, minY, minZ), + new Vector3d(maxX, maxY, minZ), + new Vector3d(maxX, minY, maxZ), + new Vector3d(maxX, maxY, maxZ)); + } + } + } + return obb; + } + + private class AxisResult { + Vector3d axis1; + Vector3d axis2; + Vector3d axis3; + + AxisResult(Vector3d a1, Vector3d a2, Vector3d a3) { + axis1 = (Vector3d) a1.clone(); + axis2 = (Vector3d) a2.clone(); + axis3 = (Vector3d) a3.clone(); + } + } + + // Quaternion3D �� applyTo() �ȊO����͌Ă΂Ȃ����� + void setQuaternion(Quaternion3D quaternion) { + this.quaternion = quaternion; + rotate(quaternion.getQuat()); + } + + public Quaternion3D getQuaternion() { + return quaternion; + } + + public boolean isLODSet() { + return bLOD; + } + + public LOD getLOD() { + return lodNode; + } +} diff --git a/src/main/java/framework/model3D/ObjectVisitor.java b/src/main/java/framework/model3D/ObjectVisitor.java new file mode 100644 index 0000000..1e5a5f9 --- /dev/null +++ b/src/main/java/framework/model3D/ObjectVisitor.java @@ -0,0 +1,57 @@ +package framework.model3D; + +import java.util.ArrayList; + +import javax.media.j3d.Transform3D; + +/** + * �I�u�W�F�N�g�̊K�w�\�����g���o�[�X����r�W�^�[ + * @author �V�c���� + * + */ +public abstract class ObjectVisitor { + /** + * ������K��ߓ_�܂ł̃p�X��ɑ��݂���ϊ��s�� + */ + protected ArrayList stackList = new ArrayList(); + + /* + * �ߓ_�i�I�u�W�F�N�g�j��K�₷�钼�O�ɌĂ΂�郁�\�b�h + * @param obj �K��ߓ_ + */ + public abstract void preVisit(Object3D obj); + /** + * �ߓ_�i�I�u�W�F�N�g��K�₵������ɌĂ΂�郁�\�b�h�j + * @param obj �K��ߓ_ + */ + public abstract void postVisit(Object3D obj); + + /** + * 1�K�w�������Ƃ��ɕϊ��s��𑝂₷ + * @param obj�@�V�����K�₵���ߓ_ + */ + protected void pushTransform(Object3D obj) { + Transform3D transPos = new Transform3D(); + obj.pos.getTransform(transPos); + stackList.add(transPos); + Transform3D transRot = new Transform3D(); + obj.rot.getTransform(transRot); + stackList.add(transRot); + Transform3D transScale = new Transform3D(); + obj.scale.getTransform(transScale); + stackList.add(transScale); + Transform3D transCenter = new Transform3D(); + obj.center.getTransform(transCenter); + stackList.add(transCenter); + } + + /** + *�@1�K�w���A�����Ƃ��ɕϊ��s��� ���炷 + */ + protected void popTransform() { + for (int i = 0; i < 4; i++) { + stackList.remove(stackList.size() - 1); + } + } + +} diff --git a/src/main/java/framework/model3D/Placeable.java b/src/main/java/framework/model3D/Placeable.java new file mode 100644 index 0000000..e8ecce0 --- /dev/null +++ b/src/main/java/framework/model3D/Placeable.java @@ -0,0 +1,13 @@ +package framework.model3D; + +import javax.media.j3d.TransformGroup; + +/** + * �z�u�ł�����̑S�� + * @author �V�c���� + * + */ +public interface Placeable { + abstract TransformGroup getTransformGroupToPlace(); + abstract BaseObject3D getBody(); +} diff --git a/src/main/java/framework/model3D/Position3D.java b/src/main/java/framework/model3D/Position3D.java new file mode 100644 index 0000000..064dda8 --- /dev/null +++ b/src/main/java/framework/model3D/Position3D.java @@ -0,0 +1,151 @@ +package framework.model3D; + +import javax.vecmath.Vector3d; + +/** + * ���W�l��\�� + * @author �V�c���� + * + */ +public class Position3D extends Property3D { + private double x; + private double y; + private double z; + + // �R���X�g���N�^ + public Position3D() { + x = 0.0; + y = 0.0; + z = 0.0; + } + + // �R���X�g���N�^ + public Position3D(double px, double py, double pz) { + x = px; + y = py; + z = pz; + } + + public Position3D(Vector3d v) { + x = v.x; + y = v.y; + z = v.z; + } + + // property3D�̒��ۃN���X�𖄂߂� + public void applyTo(Object3D o) { + o.setPosition(this); + } + + // �R�s�[�R���X�g���N�^ + public Position3D(Position3D p) { + this.x = p.x; + this.y = p.y; + this.z = p.z; + } + + public Position3D set(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + // ���Z + public Position3D add(double x, double y, double z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + // ���Z + public Position3D add(Position3D p) { + this.x += p.x; + this.y += p.y; + this.z += p.z; + return this; + } + + // ���Z + public Position3D add(Vector3d v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + } + + // ���Z + public Position3D sub(double x, double y, double z) { + this.x -= x; + this.y -= y; + this.z -= z; + return this; + } + + // ���Z + public Position3D sub(Position3D p) { + this.x -= p.x; + this.y -= p.y; + this.z -= p.z; + return this; + } + + // ���Z + public Position3D sub(Vector3d v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; + } + + // �X�J���[�{ + public Position3D mul(double d) { + this.x *= d; + this.y *= d; + this.z *= d; + return this; + } + + public Position3D setX(double x) { + this.x = x; + return this; + } + + public double getX() { + return x; + } + + public Position3D setY(double y) { + this.y = y; + return this; + } + + public double getY() { + return y; + } + + public Position3D setZ(double z) { + this.z = z; + return this; + } + + public double getZ() { + return z; + } + + public Vector3d getVector3d() { + return new Vector3d(x, y, z); + } + + public Position3D setVector3d(Vector3d v) { + x = v.x; + y = v.y; + z = v.z; + return this; + } + + public Position3D clone() { + return new Position3D(this); + } +} diff --git a/src/main/java/framework/model3D/ProjectionResult.java b/src/main/java/framework/model3D/ProjectionResult.java new file mode 100644 index 0000000..8cfeed1 --- /dev/null +++ b/src/main/java/framework/model3D/ProjectionResult.java @@ -0,0 +1,11 @@ +package framework.model3D; +import java.util.ArrayList; + +import javax.vecmath.Vector3d; + + +public class ProjectionResult { + double max = 0.0; + double min = 0.0; + ArrayList vertexList = new ArrayList(); +} diff --git a/src/main/java/framework/model3D/Property3D.java b/src/main/java/framework/model3D/Property3D.java new file mode 100644 index 0000000..4c82645 --- /dev/null +++ b/src/main/java/framework/model3D/Property3D.java @@ -0,0 +1,8 @@ +package framework.model3D; + + +public abstract class Property3D{ + public abstract void applyTo(Object3D o); + + public abstract Property3D clone(); +} diff --git a/src/main/java/framework/model3D/Quaternion3D.java b/src/main/java/framework/model3D/Quaternion3D.java new file mode 100644 index 0000000..3ba2afa --- /dev/null +++ b/src/main/java/framework/model3D/Quaternion3D.java @@ -0,0 +1,103 @@ +package framework.model3D; + +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Quat4d; + +public class Quaternion3D extends Property3D{ + private Quat4d quaternion; + + //�R���X�g���N�^============================= + public Quaternion3D(){ + AxisAngle4d aa = new AxisAngle4d(0.0, 0.0, 1.0, 0.0); + quaternion = new Quat4d(); + quaternion.set(aa); + } + + public Quaternion3D(AxisAngle4d aa){ + quaternion = new Quat4d(); + quaternion.set(aa); + } + + public Quaternion3D(double x,double y,double z,double w){ + AxisAngle4d aa = new AxisAngle4d(x, y, z, w); + quaternion = new Quat4d(); + quaternion.set(aa); + } + public Quaternion3D(Quaternion3D q){ + this.quaternion = (Quat4d)q.getQuat().clone(); + } + public Quat4d getQuat(){ + return quaternion; + } + + //�Q�b�^================================= + public double getX(){ + return quaternion.x; + } + public double getY(){ + return quaternion.y; + } + public double getZ(){ + return quaternion.z; + } + public double getW(){ + return quaternion.w; + } + public Quaternion3D getInterpolate(Quaternion3D q,double alpha){ + quaternion.interpolate(q.getQuat(), alpha); + return this; + } + + public AxisAngle4d getAxisAngle() { + AxisAngle4d axisAngle = new AxisAngle4d(); + axisAngle.set(quaternion); + return axisAngle; + } + + //�Z�b�^================================= + public Quaternion3D setQuaternion(double x,double y,double z,double w){ + quaternion = new Quat4d(x, y, z, w); + return this; + } + + public Quaternion3D setAxisAngle(double x,double y,double z,double w){ + AxisAngle4d aa = new AxisAngle4d(x, y, z, w); + quaternion = new Quat4d(); + quaternion.set(aa); + return this; + } + + public Quaternion3D add(AxisAngle4d aa){ + Quat4d q = new Quat4d(); + q.set(aa); + q.mul(quaternion); + quaternion = q; + return this; + } + + public Quaternion3D mul(Quaternion3D q){ + quaternion.mul(q.getQuat()); + return this; + } + + @Override + public void applyTo(Object3D o) { + // TODO Auto-generated method stub + o.setQuaternion(this); + } + + @Override + public Property3D clone() { + // TODO Auto-generated method stub + return new Quaternion3D(this); + } + + public double norm() { + return quaternion.w * quaternion.w + quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z * quaternion.z; + } + + public Quaternion3D normalize() { + quaternion.normalize(); + return this; + } +} diff --git a/src/main/java/framework/model3D/ReflectionMapGenerator.java b/src/main/java/framework/model3D/ReflectionMapGenerator.java new file mode 100644 index 0000000..57aa4f9 --- /dev/null +++ b/src/main/java/framework/model3D/ReflectionMapGenerator.java @@ -0,0 +1,15 @@ +package framework.model3D; + +import javax.vecmath.Color4f; + +public class ReflectionMapGenerator extends MapGenerator { + private Color4f blendColor = null; + + public ReflectionMapGenerator(Color4f blendColor) { + this.blendColor = blendColor; + } + + public Color4f getBlendColor() { + return blendColor; + } +} diff --git a/src/main/java/framework/model3D/ShadowVolume.java b/src/main/java/framework/model3D/ShadowVolume.java new file mode 100644 index 0000000..1422677 --- /dev/null +++ b/src/main/java/framework/model3D/ShadowVolume.java @@ -0,0 +1,596 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; + +import javax.media.j3d.Appearance; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Geometry; +import javax.media.j3d.GeometryArray; +import javax.media.j3d.IndexedQuadArray; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.IndexedTriangleFanArray; +import javax.media.j3d.IndexedTriangleStripArray; +import javax.media.j3d.Light; +import javax.media.j3d.Material; +import javax.media.j3d.Node; +import javax.media.j3d.PointLight; +import javax.media.j3d.PolygonAttributes; +import javax.media.j3d.RenderingAttributes; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransparencyAttributes; +import javax.media.j3d.TriangleFanArray; +import javax.media.j3d.TriangleStripArray; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.Cone; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Sphere; + +/** + * �X�e���V���o�b�t�@��p�����V���h�E�{�����[�� + * @author �V�c���� + * + */ +public class ShadowVolume { + private static final boolean WIRE_FRAME_VIEW = false; + + private Light light = null; + private double shadowDepth = 10.0; + + private IndexedQuadArray volumeGeometry = null; + private Shape3D shadowVolumeFront = null; + private Shape3D shadowVolumeBack = null; + + private int vertexCount = 0; + private double coordinates[] = null; + private int indicies[] = null; + private Hashtable edges = null; + private ArrayList triangles = null; + + /** + * ���s�����p�̃V���h�E�{�����[�� + * @param occuluder �Օ��I�u�W�F�N�g�i�e�𗎂Ƃ��I�u�W�F�N�g�j + * @param light ���� + * @param shadowDepth �e�̐[�� + * @param localToWorld �Օ��I�u�W�F�N�g�p�̍��W�ϊ� + */ + public ShadowVolume(BaseObject3D occuluder, Light light, double shadowDepth, + Transform3D localToWorld) { + this.light = light; + this.shadowDepth = shadowDepth; + + // �􉽏��̒��o + if (!extractGeometricInformation(occuluder)) return; + + // �V���h�E�{�����[���̕\�ʂ𐶐� + volumeGeometry = createVolumeSurface(light, shadowDepth, localToWorld, coordinates, edges, triangles); + + // �V���h�E�{�����[���I�u�W�F�N�g�̐��� + createShadowVolumeObject(volumeGeometry, occuluder); + } + + /** + * �V���h�E�{�����[���̍X�V + * @param localToWorld �Օ��I�u�W�F�N�g�p�̍��W�ϊ� + */ + public void update(Transform3D localToWorld) { + // �V���h�E�{�����[���̕\�ʂ��Đ��� + volumeGeometry = createVolumeSurface(light, shadowDepth, localToWorld, coordinates, edges, triangles); + + // �V���h�E�{�����[���I�u�W�F�N�g�̍X�V + shadowVolumeFront.removeAllGeometries(); + shadowVolumeFront.addGeometry(volumeGeometry); + shadowVolumeBack.removeAllGeometries(); + shadowVolumeBack.addGeometry(volumeGeometry); + } + + /** + * �􉽏��̒��o + * @param shadowCastingObject ���o���̃I�u�W�F�N�g + * @return true --- ����ɒ��o�ł���, false --- ����ɒ��o�ł��Ȃ����� + */ + private boolean extractGeometricInformation(BaseObject3D shadowCastingObject) { + Node node = shadowCastingObject.getPrimitiveNode(); + if (node == null) return false; + // GeometryArray�̏K�� + ArrayList geometries = new ArrayList(); + Geometry g = null; + if (node instanceof Shape3D) { + g = ((Shape3D)node).getGeometry(); + geometries.add(g); + } else if (node instanceof Cone) { + g = ((Cone)node).getShape(Cone.BODY).getGeometry(); + geometries.add(g); + g = ((Cone)node).getShape(Cone.CAP).getGeometry(); + geometries.add(g); + } else if (node instanceof Cylinder) { + g = ((Cylinder)node).getShape(Cylinder.BODY).getGeometry(); + geometries.add(g); + g = ((Cylinder)node).getShape(Cylinder.TOP).getGeometry(); + geometries.add(g); + g = ((Cylinder)node).getShape(Cylinder.BOTTOM).getGeometry(); + geometries.add(g); + } else if (node instanceof Box) { + g = ((Box)node).getShape(Box.TOP).getGeometry(); + geometries.add(g); + g = ((Box)node).getShape(Box.BOTTOM).getGeometry(); + geometries.add(g); + g = ((Box)node).getShape(Box.FRONT).getGeometry(); + geometries.add(g); + g = ((Box)node).getShape(Box.BACK).getGeometry(); + geometries.add(g); + g = ((Box)node).getShape(Box.LEFT).getGeometry(); + geometries.add(g); + g = ((Box)node).getShape(Box.RIGHT).getGeometry(); + geometries.add(g); + } else if (node instanceof Sphere) { + g = ((Sphere)node).getShape().getGeometry(); + geometries.add(g); + } else { + return false; + } + + // ���_�̍��W�l���擾���A�ݒ� + vertexCount = 0; + for (int n = 0; n < geometries.size(); n++) { + g = geometries.get(n); + if (g instanceof GeometryArray) { + // GeometryArray �̏ꍇ + GeometryArray geometryArray = (GeometryArray)g; + vertexCount += geometryArray.getVertexCount(); + } + } + coordinates = new double[vertexCount * 3 * 2]; + indicies = new int[vertexCount * 4 * 3]; // �ӂ̐��𒸓_�̐��̍ő�3�{�ƍl���Ă��� + int base = 0; + for (int n = 0; n < geometries.size(); n++) { + g = geometries.get(n); + if (g instanceof GeometryArray) { + // GeometryArray �̏ꍇ + GeometryArray geometryArray = (GeometryArray)g; + double coordinate[] = new double[3]; + int count = geometryArray.getVertexCount(); + for (int v = 0; v < count; v++) { + geometryArray.getCoordinate(v, coordinate); + coordinates[(v + base) * 3] = coordinate[0]; + coordinates[(v + base) * 3 + 1] = coordinate[1]; + coordinates[(v + base) * 3 + 2] = coordinate[2]; + } + base += count; + } + } + + // �ʂƕӂ̏����쐬 + edges = new Hashtable(); + triangles = new ArrayList(); + base = 0; + for (int n = 0; n < geometries.size(); n++) { + g = geometries.get(n); + if (g instanceof GeometryArray) { + // GeometryArray �̏ꍇ + GeometryArray geometryArray = (GeometryArray)g; + Point3d p1 = new Point3d(); + Point3d p2 = new Point3d(); + Point3d p3 = new Point3d(); + int v1, v2, v3; + if (g instanceof TriangleStripArray) { + // TriangleStripArray �̏ꍇ + TriangleStripArray triStripArray = (TriangleStripArray)g; + int num = triStripArray.getNumStrips(); + int strips[] = new int[num]; + triStripArray.getStripVertexCounts(strips); + int index = base; + for (int j = 0; j < num; j++) { + index += 2; + for (int i = 2; i < strips[j]; i += 2) { + addTriangle(index - 2, index - 1, index, p1, p2, p3); + if (i <= strips[j] - 2) { + addTriangle(index - 1, index + 1, index, p1, p2, p3); + index += 1; + } + index += 1; + } + } + } else if (g instanceof TriangleFanArray) { + // TriangleFanArray �̏ꍇ + TriangleFanArray triFanArray = (TriangleFanArray)g; + int num = triFanArray.getNumStrips(); + int strips[] = new int[num]; + triFanArray.getStripVertexCounts(strips); + int index = base; + for (int j = 0; j < num; j++) { + v1 = index; + index += 1; + for (int i = 1; i < strips[j] - 1; i += 1) { + addTriangle(v1, index, index + 1, p1, p2, p3); + index += 1; + } + } + } else if (g instanceof IndexedTriangleArray) { + // IndexedTriangleArray �̏ꍇ + IndexedTriangleArray triArray = (IndexedTriangleArray)g; + int indexCount = triArray.getIndexCount(); + for (int i = 0; i < indexCount; i += 3) { + v1 = triArray.getCoordinateIndex(i) + base; + v2 = triArray.getCoordinateIndex(i + 1) + base; + v3 = triArray.getCoordinateIndex(i + 2) + base; + addTriangle(v1, v2, v3, p1, p2, p3); + } + } else if (g instanceof IndexedTriangleStripArray) { + // IndexedTriangleStripArray �̏ꍇ + IndexedTriangleStripArray triStripArray = (IndexedTriangleStripArray)g; + int num = triStripArray.getNumStrips(); + int strips[] = new int[num]; + triStripArray.getStripIndexCounts(strips); + int index = 0; + for (int j = 0; j < num; j++) { + index += 2; + for (int i = 2; i < strips[j]; i += 2) { + v1 = triStripArray.getCoordinateIndex(index - 2) + base; + v2 = triStripArray.getCoordinateIndex(index - 1) + base; + v3 = triStripArray.getCoordinateIndex(index) + base; + addTriangle(v1,v2, v3, p1, p2, p3); + if (i <= strips[j] - 2) { + v1 = v2; + v2 = triStripArray.getCoordinateIndex(index + 1) + base; + addTriangle(v1, v2, v3, p1, p2, p3); + index += 1; + } + index += 1; + } + } + } else if (g instanceof IndexedTriangleFanArray) { + // IndexedTriangleFanArray �̏ꍇ + IndexedTriangleFanArray triFanArray = (IndexedTriangleFanArray)g; + int num = triFanArray.getNumStrips(); + int strips[] = new int[num]; + triFanArray.getStripIndexCounts(strips); + int index = 0; + for (int j = 0; j < num; j++) { + v1 = triFanArray.getCoordinateIndex(index) + base; + index += 1; + for (int i = 1; i < strips[j] - 1; i += 1) { + v2 = triFanArray.getCoordinateIndex(index) + base; + v3 = triFanArray.getCoordinateIndex(index + 1) + base; + addTriangle(v1, v2, v3, p1, p2, p3); + index += 1; + } + } + } + base += geometryArray.getVertexCount(); + } + } + return true; + } + + private void addTriangle(int v1, int v2, int v3, Point3d p1, Point3d p2, Point3d p3) { + Vector3d vec1; + Vector3d vec2; + Vector3d vec; + Triangle tri; + Edge e; + p1.x = coordinates[v1 * 3]; + p1.y = coordinates[v1 * 3 + 1]; + p1.z = coordinates[v1 * 3 + 2]; + p2.x = coordinates[v2 * 3]; + p2.y = coordinates[v2 * 3 + 1]; + p2.z = coordinates[v2 * 3 + 2]; + p3.x = coordinates[v3 * 3]; + p3.y = coordinates[v3 * 3 + 1]; + p3.z = coordinates[v3 * 3 + 2]; + vec = new Vector3d(p1); + vec1 = new Vector3d(p2); + vec2 = new Vector3d(p3); + vec1.sub(vec); + vec2.sub(vec); + vec1.cross(vec1, vec2); + if (vec1.length() < GeometryUtility.TOLERANCE) { + return; + } + vec1.normalize(); + tri = new Triangle(v1, v2, v3, vec1); + triangles.add(tri); + e = edges.get(new Integer(v2 * vertexCount + v1)); // �t�����ɉ���Ă���ӂ̂݋��L + if (e != null) { + tri.edges[0] = e; + e.triangles[1] = tri; + } else { + vec = new Vector3d(p2); + vec.sub(p1); + e = new Edge(v1, v2, vec); + tri.edges[0] = e; + e.triangles[0] = tri; + edges.put(new Integer(v1 * vertexCount + v2), e); + } + e = edges.get(new Integer(v3 * vertexCount + v2)); // �t�����ɉ���Ă���ӂ̂݋��L + if (e != null) { + tri.edges[1] = e; + e.triangles[1] = tri; + } else { + vec = new Vector3d(p3); + vec.sub(p2); + e = new Edge(v2, v3, vec); + tri.edges[1] = e; + e.triangles[0] = tri; + edges.put(new Integer(v2 * vertexCount + v3), e); + } + e = edges.get(new Integer(v1 * vertexCount + v3)); // �t�����ɉ���Ă���ӂ̂݋��L + if (e != null) { + tri.edges[2] = e; + e.triangles[1] = tri; + } else { + vec = new Vector3d(p1); + vec.sub(p3); + e = new Edge(v3, v1, vec); + tri.edges[2] = e; + e.triangles[0] = tri; + edges.put(new Integer(v3 * vertexCount + v1), e); + } + } + + /** + * �V���h�E�{�����[���̃W�I���g���̍쐬 + * @param light + * @param shadowDepth + * @param localToWorld + * @param coordinates + * @param edges + * @param triangles + * @return �V���h�E�{�����[���̃W�I���g�� + */ + private IndexedQuadArray createVolumeSurface(Light light, double shadowDepth, Transform3D localToWorld, + double[] coordinates, Hashtable edges, ArrayList triangles) { + // �I�u�W�F�N�g�ɑ΂��鑊�΍��W�n�ɕϊ� + Vector3d displacement = null; + Point3d localLightPosition = null; + Transform3D worldToLocal; + Point3d worldLightPosition = null; + if (light instanceof DirectionalLight) { + // ���s�����̏ꍇ + Vector3f lightDirectionF = new Vector3f(); + ((DirectionalLight)light).getDirection(lightDirectionF); + displacement = new Vector3d(lightDirectionF); + displacement.scale(shadowDepth); + worldToLocal = new Transform3D(localToWorld); + worldToLocal.invert(); + worldToLocal.transform(displacement); + } else if (light instanceof PointLight) { + // �_�����̏ꍇ + Point3f worldLightPositionF = new Point3f(); + ((PointLight)light).getPosition(worldLightPositionF); + worldLightPosition = new Point3d(worldLightPositionF); + localLightPosition = new Point3d(worldLightPosition); + worldToLocal = new Transform3D(localToWorld); + worldToLocal.invert(); + worldToLocal.transform(localLightPosition); + } else { + return null; + } + + Triangle tri; + // ���ׂĂ̖ʂ̌����ɑ΂���������v�Z + if (displacement != null) { + for (int n = 0; n < triangles.size(); n++) { + tri = triangles.get(n); + tri.innerProduct = tri.normal.dot(displacement); + } + } else if (localLightPosition != null) { + for (int n = 0; n < triangles.size(); n++) { + tri = triangles.get(n); + Vector3d v = new Vector3d(coordinates[tri.v1*3], coordinates[tri.v1*3 + 1], coordinates[tri.v1*3 + 2]); + v.sub(localLightPosition); + tri.innerProduct = tri.normal.dot(v); + } + } + Collection es = edges.values(); + Edge edge; + int index = 0; + boolean doesGenerateSurface = false; + double i0 = 0, i1 = 0; + Vector3d displacement1 = displacement; + Vector3d displacement2 = displacement; + Vector3d tempVec = new Vector3d(); + Point3d worldPos = new Point3d(); + if (localLightPosition != null) { + // �_�����̏ꍇ + displacement1 = new Vector3d(); + displacement2 = new Vector3d(); + } + for (Iterator it = es.iterator(); it.hasNext(); ) { + edge = it.next(); + // edge�ɑ΂��ăV���h�E�{�����[���̕\�ʂ𐶐����邩�ۂ��̔��� + doesGenerateSurface = false; + if (edge.triangles[1] == null) { + // �J���ʑ̂̏ꍇ + i0 = edge.triangles[0].innerProduct; + if (i0 < -GeometryUtility.TOLERANCE) { + // �����ɑ΂��ĕ\�����̖ʂ̕ӂɑ΂��Ă̂ݐ��� + doesGenerateSurface = true; // �������� + } + } else { + i0 = edge.triangles[0].innerProduct; + i1 = edge.triangles[1].innerProduct; + if (i0 * i1 < GeometryUtility.TOLERANCE) { + if (i0 * i1 > -GeometryUtility.TOLERANCE) { + // �ӂ����ނQ�‚̖ʂ̈���������̌����ɑ΂��ĕ��s�ł��� + if (i0 < -GeometryUtility.TOLERANCE || i1 < -GeometryUtility.TOLERANCE) { + // �����ꂩ�̖ʂ��\�����������ꍇ + tempVec.cross(edge.triangles[0].normal, edge.triangles[1].normal); + if (edge.v1ToV2.dot(tempVec) > GeometryUtility.TOLERANCE) { + // �ӂ��ʂ̏ꍇ�̂ݐ��� + doesGenerateSurface = true; // �������� + } + } + } else { + // �ӂ����ނQ�‚̖ʂ������̌����ɑ΂��ė��\�ł��� + doesGenerateSurface = true; // �������� + } + } + } + if (doesGenerateSurface) { + // �V���h�E�{�����[���̕\�ʂ𐶐����� + if (localLightPosition != null) { + // �_�����̏ꍇ + displacement1.x = coordinates[edge.v1 * 3] - localLightPosition.x; + displacement1.y = coordinates[edge.v1 * 3 + 1] - localLightPosition.y; + displacement1.z = coordinates[edge.v1 * 3 + 2] - localLightPosition.z; + worldPos.x = coordinates[edge.v1 * 3]; + worldPos.y = coordinates[edge.v1 * 3 + 1]; + worldPos.z = coordinates[edge.v1 * 3 + 2]; + localToWorld.transform(worldPos); + displacement1.scale(shadowDepth / worldPos.distance(worldLightPosition)); + displacement2.x = coordinates[edge.v2 * 3] - localLightPosition.x; + displacement2.y = coordinates[edge.v2 * 3 + 1] - localLightPosition.y; + displacement2.z = coordinates[edge.v2 * 3 + 2] - localLightPosition.z; + worldPos.x = coordinates[edge.v2 * 3]; + worldPos.y = coordinates[edge.v2 * 3 + 1]; + worldPos.z = coordinates[edge.v2 * 3 + 2]; + localToWorld.transform(worldPos); + displacement2.scale(shadowDepth / worldPos.distance(worldLightPosition)); + } + if (i0 < -GeometryUtility.TOLERANCE) { + // �\�������Ă���ʂ�edge.triangles[0]�Aedge�̌����͏��edge.triangles[0]�̕ӂ̌����ƈ�v����̂ŁA + // edge�̌����ɏ]���ăV���h�E�{�����[���̕\�ʂ𐶐� + indicies[index] = edge.v2; + indicies[index + 1] = edge.v1; + indicies[index + 2] = edge.v1 + vertexCount; + indicies[index + 3] = edge.v2 + vertexCount; + } else { + // �\�������Ă���ʂ�edge.triangles[1]�Aedge�̌����͏��edge.triangles[1]�̕ӂ̌����Ɣ��΂Ȃ̂ŁA + // edge�̌����Ƌt�����ɃV���h�E�{�����[���̕\�ʂ𐶐� + indicies[index] = edge.v1; + indicies[index + 1] = edge.v2; + indicies[index + 2] = edge.v2 + vertexCount; + indicies[index + 3] = edge.v1 + vertexCount; + } + coordinates[(edge.v1 + vertexCount) * 3] = coordinates[edge.v1 * 3] + displacement1.x; + coordinates[(edge.v1 + vertexCount) * 3 + 1] = coordinates[edge.v1 * 3 + 1] + displacement1.y; + coordinates[(edge.v1 + vertexCount) * 3 + 2] = coordinates[edge.v1 * 3 + 2] + displacement1.z; + coordinates[(edge.v2 + vertexCount) * 3] = coordinates[edge.v2 * 3] + displacement2.x; + coordinates[(edge.v2 + vertexCount) * 3 + 1] = coordinates[edge.v2 * 3 + 1] + displacement2.y; + coordinates[(edge.v2 + vertexCount) * 3 + 2] = coordinates[edge.v2 * 3 + 2] + displacement2.z; + index += 4; + } + } + if (index == 0) return null; + int validIndicies[] = new int[index]; + System.arraycopy(indicies, 0, validIndicies, 0, index); + volumeGeometry = new IndexedQuadArray(coordinates.length / 3, + IndexedQuadArray.COORDINATES | IndexedQuadArray.BY_REFERENCE, + index); + volumeGeometry.setCapability(IndexedQuadArray.ALLOW_COORDINATE_READ); + volumeGeometry.setCapability(IndexedQuadArray.ALLOW_COORDINATE_WRITE); + volumeGeometry.setCapability(IndexedQuadArray.ALLOW_COORDINATE_INDEX_READ); + volumeGeometry.setCapability(IndexedQuadArray.ALLOW_COORDINATE_INDEX_WRITE); + + volumeGeometry.setCoordRefDouble(coordinates); + volumeGeometry.setCoordinateIndices(0, validIndicies); + return volumeGeometry; + } + + /** + * �V���h�E�{�����[���̐��� + * @param volumeGeometry + * @param ������������������ + */ + private void createShadowVolumeObject(IndexedQuadArray volumeGeometry, BaseObject3D ������������������) { + // �V���h�E�{�����[���̕\�ʂ̃I�u�W�F�N�g�̐��� + Appearance frontAp = new Appearance(); + if (WIRE_FRAME_VIEW) frontAp.setMaterial(new Material()); + RenderingAttributes frontRA = new RenderingAttributes(); + if (!WIRE_FRAME_VIEW) frontRA.setStencilEnable(true); // �X�e���V���o�b�t�@��p����i�������ACanvas3D�œK�؂Ȑݒ肪����Ă���K�v������j + if (!WIRE_FRAME_VIEW) frontRA.setDepthBufferWriteEnable(false); // Z�o�b�t�@���X�V���Ȃ� + frontRA.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); // Z�o�b�t�@�̉e�����󂯂� + frontRA.setStencilFunction(RenderingAttributes.ALWAYS, 0, ~0); // �X�e���V���o�b�t�@�̉e�����󂯂Ȃ� + frontRA.setStencilOp(RenderingAttributes.STENCIL_KEEP, + RenderingAttributes.STENCIL_KEEP, + RenderingAttributes.STENCIL_INCR); // �����Ă���s�N�Z���̂݃X�e���V���o�b�t�@�̒l�𑝂₷ + frontAp.setRenderingAttributes(frontRA); + PolygonAttributes pa1 = new PolygonAttributes(); + if (WIRE_FRAME_VIEW) pa1.setPolygonMode(PolygonAttributes.POLYGON_LINE); + pa1.setCullFace(PolygonAttributes.CULL_BACK); // ���ʂ��������Ȃ� + frontAp.setPolygonAttributes(pa1); + if (!WIRE_FRAME_VIEW) { + TransparencyAttributes frontTA = new TransparencyAttributes(); // setVisible(false)���ƃX�e���V���o�b�t�@���X�V����Ȃ��̂ŁA�����ɂ��� + frontTA.setTransparencyMode(TransparencyAttributes.BLENDED); + frontTA.setTransparency(1.0f); + frontAp.setTransparencyAttributes(frontTA); + } + shadowVolumeFront = new Shape3D(volumeGeometry, frontAp); + shadowVolumeFront.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shadowVolumeFront.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + ������������������.center.addChild(shadowVolumeFront); + + // �V���h�E�{�����[���̗��ʂ̃I�u�W�F�N�g�̐��� + Appearance backAp= new Appearance(); + if (WIRE_FRAME_VIEW) backAp.setMaterial(new Material()); + RenderingAttributes backRA= new RenderingAttributes(); + if (!WIRE_FRAME_VIEW) backRA.setStencilEnable(true); // �X�e���V���o�b�t�@��p����i�������ACanvas3D�œK�؂Ȑݒ肪����Ă���K�v������j + if (!WIRE_FRAME_VIEW) backRA.setDepthBufferWriteEnable(false); // Z�o�b�t�@���X�V���Ȃ� + backRA.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); // Z�o�b�t�@�̉e�����󂯂� + backRA.setStencilFunction(RenderingAttributes.ALWAYS, 0, ~0); // �X�e���V���o�b�t�@�̉e�����󂯂Ȃ� + backRA.setStencilOp(RenderingAttributes.STENCIL_KEEP, + RenderingAttributes.STENCIL_KEEP, + RenderingAttributes.STENCIL_DECR); // �����Ă���s�N�Z���̂݃X�e���V���o�b�t�@�̒l�����炷 + backAp.setRenderingAttributes(backRA); + PolygonAttributes pa2 = new PolygonAttributes(); + if (WIRE_FRAME_VIEW) pa2.setPolygonMode(PolygonAttributes.POLYGON_LINE); + pa2.setCullFace(PolygonAttributes.CULL_FRONT); // �\�ʂ��������Ȃ� + backAp.setPolygonAttributes(pa2); + if (!WIRE_FRAME_VIEW) { + TransparencyAttributes backTA = new TransparencyAttributes(); // setVisible(false)���ƃX�e���V���o�b�t�@���X�V����Ȃ��̂ŁA�����ɂ��� + backTA.setTransparencyMode(TransparencyAttributes.BLENDED); + backTA.setTransparency(1.0f); + backAp.setTransparencyAttributes(backTA); + } + shadowVolumeBack = new Shape3D(volumeGeometry, backAp); + shadowVolumeBack.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shadowVolumeBack.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + ������������������.center.addChild(shadowVolumeBack); + } + + private class Triangle { + Edge edges[] = new Edge[3]; + Vector3d normal; + double innerProduct; + int v1, v2, v3; + + Triangle(int v1, int v2, int v3, Vector3d normal) { + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + this.normal = normal; + } + } + + private class Edge { + Triangle triangles[] = new Triangle[2]; + int v1, v2; + Vector3d v1ToV2; +// Vector3d normal = null; + + Edge(int v1, int v2, Vector3d v1ToV2) { + this.v1 = v1; + this.v2 = v2; + this.v1ToV2 = v1ToV2; + } + +// Vector3d normal() { +// if (normal != null) return normal; +// normal = new Vector3d(triangles[0].normal); +// if (triangles[1] != null) { +// normal.add(triangles[1].normal); +// normal.scale(0.5); +// } +// return normal; +// } + } +} diff --git a/src/main/java/framework/model3D/ShadowVolumeVisitor.java b/src/main/java/framework/model3D/ShadowVolumeVisitor.java new file mode 100644 index 0000000..b50ed96 --- /dev/null +++ b/src/main/java/framework/model3D/ShadowVolumeVisitor.java @@ -0,0 +1,70 @@ +package framework.model3D; + +import java.util.ArrayList; + +import javax.media.j3d.Light; +import javax.media.j3d.Transform3D; +import javax.vecmath.Vector3d; + +/** + * �V���h�E�{�����[���p�̃r�W�^�[ + * @author Nitta + * + */ +public class ShadowVolumeVisitor extends ObjectVisitor { + private boolean bInitialize = true; + private ArrayList lights = null; + private double shadowDepth = 0; + + /** + * �V���h�E�{�����[�����X�V����ꍇ + */ + public ShadowVolumeVisitor() { + this.bInitialize = false; + Transform3D t = new Transform3D(); + stackList.add(t); + } + + /** + * �V���h�E�{�����[�����쐬����ꍇ + * @param lights ���� + * @param shadowDepth �e�̐[�� + */ + public ShadowVolumeVisitor(ArrayList lights, double shadowDepth) { + this.lights = lights; + this.shadowDepth = shadowDepth; + this.bInitialize = true; + Transform3D t = new Transform3D(); + stackList.add(t); + } + + @Override + public void preVisit(Object3D obj) { + Transform3D t = new Transform3D(stackList.get(stackList.size() - 1)); + Transform3D t2 = new Transform3D(); + obj.pos.getTransform(t2); + t.mul(t2); + obj.rot.getTransform(t2); + t.mul(t2); + obj.scale.getTransform(t2); + t.mul(t2); + obj.center.getTransform(t2); + t.mul(t2); + stackList.add(t); + } + + @Override + public void postVisit(Object3D obj) { + Transform3D t = stackList.remove(stackList.size() - 1); + if (!obj.hasChildren()) { + // �t�I�u�W�F�N�g�̏ꍇ�A�V���h�E�{�����[���̏��������� + if (bInitialize) { + // �������̏ꍇ�A�V���h�E�{�����[���̐��� + obj.createShadowVolume(lights, shadowDepth, t); + } else { + // �������łȂ��ꍇ�A�V���h�E�{�����[���̍X�V + obj.updateShadowVolume(t); + } + } + } +} diff --git a/src/main/java/framework/model3D/Terrain3D.java b/src/main/java/framework/model3D/Terrain3D.java new file mode 100644 index 0000000..695bac1 --- /dev/null +++ b/src/main/java/framework/model3D/Terrain3D.java @@ -0,0 +1,466 @@ +package framework.model3D; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingBox; +import javax.media.j3d.Shape3D; +import javax.media.j3d.IndexedTriangleStripArray; +import javax.media.j3d.TriangleStripArray; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +/** + * ���b�V���ō\�����ꂽ�n�`�p�̃I�u�W�F�N�g�i�Փ˔��肪����������Ă���j + * @author �V�c���� + * + */ +public class Terrain3D extends BaseObject3D { + static final int MESH_SIZE = 4; + private Position3D origin; + private double sizeX = 0; + private double sizeZ = 0; + private double heightMap[][] = null; + private int meshX = 0; + private int meshZ = 0; + private TriangleStripArray triStripAttay = null; + + public Terrain3D(Position3D origin, double sizeX, double sizeZ, double heightMap[][], Appearance a) { + super(); + this.origin = origin; + this.sizeX = sizeX; + this.sizeZ = sizeZ; + this.heightMap = heightMap; + meshX = heightMap[0].length; + meshZ = heightMap.length; + + int stripVertexCounts[] = new int[meshZ - 1]; + for (int n = 0; n < meshZ - 1; n++) { + stripVertexCounts[n] = meshX * 2; + } + triStripAttay = new TriangleStripArray(meshX * 2 * (meshZ - 1), + TriangleStripArray.COORDINATES | TriangleStripArray.NORMALS, + stripVertexCounts); + int index = 0; + for (int z = 0; z < meshZ; z++) { + for (int x = 0; x < meshX; x++) { + // ���b�V�����ƂɎO�p�`��2�‚��� + if (z < meshZ - 1) { + // ���_���W�̐ݒ� + // ���_�̖@���x�N�g���̐ݒ� + triStripAttay.setCoordinate(index, + new Point3d(origin.getX() + sizeX * (double)x, + origin.getY() + heightMap[z][x], + origin.getZ() + sizeZ * (double)z)); + Vector3f normal = calcNormal(z, x); + normal.normalize(); + triStripAttay.setNormal(index, normal); + + triStripAttay.setCoordinate(index + 1, + new Point3d(origin.getX() + sizeX * (double)x, + origin.getY() + heightMap[z + 1][x], + origin.getZ() + sizeZ * (double)(z + 1))); + normal = calcNormal(z + 1, x); + normal.normalize(); + triStripAttay.setNormal(index + 1, normal); + + index += 2; + } + } + } + Appearance a2 = (Appearance)a.cloneNodeComponent(true); + a2.setCapability(Appearance.ALLOW_MATERIAL_READ); + a2.setCapability(Appearance.ALLOW_TEXTURE_READ); + a2.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); + a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); + Shape3D shape = new Shape3D(triStripAttay, a2); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + center.addChild(shape); + } + + private Vector3f calcNormal(int z, int x) { + Vector3f normal = new Vector3f(); + if (x < meshX - 1) { + Vector3f xp = new Vector3f((float)sizeX, (float)(heightMap[z][x+1] - heightMap[z][x]), 0.0f); + if (z < meshZ - 1) { + Vector3f zp = new Vector3f(0.0f, (float)(heightMap[z+1][x] - heightMap[z][x]), (float)sizeZ); + Vector3f v1 = new Vector3f(); + v1.cross(zp, xp); + v1.normalize(); + normal.add(v1); + } + if (z > 0) { + Vector3f zm = new Vector3f(0.0f, (float)(heightMap[z-1][x] - heightMap[z][x]), -(float)sizeZ); + Vector3f v1 = new Vector3f(); + v1.cross(xp, zm); + v1.normalize(); + normal.add(v1); + } + } + if (x > 0) { + Vector3f xm = new Vector3f(-(float)sizeX, (float)(heightMap[z][x-1] - heightMap[z][x]), 0.0f); + if (z < meshZ - 1) { + Vector3f zp = new Vector3f(0.0f, (float)(heightMap[z+1][x] - heightMap[z][x]), (float)sizeZ); + Vector3f v1 = new Vector3f(); + v1.cross(xm, zp); + v1.normalize(); + normal.add(v1); + } + if (z > 0) { + Vector3f zm = new Vector3f(0.0f, (float)(heightMap[z-1][x] - heightMap[z][x]), -(float)sizeZ); + Vector3f v1 = new Vector3f(); + v1.cross(zm, xm); + v1.normalize(); + normal.add(v1); + } + } + return normal; + } + + /** + * �Փ˔���p�̃{�����[���i�|���S���Ƒe������p�̒����́j���擾���� + * @return�@�Փ˔���p�̃{�����[���� + */ + public BoundingSurface[] getBoundingSurfaces() { + if (boundingSurfaces == null) { + if (triStripAttay == null) return null; + double coordinate1[] = new double[3]; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = new double[3]; + + // GeometryArray�̏K�� + if (triStripAttay instanceof TriangleStripArray) { + // IndexedTriangleStripArray �̏ꍇ + // 8 x 8 ���b�V���P�ʂł܂Ƃ߂� + BoundingSurface surfaces[] = new BoundingSurface[((meshX + MESH_SIZE - 2) / MESH_SIZE) * ((meshZ + MESH_SIZE - 2) / MESH_SIZE)]; + int n = 0; + for (int j = 0; j < meshZ - 1; j += MESH_SIZE) { + for (int i = 0; i < meshX - 1; i += MESH_SIZE) { + BoundingSurface parent = new BoundingSurface(); + double lowY = 1.0; + double highY = -1.0; + for (int j2 = 0; j + j2 < meshZ - 1 && j2 < MESH_SIZE; j2++) { + for (int i2 = 0; i + i2 < meshX - 1 && i2 < MESH_SIZE; i2++) { + int index = (j + j2) * meshX * 2 + (i + i2) * 2; + triStripAttay.getCoordinates(index, coordinate1); + triStripAttay.getCoordinates(index + 1, coordinate2); + triStripAttay.getCoordinates(index + 2, coordinate3); + triStripAttay.getCoordinates(index + 3, coordinate4); + if (lowY > highY) { + lowY = highY = coordinate1[1]; + } else { + if (lowY > coordinate1[1]) { + lowY = coordinate1[1]; + } else if (highY < coordinate1[1]) { + highY = coordinate1[1]; + } + if (lowY > coordinate2[1]) { + lowY = coordinate2[1]; + } else if (highY < coordinate2[1]) { + highY = coordinate2[1]; + } + if (lowY > coordinate3[1]) { + lowY = coordinate3[1]; + } else if (highY < coordinate3[1]) { + highY = coordinate3[1]; + } + if (lowY > coordinate4[1]) { + lowY = coordinate4[1]; + } else if (highY < coordinate4[1]) { + highY = coordinate4[1]; + } + } + + // 1 x 1 ���b�V������BoundingSurface + Vector3d v1 = new Vector3d(coordinate1); + Vector3d v2 = new Vector3d(coordinate2); + Vector3d v3 = new Vector3d(coordinate3); + Vector3d v4 = new Vector3d(coordinate4); + BoundingSurface bSurface = new BoundingSurface(); + bSurface.addVertex((Vector3d)v1.clone()); //1�‚߂̎O�p�` + bSurface.addVertex((Vector3d)v2.clone()); + bSurface.addVertex((Vector3d)v3.clone()); + bSurface.setBounds(createBoundingPolytope(v1, v2, v3)); + parent.addChild(bSurface, false); + + bSurface = new BoundingSurface(); + bSurface.addVertex((Vector3d)v2.clone()); //2�‚߂̎O�p�` + bSurface.addVertex((Vector3d)v4.clone()); + bSurface.addVertex((Vector3d)v3.clone()); + bSurface.setBounds(createBoundingPolytope(v2, v4, v3)); + parent.addChild(bSurface, true); + } + } + // 8 x 8 ���b�V���P�ʂ�BoundingSurface + triStripAttay.getCoordinates(j * meshX * 2 + i * 2, coordinate1); + parent.setBounds(new BoundingBox(new Point3d(coordinate1[0], lowY, coordinate1[2]), + new Point3d(coordinate4[0], highY, coordinate4[2]))); + surfaces[n] = parent; + n++; + } + } + boundingSurfaces = surfaces; + } else { + return null; + } + } + return boundingSurfaces; + } + + public double getHeight(double x, double z) { + int i = (int)((x - origin.getX()) / sizeX); + int j = (int)((z - origin.getZ()) / sizeZ); + if (i >= meshX || i < 0 || j >= meshZ || j < 0) return 0.0; + + int index = j * meshX * 2 + i * 2; + double coordinate1[] = new double[3]; + double coordinate2[] = new double[3]; + double coordinate3[] = new double[3]; + double coordinate4[] = new double[3]; + triStripAttay.getCoordinates(index, coordinate1); + triStripAttay.getCoordinates(index + 1, coordinate2); + triStripAttay.getCoordinates(index + 2, coordinate3); + triStripAttay.getCoordinates(index + 3, coordinate4); + Vector3d v1 = new Vector3d(coordinate1); + Vector3d v2 = new Vector3d(coordinate2); + Vector3d v3 = new Vector3d(coordinate3); + Vector3d v4 = new Vector3d(coordinate4); + Vector3d p1 = new Vector3d(x, 0.0, z); + Vector3d p2 = new Vector3d(x, 1.0, z); + + double x2 = x - (double)i * sizeX - origin.getX(); + double z2 = z - (double)j * sizeZ - origin.getZ(); + if (x2 < GeometryUtility.TOLERANCE || (meshZ - z2) / x2 > meshZ / meshX) { + // 1�‚߂̎O�p�`��ʂ�ꍇ + Vector3d crossPoint = GeometryUtility.intersect(GeometryUtility.createPlane(v1, v2, v3), p1, p2); + return crossPoint.getY(); + } else { + // 2�‚߂̎O�p�`��ʂ�ꍇ + Vector3d crossPoint = GeometryUtility.intersect(GeometryUtility.createPlane(v2, v4, v3), p1, p2); + return crossPoint.getY(); + } + } +} + +// +// ********** IndexedTriangleStripArray ���g���o�[�W���� ********** +// (IndexedTriangleStripArray��p����ƃ�������ߖ�ł��邪�A�V�F�[�f�B���O���ł��Ȃ��̂Œ���) +// +//public class Terrain3D extends BaseObject3D { +// static final int MESH_SIZE = 8; +// private Position3D origin; +// private double sizeX = 0; +// private double sizeZ = 0; +// private double heightMap[][] = null; +// private int meshX = 0; +// private int meshZ = 0; +// private IndexedTriangleStripArray triStripAttay = null; +// +// public Terrain3D(Position3D origin, double sizeX, double sizeZ, double heightMap[][], Appearance a) { +// super(); +// this.origin = origin; +// this.sizeX = sizeX; +// this.sizeZ = sizeZ; +// this.heightMap = heightMap; +// meshX = heightMap[0].length; +// meshZ = heightMap.length; +// +// int stripVertexCounts[] = new int[meshZ - 1]; +// for (int n = 0; n < meshZ - 1; n++) { +// stripVertexCounts[n] = meshX * 2; +// } +// triStripAttay = new IndexedTriangleStripArray(meshX * meshZ, +// IndexedTriangleStripArray.COORDINATES | IndexedTriangleStripArray.NORMALS, +// meshX * 2 * (meshZ - 1), +// stripVertexCounts); +// int index = 0, index2 = 0, i1, i2; +// for (int z = 0; z < meshZ; z++) { +// for (int x = 0; x < meshX; x++) { +// // ���_���W�̐ݒ� +// triStripAttay.setCoordinate(index, +// new Point3d(origin.getX() + sizeX * (double)x, +// origin.getY() + heightMap[z][x], +// origin.getZ() + sizeZ * (double)z)); +// // ���_�̖@���x�N�g���̐ݒ� +// Vector3f normal = new Vector3f(); +// if (x < meshX - 1) { +// Vector3f xp = new Vector3f((float)sizeX, (float)(heightMap[z][x+1] - heightMap[z][x]), 0.0f); +// if (z < meshZ - 1) { +// Vector3f zp = new Vector3f(0.0f, (float)(heightMap[z+1][x] - heightMap[z][x]), (float)sizeZ); +// Vector3f v1 = new Vector3f(); +// v1.cross(zp, xp); +// v1.normalize(); +// normal.add(v1); +// } +// if (z > 0) { +// Vector3f zm = new Vector3f(0.0f, (float)(heightMap[z-1][x] - heightMap[z][x]), -(float)sizeZ); +// Vector3f v1 = new Vector3f(); +// v1.cross(xp, zm); +// v1.normalize(); +// normal.add(v1); +// } +// } +// if (x > 0) { +// Vector3f xm = new Vector3f(-(float)sizeX, (float)(heightMap[z][x-1] - heightMap[z][x]), 0.0f); +// if (z < meshZ - 1) { +// Vector3f zp = new Vector3f(0.0f, (float)(heightMap[z+1][x] - heightMap[z][x]), (float)sizeZ); +// Vector3f v1 = new Vector3f(); +// v1.cross(xm, zp); +// v1.normalize(); +// normal.add(v1); +// } +// if (z > 0) { +// Vector3f zm = new Vector3f(0.0f, (float)(heightMap[z-1][x] - heightMap[z][x]), -(float)sizeZ); +// Vector3f v1 = new Vector3f(); +// v1.cross(zm, xm); +// v1.normalize(); +// normal.add(v1); +// } +// } +// normal.normalize(); +// triStripAttay.setNormal(index, normal); +// index++; +// // ���b�V�����ƂɎO�p�`��2�‚��� +// if (z < meshZ - 1) { +// i1 = z * meshX + x; +// i2 = (z + 1) * meshX + x; +// triStripAttay.setCoordinateIndices(index2, new int[]{i1, i2}); +// index2 += 2; +// } +// } +// } +// Appearance a2 = (Appearance)a.cloneNodeComponent(true); +// a2.setCapability(Appearance.ALLOW_MATERIAL_READ); +// a2.setCapability(Appearance.ALLOW_TEXTURE_READ); +// a2.setCapability(Appearance.ALLOW_TEXTURE_WRITE); +// a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); +// a2.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE); +// Shape3D shape = new Shape3D(triStripAttay, a2); +// shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); +// shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); +// center.addChild(shape); +// } +// +// public BoundingSurface[] getBoundingSurfaces() { +// if (boundingSurfaces == null) { +// if (triStripAttay == null) return null; +// double coordinate1[] = new double[3]; +// double coordinate2[] = new double[3]; +// double coordinate3[] = new double[3]; +// double coordinate4[] = new double[3]; +// +// // GeometryArray�̏K�� +// if (triStripAttay instanceof IndexedTriangleStripArray) { +// // IndexedTriangleStripArray �̏ꍇ +// // 8 x 8 ���b�V���P�ʂł܂Ƃ߂� +// BoundingSurface surfaces[] = new BoundingSurface[((meshX + MESH_SIZE - 2) / MESH_SIZE) * ((meshZ + MESH_SIZE - 2) / MESH_SIZE)]; +// int n = 0; +// for (int j = 0; j < meshZ - 1; j += MESH_SIZE) { +// for (int i = 0; i < meshX - 1; i += MESH_SIZE) { +// BoundingSurface parent = new BoundingSurface(); +// double lowY = 1.0; +// double highY = -1.0; +// for (int j2 = 0; j + j2 < meshZ - 1 && j2 < MESH_SIZE; j2++) { +// for (int i2 = 0; i + i2 < meshX - 1 && i2 < MESH_SIZE; i2++) { +// int index = (j + j2) * meshX * 2 + (i + i2) * 2; +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index), coordinate1); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+1), coordinate2); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+2), coordinate3); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+3), coordinate4); +// if (lowY > highY) { +// lowY = highY = coordinate1[1]; +// } else { +// if (lowY > coordinate1[1]) { +// lowY = coordinate1[1]; +// } else if (highY < coordinate1[1]) { +// highY = coordinate1[1]; +// } +// if (lowY > coordinate2[1]) { +// lowY = coordinate2[1]; +// } else if (highY < coordinate2[1]) { +// highY = coordinate2[1]; +// } +// if (lowY > coordinate3[1]) { +// lowY = coordinate3[1]; +// } else if (highY < coordinate3[1]) { +// highY = coordinate3[1]; +// } +// if (lowY > coordinate4[1]) { +// lowY = coordinate4[1]; +// } else if (highY < coordinate4[1]) { +// highY = coordinate4[1]; +// } +// } +// +// // 1 x 1 ���b�V������BoundingSurface +// Vector3d v1 = new Vector3d(coordinate1); +// Vector3d v2 = new Vector3d(coordinate2); +// Vector3d v3 = new Vector3d(coordinate3); +// Vector3d v4 = new Vector3d(coordinate4); +// BoundingSurface bSurface = new BoundingSurface(); +// bSurface.addVertex((Vector3d)v1.clone()); //1�‚߂̎O�p�` +// bSurface.addVertex((Vector3d)v2.clone()); +// bSurface.addVertex((Vector3d)v3.clone()); +// bSurface.setBounds(createBoundingPolytope(v1, v2, v3)); +// parent.addChild(bSurface, false); +// +// bSurface = new BoundingSurface(); +// bSurface.addVertex((Vector3d)v2.clone()); //2�‚߂̎O�p�` +// bSurface.addVertex((Vector3d)v4.clone()); +// bSurface.addVertex((Vector3d)v3.clone()); +// bSurface.setBounds(createBoundingPolytope(v2, v4, v3)); +// parent.addChild(bSurface, true); +// } +// } +// // 8 x 8 ���b�V���P�ʂ�BoundingSurface +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(j * meshX * 2 + i * 2), coordinate1); +// parent.setBounds(new BoundingBox(new Point3d(coordinate1[0], lowY, coordinate1[2]), +// new Point3d(coordinate4[0], highY, coordinate4[2]))); +// surfaces[n] = parent; +// n++; +// } +// } +// boundingSurfaces = surfaces; +// } else { +// return null; +// } +// } +// return boundingSurfaces; +// } +// +// public double getHeight(double x, double z) { +// int i = (int)((x - origin.getX()) / sizeX); +// int j = (int)((z - origin.getZ()) / sizeZ); +// if (i >= meshX || i < 0 || j >= meshZ || j < 0) return 0.0; +// +// int index = j * meshX * 2 + i * 2; +// double coordinate1[] = new double[3]; +// double coordinate2[] = new double[3]; +// double coordinate3[] = new double[3]; +// double coordinate4[] = new double[3]; +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index), coordinate1); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+1), coordinate2); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+2), coordinate3); +// triStripAttay.getCoordinates(triStripAttay.getCoordinateIndex(index+3), coordinate4); +// Vector3d v1 = new Vector3d(coordinate1); +// Vector3d v2 = new Vector3d(coordinate2); +// Vector3d v3 = new Vector3d(coordinate3); +// Vector3d v4 = new Vector3d(coordinate4); +// Vector3d p1 = new Vector3d(x, 0.0, z); +// Vector3d p2 = new Vector3d(x, 1.0, z); +// +// double x2 = x - (double)i * sizeX - origin.getX(); +// double z2 = z - (double)j * sizeZ - origin.getZ(); +// if (x2 < GeometryUtility.TOLERANCE || (meshZ - z2) / x2 > meshZ / meshX) { +// // 1�‚߂̎O�p�`��ʂ�ꍇ +// Vector3d crossPoint = GeometryUtility.intersect(GeometryUtility.createPlane(v1, v2, v3), p1, p2); +// return crossPoint.getY(); +// } else { +// // 2�‚߂̎O�p�`��ʂ�ꍇ +// Vector3d crossPoint = GeometryUtility.intersect(GeometryUtility.createPlane(v2, v4, v3), p1, p2); +// return crossPoint.getY(); +// } +// } +//} diff --git a/src/main/java/framework/model3D/UndoBuffer.java b/src/main/java/framework/model3D/UndoBuffer.java new file mode 100644 index 0000000..aad37c7 --- /dev/null +++ b/src/main/java/framework/model3D/UndoBuffer.java @@ -0,0 +1,50 @@ +package framework.model3D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; + + + +public class UndoBuffer { + + @SuppressWarnings("unchecked") + private ArrayList> list = new ArrayList>(); + @SuppressWarnings("unchecked") + private Hashtable nowCondition = new Hashtable(); + private static final int max = 3; + + UndoBuffer() { + } + + UndoBuffer(UndoBuffer another) { + this.list = (ArrayList>)another.list.clone(); + this.nowCondition = (Hashtable)another.nowCondition.clone(); + } + + public void push(Property3D p) { + nowCondition.put(p.getClass(), p.clone()); + } + + @SuppressWarnings("unchecked") + public void setUndoMark() { + if(list.size() == max) { + list.remove(max - 1); + } + list.add(0, (Hashtable) nowCondition.clone()); + } + + @SuppressWarnings("unchecked") + public Collection undo() { + if(list.size() != 0) { + nowCondition = list.remove(0); + return nowCondition.values(); + } + else { + return new Hashtable().values(); + } + } + + public void clear() { + + } +} diff --git a/src/main/java/framework/model3D/Universe.java b/src/main/java/framework/model3D/Universe.java new file mode 100644 index 0000000..e52c392 --- /dev/null +++ b/src/main/java/framework/model3D/Universe.java @@ -0,0 +1,415 @@ +package framework.model3D; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Stack; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Light; +import javax.media.j3d.Locale; +import javax.media.j3d.Material; +import javax.media.j3d.Node; +import javax.media.j3d.RenderingAttributes; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.VirtualUniverse; +import javax.vecmath.Color3f; + + + +/** + * �e�A���˃}�b�s���O�A�o���v�}�b�s���O�Ȃǂ������_�����O�ł��� SimpleUniverse + * �i���ׂĂ̕��̂�z�u������ɁA�K�� compile() ���Ă΂Ȃ��Ƃ����Ȃ����Ƃɒ��ӁI�j + * @author �V�c���� + * + */ +public class Universe extends VirtualUniverse { + private Locale locale = null; + private BranchGroup root = null; + private BranchGroup additionalRoot = null; + private ArrayList lights = new ArrayList(); + private BackgroundBox skyBox = null; +// private ArrayList backgrounds = new ArrayList(); + private double shadowDepth = 100.0; + private ArrayList occluders = new ArrayList(); + private ArrayList shadows = new ArrayList(); + private ArrayList receivers = new ArrayList(); + private ArrayList extraObjects = new ArrayList(); + + public Universe() { + super(); + locale = new Locale(this); + root = new BranchGroup(); + additionalRoot = new BranchGroup(); + additionalRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); + additionalRoot.setCapability(BranchGroup.ALLOW_CHILDREN_READ); + additionalRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + shadowDepth = 100.0; + } + + /** + * ���f���̃��[�g��ݒ肷�� + * @param root + */ + public void setRoot(BranchGroup root) { + removeRoot(); + this.root = root; + } + + /** + * ���f���̃��[�g���擾���� + * @return ���f���̃��[�g�ɑ������� SceneGraph + */ + public BranchGroup getRoot() { + return root; + } + + /** + * ���f���̃��[�g���폜���� + */ + public void removeRoot() { + if (root == null) return; + Enumeration branchGroups = locale.getAllBranchGraphs(); + while (branchGroups.hasMoreElements()) { + if (branchGroups.nextElement() == root) { + locale.removeBranchGraph(root); + root = null; + break; + } + } + } + + public void addBranchGraph(BranchGroup g) { + locale.addBranchGraph(g); + } + + /** + * �I�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void place(Node obj) { + if (!root.isCompiled()) { + root.addChild(obj); + } else { + additionalRoot.addChild(obj); + } + } + + /** + * �I�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void place(Placeable obj) { + BaseObject3D body = obj.getBody(); + if (body.isReflectionMappingApplied() || body.isBumpMappingApplied()) { + extraObjects.add(body); + } else { + place(obj.getTransformGroupToPlace()); + } + } + + /** + * ��Ŏ�菜����悤�ɃI�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeDisplacable(Node obj) { + BranchGroup objRoot; + if (obj.getParent() != null + && obj.getParent() instanceof BranchGroup) { + objRoot = (BranchGroup)obj.getParent(); + } else { + objRoot = new BranchGroup(); + objRoot.setCapability(BranchGroup.ALLOW_DETACH); + objRoot.addChild(obj); + } + additionalRoot.addChild(objRoot); + } + + /** + * ��Ŏ�菜����悤�ɃI�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeDisplacable(Placeable obj) { + BaseObject3D body = obj.getBody(); + if (body != null && (body.isReflectionMappingApplied() || body.isBumpMappingApplied())) { + extraObjects.add(body); + } else { + placeDisplacable(obj.getTransformGroupToPlace()); + } + } + + /** + * �e�t���Ŕz�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeAsAnOcculuder(Placeable obj) { + BaseObject3D body = obj.getBody(); + if (body instanceof Object3D) { + addShadowOcculuder((Object3D)body); + } else { + place(obj); + } + } + + /** + * ���̃I�u�W�F�N�g�̉e��������悤�ɃI�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeAsAReceiver(Placeable obj) { + addShadowReceiver(obj.getBody(), new Color3f(0.5f, 0.5f, 0.5f)); + } + + /** + * ���̃I�u�W�F�N�g�̉e��������悤�ɃI�u�W�F�N�g��\������ + * @param obj �\������I�u�W�F�N�g + * @param shadowColor �e�̐F + */ + public void placeAsAReceiver(Placeable obj, Color3f shadowColor) { + addShadowReceiver(obj.getBody(), shadowColor); + } + + /** + * �����̒lj� + * @param light �lj�������� + */ + public void placeLight(Light light) { + root.addChild(light); + getLights().add((Light)light.cloneTree()); + } + + /** + * �����̒lj��i�e�‚��j + * @param light �lj�������� + * @param shadowDepth �e�̐[�� + */ + public void placeLight(Light light, double shadowDepth) { + root.addChild(light); + getLights().add((Light)light.cloneTree()); + this.shadowDepth = shadowDepth; + } + + /** + * �X�J�C�{�b�N�X�̒lj� + * @param skyBox �lj�����X�J�C�{�b�N�X + */ + public void placeSkyBox(BackgroundBox skyBox) { + root.addChild(skyBox); + this.skyBox = skyBox; + } + + /** + * �I�u�W�F�N�g���”\�Ȃ�Ύ�菜�� + * @param obj ��菜���I�u�W�F�N�g + */ + public void displace(Node obj) { + Node parent = obj.getParent(); + if (parent == root) return; + if (parent == additionalRoot) { + additionalRoot.removeChild(obj); + } else if (parent instanceof BranchGroup + && parent.getCapability(BranchGroup.ALLOW_DETACH) + && parent.getParent() == additionalRoot) { + additionalRoot.removeChild(parent); + } + } + + /** + * �I�u�W�F�N�g���”\�Ȃ�Ύ�菜�� + * @param obj ��菜���I�u�W�F�N�g + */ + public void displace(Placeable obj) { + BaseObject3D body = obj.getBody(); + if (occluders.contains(body)) { + occluders.remove(body); + } + if (shadows.contains(body)) { + shadows.remove(body); + } + if (receivers.contains(body)) { + receivers.remove(body); + } + if (extraObjects.contains(body)) { + extraObjects.remove(body); + } + displace(obj.getTransformGroupToPlace()); + } + + public ArrayList getLights() { + return lights; + } + + public BackgroundBox getSkyBox() { + return skyBox; + } + + private void addShadowOcculuder(Object3D occluder) { +// occluder.view(this); // occluder ���g�̕\�� + ShadowVolumeVisitor shadowVolumeVisitor = + new ShadowVolumeVisitor(getLights(), shadowDepth); // ShadowVolume �̐��� + occluder.accept(shadowVolumeVisitor); // occluder ������ ShadowVolume ���ێ������ + occluders.add(occluder); + } + + private void addShadowReceiver(BaseObject3D receiverObject, Color3f shadowColor) { + BaseObject3D receiverObjectBody = receiverObject.duplicate(); + + // ���� BaseObject3D ���e�\���p�ɂ��� + ArrayList aps = receiverObject.getAppearances(); + Material m = new Material(); + m.setDiffuseColor(shadowColor); // �e�̐F + m.setAmbientColor(0.0f, 0.0f, 0.0f); + m.setSpecularColor(0.0f, 0.0f, 0.0f); + m.setShininess(1.0f); + RenderingAttributes ra = new RenderingAttributes(); + ra.setStencilEnable(false); // �X�e���V���o�b�t�@���g��Ȃ� + ra.setDepthBufferWriteEnable(true); // �ʏ�ʂ�Z�o�b�t�@�ɏ������� + ra.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); // �ʏ�ʂ�Z�o�b�t�@�Ŕ��肷�� + for (int n = 0; n < aps.size(); n++) { + Appearance ap = aps.get(n); + ap.setMaterial(m); + ap.setRenderingAttributes(ra); + } + + shadows.add(receiverObject); + + // �������� BaseObject3D ��ʏ�\���p�i�������e�̕����͕`�悵�Ȃ��j�ɂ��� + ArrayList aps2 = receiverObjectBody.getAppearances(); + RenderingAttributes ra2 = new RenderingAttributes(); + ra2.setStencilEnable(true); // �X�e���V���o�b�t�@���g�� + ra2.setDepthBufferWriteEnable(true); + ra2.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); // �e�̏�ɏ㏑������ + ra2.setStencilFunction(RenderingAttributes.GREATER_OR_EQUAL, 0, ~0); // �X�e���V���o�b�t�@�̒l��1�ȏ�̂Ƃ��`�悵�Ȃ� + ra2.setStencilOp(RenderingAttributes.STENCIL_REPLACE, // �X�e���V���o�b�t�@���N���A���� + RenderingAttributes.STENCIL_REPLACE, + RenderingAttributes.STENCIL_REPLACE); +// TransparencyAttributes ta2 = new TransparencyAttributes(); +// ta2.setTransparencyMode(TransparencyAttributes.BLENDED); +// ta2.setTransparency(0.0001f); + for (int n = 0; n < aps2.size(); n++) { + Appearance ap2 = aps2.get(n); + ap2.setRenderingAttributes(ra2); +// ap2.setTransparencyAttributes(ta2); + } + + receivers.add(receiverObjectBody); + } + + public void update() { + ShadowVolumeVisitor shadowVolumeVisitor = + new ShadowVolumeVisitor(); // ShadowVolume �� �X�V + for (int n = 0; n < occluders.size(); n++) { + occluders.get(n).accept(shadowVolumeVisitor); + } + } + + /** + * Mixed���[�h�����_�����O��p���ĉe�̕`����s�� + * �i�e��������I�u�W�F�N�g�i���V�[�o�j�̉e�����A�V���h�E�{�����[���j + * @param graphicsContext3D + */ + public void preRender(IViewer3D viewer) { + update(); + + viewer.update(lights, skyBox); + } + + /** + * Mixed���[�h�����_�����O��p���ĉe�̕`����s�� + * �i�e��������I�u�W�F�N�g�̉e�ȊO�̕����j + * @param graphicsContext3D + */ + public void renderField(IViewer3D viewer) { + // ������ �����_�����O�͈ȉ��̏��Ԃł������܂������Ȃ� ������ + // ���Ƃ��΁A�V���h�E�{�����[���������_�����O������Ƀ��V�[�o�̉e�ȊO�̕����������_�����O����ƁA + // BackgroundBox�̕`�悪�Ȃ��������Ȃ��Ă��܂��B + + // 1. ���V�[�o�̉e���� + Transform3D trans = new Transform3D(); + for (int n = 0; n < shadows.size(); n++) { + BaseObject3D obj = shadows.get(n); + if (obj instanceof Object3D) { + ((Object3D)obj).accept(new ObjectRenderer(viewer)); + } else { + obj.center.getTransform(trans); + viewer.setModelTransform(trans); + viewer.draw(obj); + } + } + + // 2. ���V�[�o�̉e�ȊO�̕��� + for (int n = 0; n < receivers.size(); n++) { + BaseObject3D obj = receivers.get(n); + if (obj instanceof Object3D) { + ((Object3D)obj).accept(new ObjectRenderer(viewer)); + } else { + obj.center.getTransform(trans); + viewer.setModelTransform(trans); + viewer.draw(obj); + } + } + + // 3. �V���h�E�{�����[���̕\�ʁiocculuder�����ɐς�ł���j + // 4. �V���h�E�{�����[���̗��ʁiocculuder�����ɐς�ł���j + for (int n = 0; n < occluders.size(); n++) { + Object3D occuluder = occluders.get(n); + occuluder.accept(new ObjectRenderer(viewer)); + } + + // ����ȃ����_�����O���K�v�ƂȂ�I�u�W�F�N�g + for (int n = 0; n < extraObjects.size(); n++) { + BaseObject3D extra = extraObjects.get(n); + if (extra instanceof Object3D) { + ((Object3D)extra).accept(new ObjectRenderer(viewer)); + } else { + extra.center.getTransform(trans); + viewer.setModelTransform(trans); + viewer.draw(extra); + } + } + } + + public void postRender(IViewer3D viewer) { + } + + public void compile() { + root.compile(); + locale.addBranchGraph(root); + locale.addBranchGraph(additionalRoot); + } + + private class ObjectRenderer extends ObjectVisitor { + Stack transforms = new Stack(); + IViewer3D viewer = null; + + public ObjectRenderer(IViewer3D viewer) { + Transform3D t = new Transform3D(); + transforms.push(t); + this.viewer = viewer; + } + + @Override + public void preVisit(Object3D obj) { + Transform3D t = new Transform3D(transforms.peek()); + Transform3D t2 = new Transform3D(); + obj.pos.getTransform(t2); + t.mul(t2); + obj.rot.getTransform(t2); + t.mul(t2); + obj.scale.getTransform(t2); + t.mul(t2); + obj.center.getTransform(t2); + t.mul(t2); + transforms.push(t); + } + + @Override + public void postVisit(Object3D obj) { + Transform3D t = transforms.pop(); + if (!obj.hasChildren()) { + viewer.setModelTransform(t); + viewer.draw(obj); + } + } + } +} diff --git a/src/main/java/framework/physics/AngularVelocity3D.java b/src/main/java/framework/physics/AngularVelocity3D.java new file mode 100644 index 0000000..97b1c02 --- /dev/null +++ b/src/main/java/framework/physics/AngularVelocity3D.java @@ -0,0 +1,85 @@ +package framework.physics; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Vector3d; + +import framework.model3D.Object3D; +import framework.model3D.Property3D; + + +public class AngularVelocity3D extends Property3D{ + private double x; + private double y; + private double z; + + public AngularVelocity3D(AngularVelocity3D w) { + x = w.x; + y = w.y; + z = w.z; + } + + public AngularVelocity3D(double x,double y,double z){ + this.x = x; + this.y = y; + this.z = z; + } + + public AngularVelocity3D(){ + x = 0.0; + y = 0.0; + z = 0.0; + } + + public void applyTo(Object3D o){ + ((Solid3D)o).setAngularVelocity(this); + } + + public double getX() { + // TODO Auto-generated method stub + return this.x; + } + + public double getY() { + // TODO Auto-generated method stub + return this.y; + } + + public double getZ() { + // TODO Auto-generated method stub + return this.z; + } + + public AngularVelocity3D add(double x, double y, double z){ + this.x += x; + this.y += y; + this.z += z; + return this; + } + + public AngularVelocity3D add(Vector3d v) { + // TODO Auto-generated method stub + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + } + + public Vector3d getVector3d(){ + return new Vector3d(x,y,z); + } + + public AxisAngle4d getAxisAngle4d() { + double l = getVector3d().length(); + if (l <= 0.00001) { + return new AxisAngle4d(0, 0, 1.0, 0.0); + } + return new AxisAngle4d(x / l, y / l, z / l, l); + } + + @Override + public Property3D clone() { + // TODO Auto-generated method stub + return new AngularVelocity3D(this); + } +} + + diff --git a/src/main/java/framework/physics/BoundingBoxVisitor.java b/src/main/java/framework/physics/BoundingBoxVisitor.java new file mode 100644 index 0000000..735aa51 --- /dev/null +++ b/src/main/java/framework/physics/BoundingBoxVisitor.java @@ -0,0 +1,93 @@ +package framework.physics; +import java.util.ArrayList; + +import javax.media.j3d.BoundingSphere; + +import framework.model3D.OBB; +import framework.model3D.Object3D; +import framework.model3D.ObjectVisitor; + + +public class BoundingBoxVisitor extends ObjectVisitor { + private ArrayList obbList = new ArrayList(); // �S�\���v�f��OBB�̃��X�g + private ArrayList bsStack = new ArrayList(); // �I�u�W�F�N�g�̊K�w����BoundingSphere�̃X�^�b�N + private String partName = null; // ���i���w�肷��ꍇ�Ɏg�� + private boolean inPart = false; + + public BoundingBoxVisitor() { + partName = null; + } + + public BoundingBoxVisitor(String partName) { + this.partName = partName; + } + + public void preVisit(Object3D obj) { + pushTransform(obj); + if (partName != null && obj.name.equals(partName)) { + inPart = true; + } + if (obj.hasChildren() && obj.bs == null) { + // �q��������ꍇ�A���̊K�w�p��null��push���� + bsStack.add(null); + } + } + + public void postVisit(Object3D obj) { + int pattern = 2; + if (!obj.hasChildren()) { + // �t�̏ꍇ + OBB obb = obj.getOBB(pattern); + if (obb != null) { + if (obj.bs == null) { + obj.bs = obb.getBoundingSphere(); + } + + obb = (OBB)obb.clone(); + BoundingSphere bs = (BoundingSphere)obj.bs.clone(); + for (int i = stackList.size() - 1; i >= 0; i--) { + obb.transform(stackList.get(i)); + bs.transform(stackList.get(i)); + } + if (partName == null || partName.length() == 0 || inPart) { + obbList.add(obb); // Transform3D��K��������Bounds��boundsList�ɒlj� + int stackTop = bsStack.size() - 1; + if (bs != null && stackTop >= 0) { + if (bsStack.get(stackTop) == null) { + // ���̊K�w�̍ŏ��̃I�u�W�F�N�g�̏ꍇ�Anull��u������ + bsStack.set(stackTop, bs); + } else { + // ���̊K�w��2�Ԗڈȍ~�̃I�u�W�F�N�g�̏ꍇ�A���� + bsStack.get(stackTop).combine(bs); + } + } + } + } + } else { + // �q��������ꍇ + int stackTop = bsStack.size() - 1; + if (obj.bs == null) { + // ���̊K�w�̌������ʂ�pop���ė��p���� + obj.bs = bsStack.remove(stackTop); + stackTop--; + } + if (obj.bs != null && stackTop >= 0) { + if (bsStack.get(stackTop) == null) { + // ���̊K�w�̍ŏ��̃I�u�W�F�N�g�̏ꍇ�Anull��u������ + bsStack.set(stackTop, obj.bs); + } else { + // ���̊K�w��2�Ԗڈȍ~�̃I�u�W�F�N�g�̏ꍇ�A���� + bsStack.get(stackTop).combine(obj.bs); + } + } + } + popTransform(); + if (partName != null && obj.name.equals(partName)) { + inPart = false; + } + } + + public ArrayList getObbList() { + return obbList; + } +} diff --git a/src/main/java/framework/physics/BoundingSurfaceVisitor.java b/src/main/java/framework/physics/BoundingSurfaceVisitor.java new file mode 100644 index 0000000..702367a --- /dev/null +++ b/src/main/java/framework/physics/BoundingSurfaceVisitor.java @@ -0,0 +1,61 @@ +package framework.physics; + +import java.util.ArrayList; + +import javax.media.j3d.Transform3D; + +import framework.model3D.BaseObject3D; +import framework.model3D.BoundingSurface; +import framework.model3D.Object3D; +import framework.model3D.ObjectVisitor; + +/** + * �n�ʂ̏Փ˔���p�̃{�����[���𐶐����邽�߂̃r�W�^�[ + * @author �V�c���� + * + */ +public class BoundingSurfaceVisitor extends ObjectVisitor { + private ArrayList boundingSurfaceList = new ArrayList(); + public BoundingSurfaceVisitor() { + boundingSurfaceList.add(new BoundingSurface()); + } + + public void preVisit(Object3D obj) { + pushTransform(obj); + if (obj.hasChildren()) { + boundingSurfaceList.add(new BoundingSurface()); + } + } + + public void postVisit(Object3D obj) { + if (!obj.hasChildren()) { + // �t�̏ꍇ + BoundingSurface[] s = (BoundingSurface[]) obj.getBoundingSurfaces().clone(); + for (int i = 0; i < s.length; i++) { + s[i] = (BoundingSurface) s[i].clone(); + for (int j = stackList.size() - 1; j >= 0; j--) { + s[i].transform(stackList.get(j)); + } + boundingSurfaceList.get(boundingSurfaceList.size() - 1).addChild(s[i], true); // Transform3D��K��������Bounds��surfaceList�ɒlj� + } + } else { + BoundingSurface child = boundingSurfaceList.remove(boundingSurfaceList.size() - 1); + BoundingSurface parent = boundingSurfaceList.get(boundingSurfaceList.size() - 1); + parent.addChild(child, true); + } + popTransform(); + } + + public void baseVisit(BaseObject3D obj) { + BoundingSurface parent = boundingSurfaceList.get(boundingSurfaceList.size() - 1); + BoundingSurface[] s = (BoundingSurface[]) obj.getBoundingSurfaces().clone(); + for (int i = 0; i < s.length; i++) { + s[i] = (BoundingSurface) s[i].clone(); + parent.addChild(s[i], true); + } + } + + public BoundingSurface getBoundingSurface() { + return boundingSurfaceList.get(0); + } +} diff --git a/src/main/java/framework/physics/Force3D.java b/src/main/java/framework/physics/Force3D.java new file mode 100644 index 0000000..dd77287 --- /dev/null +++ b/src/main/java/framework/physics/Force3D.java @@ -0,0 +1,35 @@ +package framework.physics; +import javax.vecmath.Vector3d; + + +public class Force3D { + double x; + double y; + double z; + public static final Force3D ZERO = new Force3D( 0.0, 0.0, 0.0); + + public Force3D(double x,double y,double z){ + this.x = x; + this.y = y; + this.z = z; + } + + public Force3D(Vector3d v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } + public Vector3d getVector3d(){ + return new Vector3d(x,y,z); + } + + public void add(Force3D f) { + x += f.x; + y += f.y; + z += f.z; + } + + public double getSeverity() { + return getVector3d().length(); + } +} diff --git a/src/main/java/framework/physics/Ground.java b/src/main/java/framework/physics/Ground.java new file mode 100644 index 0000000..069b2cc --- /dev/null +++ b/src/main/java/framework/physics/Ground.java @@ -0,0 +1,57 @@ +package framework.physics; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.TransformGroup; + +import framework.model3D.BaseObject3D; +import framework.model3D.BoundingSurface; +import framework.model3D.Object3D; +import framework.model3D.Placeable; + + +/** + * �n�ʂȂǂ́i��{�I�ɓ����Ȃ��j�\������\���I�u�W�F�N�g + * @author �V�c���� + * + */ +public class Ground implements Placeable { + private BaseObject3D groundObj = null; + private BoundingSurface boundingSurface = null; // �Փ˔���p�{�����[���̃L���b�V�� + + public Ground(BaseObject3D obj) { + groundObj = obj; + } + + public BaseObject3D getBody() { + return groundObj; + } + + public void updateBody(BaseObject3D obj) { + groundObj = obj; + boundingSurface = null; + } + + @Override + public TransformGroup getTransformGroupToPlace() { + return groundObj.getTransformGroupToPlace(); + } + + /** + * �Փ˔���p�̃{�����[�����擾���� + * @return �Փ˔���p�{�����[���i�K�w������Ă���ꍇ������j + */ + BoundingSurface getBoundingSurface() { + if (boundingSurface == null) { + // �L���b�V���ɉ����ς܂�Ă��Ȃ��ꍇ�̂݌v�Z���� + BoundingSurfaceVisitor surfaceVisitor = new BoundingSurfaceVisitor(); + if (groundObj instanceof Object3D) { + // Object3D�̏ꍇ�K�w�\�������ǂ� + ((Object3D)groundObj).accept(surfaceVisitor); + } else { + // BaseObject3d�̏ꍇ�K�w�\�����Ȃ� + surfaceVisitor.baseVisit(groundObj); + } + boundingSurface = surfaceVisitor.getBoundingSurface(); + } + return boundingSurface; + } +} diff --git a/src/main/java/framework/physics/Inertia3D.java b/src/main/java/framework/physics/Inertia3D.java new file mode 100644 index 0000000..4583bbb --- /dev/null +++ b/src/main/java/framework/physics/Inertia3D.java @@ -0,0 +1,54 @@ +package framework.physics; +import javax.vecmath.Vector3d; + +import framework.model3D.OBB; + + +public class Inertia3D { + double ixx; + double iyy; + double izz; + static final Inertia3D ZERO = new Inertia3D( 0.0, 0.0, 0.0); + + public Inertia3D(double x,double y,double z){ + this.ixx = x; + this.iyy = y; + this.izz = z; + } + + public Inertia3D(Vector3d v) { + this.ixx = v.x; + this.iyy = v.y; + this.izz = v.z; + } + + public Inertia3D(Solid3D obj) { + BoundingBoxVisitor visitor = new BoundingBoxVisitor(); + obj.accept(visitor); + if (visitor.getObbList().size() == 1) { + OBB obb = visitor.getObbList().get(0); + Vector3d vx = new Vector3d(); + vx.sub(obb.getVertex(4), obb.getVertex(0)); + + Vector3d vy = new Vector3d(); + vy.sub(obb.getVertex(1), obb.getVertex(0)); + + Vector3d vz = new Vector3d(); + vz.sub(obb.getVertex(2), obb.getVertex(0)); + +// System.out.println("vx:" + vx + ",vy:" + vy + ",vz:" + vz); + this.ixx = obj.mass * (1.0/12.0 * (Math.pow(vy.length(), 2.0) + Math.pow(vz.length(), 2.0))); + this.iyy = obj.mass * (1.0/12.0 * (Math.pow(vx.length(), 2.0) + Math.pow(vz.length(), 2.0))); + this.izz = obj.mass * (1.0/12.0 * (Math.pow(vx.length(), 2.0) + Math.pow(vy.length(), 2.0))); + } else { + this.ixx = obj.mass; + this.iyy = obj.mass; + this.izz = obj.mass; + } + } + + public Vector3d getVector3d() { + return new Vector3d(ixx, iyy, izz); + } +} + diff --git a/src/main/java/framework/physics/PhysicalSystem.java b/src/main/java/framework/physics/PhysicalSystem.java new file mode 100644 index 0000000..d95d23a --- /dev/null +++ b/src/main/java/framework/physics/PhysicalSystem.java @@ -0,0 +1,153 @@ +package framework.physics; + +import java.util.ArrayList; + +import javax.vecmath.Vector3d; + +import framework.model3D.CollisionResult; +import framework.model3D.Position3D; + + +public class PhysicalSystem { + + public ArrayList objects = new ArrayList(); + + // ���̂̑}�� + public int add(Solid3D s) { + objects.add(s); + return objects.size() - 1; + } + + // ���̂̉^�� + public void motion(int id, long interval, Force3D f, Position3D appPoint, Ground ground) { + ArrayList forces[] = new ArrayList[objects.size()]; + ArrayList appPoints[] = new ArrayList[objects.size()]; + for (int i = 0; i < objects.size(); i++) { + forces[i] = new ArrayList(); + appPoints[i] = new ArrayList(); + } + + // id�Ԗڂ̊O�͂̌v�Z + forces[id].add(f); + appPoints[id].add(appPoint); +// objects.get(id).move(interval, f, appPoint); + + double l; // �΂˂̐L�� + + Force3D penalty = new Force3D(0.0, 0.0, 0.0); // �y�i���e�B�@�ɂ��y�i���e�B�̍�p�̗� + Force3D inversepenalty; // + // //�y�i���e�B�@�ɂ��y�i���e�B�̔���p�̗� + CollisionResult cr; + Solid3D s; + for (int n = 0; n < objects.size(); n++) { + // �d�͂̌v�Z + s = objects.get(n); + forces[n].add(PhysicsUtility.getGravity(s)); + appPoints[n].add(s.getGravityCenter()); +// objects.get(n).move(interval, +// PhysicsFacade.getGravity(objects.get(n)), +// objects.get(n).getGravityCenter()); // �d�͂̌v�Z + // �n�ʂƂ̓����蔻�� + cr = PhysicsUtility.doesIntersect(s, ground); + // �n�ʂɕ��̂��߂荞��ł���ꍇ + if (cr != null) { + double gk = 5000.0; // �n�ʂł̂΂ˌW�� + double e = 1.0; // �n�ʂł̒��˕Ԃ莞�̒�R�W�� + double b = 300.0; + l = cr.length; + // <��p�̗͂̌v�Z> + // �y�i���e�B�̕ϐ� +// Vector3d v = cr.normal; +// v.scale(gk * l); + // ��p�_�x�N�g���̍쐬 + Vector3d r = cr.collisionPoint.getVector3d(); + // (��p�_-�d�S)�x�N�g�� + r.sub(s.getGravityCenter().getVector3d()); + // �p���x�x�N�g���̍쐬 + Vector3d angVel = s.getAngularVelocity().getVector3d(); + // �p���x�x�N�g����(��p�_-�d�S)�x�N�g���̊O�όv�Z + angVel.cross(angVel, r); + // ���x�x�N�g��+�p���x�x�N�g����(��p�_-�d�S)�x�N�g���̊O�όv�Z + Vector3d relV = s.getVelocity().getVector3d(); + // ���Α��x�x�N�g���̍쐬 + relV.add(angVel); + Vector3d v = cr.normal; +//System.out.println(r + "," + (gk * l) + "," + (- relV.dot(v) * b)); + // �y�i���e�B�̑傫������ + v.scale(gk * l - relV.dot(v) * b); + penalty = new Force3D(v); + + // ��p�̗͂ɂ��^�� + forces[n].add(penalty); + appPoints[n].add(cr.collisionPoint); +// objects.get(n).move(interval, penalty, cr.collisionPoint); + } + // �n�ʂɕ��̂��߂荞��ł��Ȃ��ꍇ + else { + } + for (int m = 0; m < n; m++) { + Solid3D s1 = objects.get(n); + Solid3D s2 = objects.get(m); + cr = PhysicsUtility.checkCollision(s1, null, s2, null); + // ���̂��߂荞��ł���ꍇ + if (cr != null) { + double sk = 5000; // ���̂ł̂΂ˌW�� + double e = 0.2; // ���̂ł̒��˕Ԃ莞�̒�R�W�� + double b = 300.0; + l = cr.length; + // <��p�̗͂̌v�Z> + // ��p�_�x�N�g���̍쐬 + // s1�Ɋւ���v�Z + // s1�̊p���x�x�N�g���̍쐬 + Vector3d r = cr.collisionPoint.getVector3d(); + r.sub(s1.getGravityCenter().getVector3d()); + Vector3d s1AngVel = s1.getAngularVelocity().getVector3d(); + s1AngVel.cross(s1AngVel, r); + // s1�̑��x�x�N�g���̍쐬 + Vector3d s1RelV = s1.getVelocity().getVector3d(); + // s1�̑��x�x�N�g��+s1�̊p���x�x�N�g����(��p�_-s1�̏d�S)�x�N�g���̊O�όv�Z + s1RelV.add(s1AngVel); + // s2�Ɋւ���v�Z + // s2�̊p���x�x�N�g���̍쐬 + r = cr.collisionPoint.getVector3d(); + r.sub(s2.getGravityCenter().getVector3d()); + Vector3d s2AngVel = s2.getAngularVelocity().getVector3d(); + s2AngVel.cross(s2AngVel, r); + // s2�̑��x�x�N�g���̍쐬 + Vector3d s2RelV = s2.getVelocity().getVector3d(); + // s2�̑��x�x�N�g��+s2�̊p���x�x�N�g����(��p�_-s2�̏d�S)�x�N�g���̊O�όv�Z + s2RelV.add(s2AngVel); + // ���Α��x�x�N�g���̍쐬 + s1RelV.sub(s2RelV); + // �y�i���e�B�̑傫������ + Vector3d v = (Vector3d)cr.normal.clone(); +//System.out.println(r + "," + (sk * l) + "," + (- relV.dot(v) * b)); + v.scale(sk * l - s1RelV.dot(v) * b); + penalty = new Force3D(v); + + // ����p�̗͂̌v�Z + v.scale(-1); + inversepenalty = new Force3D(v); + + // ��p�̗͂ɂ�镨�̂̈ړ� + forces[n].add(penalty); + appPoints[n].add(cr.collisionPoint); +// s1.move(interval, penalty, cr.collisionPoint); + + // ����p�̗͂ɂ�镨�̂̈ړ� + forces[m].add(inversepenalty); + appPoints[m].add(cr.collisionPoint); +// s2.move(interval, inversepenalty, cr.collisionPoint); + } +// // ���̂��߂荞��ł��Ȃ��ꍇ +// else { +// s2.move(interval, f, s2.getGravityCenter()); +// s1.move(interval, f, s1.getGravityCenter()); +// } + } + } + for (int n2 = 0; n2 < objects.size(); n2++) { + objects.get(n2).move(interval, forces[n2], appPoints[n2]); + } + } +} diff --git a/src/main/java/framework/physics/PhysicsUtility.java b/src/main/java/framework/physics/PhysicsUtility.java new file mode 100644 index 0000000..8019eec --- /dev/null +++ b/src/main/java/framework/physics/PhysicsUtility.java @@ -0,0 +1,194 @@ +package framework.physics; + +import java.util.ArrayList; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Transform3D; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; + +import framework.model3D.BoundingSurface; +import framework.model3D.CollisionResult; +import framework.model3D.Object3D; +import framework.model3D.Position3D; + + +/** + * �������Z�̃R�A + * @author �V�c���� + * + */ +public class PhysicsUtility { + public static final double GRAVITY = 9.8; // �d�͂̉����x + public static final Vector3d horizon = new Vector3d(1.0, 0.0, 0.0); + public static final Vector3d vertical = new Vector3d(0.0, 1.0, 0.0); + + public static Vector3d gravityDirection = new Vector3d(0.0, 1.0, 0.0); + + /** + * ���̂ɉ����d�͂����߂� + * @param body �Ώە��� + * @return body�ɉ����d�� + */ + public static Force3D getGravity(Solid3D body) { + return new Force3D(gravityDirection.x * -body.mass * GRAVITY, gravityDirection.y * -body.mass * GRAVITY, gravityDirection.z * -body.mass * GRAVITY); + } + + /** + * @param v + * �F�P�ʃx�N�g���A���邢�̓[���x�N�g���������œn������ + */ + public static void setGravityDirection(Vector3d v) { + gravityDirection = new Vector3d(v.x, v.y, v.z); + } + + // ���[�����g�̌v�Z + static Vector3d calcMoment(Force3D f, Position3D gravityCenter, + Position3D applicationPoint) { + Vector3d v1 = applicationPoint.getVector3d(); + Vector3d v2 = gravityCenter.getVector3d(); + v1.sub(v2); + + Vector3d cv = new Vector3d(); + Vector3d fv = f.getVector3d(); + cv.cross(v1, fv); + return cv; + + } + + /** + * ���̂̔����W������Փˎ��ɉ����͂����߂� + * @param interval �Փ˂��Ă��鎞�� + * @param nor ���̂��Ԃ‚������ʂ̕��x�N�g�� + * @param solid ���� + * @return �Փˎ��ɉ����� + */ + public static Force3D calcForce(long interval, Vector3d nor, Solid3D solid) { + double f1 = 0.0; + Vector3d vf = new Vector3d(solid.getVelocity().getX(), solid + .getVelocity().getY(), solid.getVelocity().getZ()); + f1 = solid.mass * (vf.length() + solid.e * vf.length()) + / ((double) interval / 1000.0); + nor.scale(f1); + Force3D f = new Force3D(nor.x, nor.y, nor.z); + return f; + } + + /** + * ���̂ƒn�ʂƂ̏Փ˔��� + * @param obj ���� + * @param ground �n�� + * @return �Փˏ��inull�̂Ƃ��Փ˂Ȃ��j + */ + public static CollisionResult doesIntersect(Solid3D obj, Ground ground) { + if (ground == null) return null; + CollisionResult cr = null; + BoundingSurface boundingSurface = ground.getBoundingSurface(); + + // BoundingSphere���g���đ�G�c�ɏՓ˔�����s�� + ArrayList boundingSurfaceList = null; + if (obj.bs != null) { + BoundingSphere bs = (BoundingSphere) (obj.bs.clone()); + Transform3D t3d = new Transform3D(); + obj.center.getTransform(t3d); + bs.transform(t3d); + obj.scale.getTransform(t3d); + bs.transform(t3d); + obj.rot.getTransform(t3d); + bs.transform(t3d); + obj.pos.getTransform(t3d); + bs.transform(t3d); + // �e���Փ˔�����s���i�ŏ�ʂ�BoundingSurface��BoundingSphere�̊ԂŁj + boundingSurfaceList = boundingSurface.intersect(bs); + bs = null; + t3d = null; + } + + if (obj.bs == null) { + // BoundingSphere ���܂�����Ă��ȂȂ������ꍇ�A + // �ڍׂȏՓ˔���̂��߂ɁA�ŏ�ʂ̑S BoundingSurface ���擾���� + boundingSurfaceList.add(boundingSurface); + } + + if (boundingSurfaceList.size() > 0) { + // �e���Փ˔���ŏՓ˂��Ă����ꍇ�AOBB�̏W����p���Ă��ڂ����Փ˔�����s�� + // �iBoundingSphere ���܂�����Ă��Ȃ��ꍇ�AOBB �̍쐬�Ɠ����� BoundingSphere ���쐬�����j + BoundingBoxVisitor obbVisitor = new BoundingBoxVisitor(); + obj.accept(obbVisitor); + for (int i = 0; i < obbVisitor.getObbList().size(); i++) { + // OBB�ƏՓ˔��������ꍇ�́A�n�ʂ𑽊p�`�̂܂܈��� + for (int j = 0; j < boundingSurfaceList.size(); j++) { + cr = boundingSurfaceList.get(j).intersect(obbVisitor.getObbList().get(i)); + if (cr != null) { + return cr; + } + } + } + obbVisitor = null; + } + return null; + } + + /** + * ���̓��m�̏Փ˔��� + * @param obj1 ����1 + * @param part1 ���肷�镨��1�̕����̖��� + * @param obj2 ����2 + * @param part2 ���肷�镨��2�̕����̖��� + * @return�@�Փˏ��inull�̂Ƃ��Փ˂Ȃ��j + */ + public static CollisionResult checkCollision(Object3D obj1, String part1, + Object3D obj2, String part2) { + CollisionResult cr = null; + + // BoundingSphere���g���đ�G�c�ɏՓ˔�����s�� + boolean f = false; + if (obj1.bs != null && obj2.bs != null) { + // sol1 �� BoundingSphere�@���v�Z + BoundingSphere bs1 = (BoundingSphere) (obj1.bs.clone()); + Transform3D t3d = new Transform3D(); + obj1.center.getTransform(t3d); + bs1.transform(t3d); + obj1.scale.getTransform(t3d); + bs1.transform(t3d); + obj1.rot.getTransform(t3d); + bs1.transform(t3d); + obj1.pos.getTransform(t3d); + bs1.transform(t3d); + + // sol2 �� BoundingSphere�@���v�Z + BoundingSphere bs2 = (BoundingSphere) (obj2.bs.clone()); + obj2.center.getTransform(t3d); + bs2.transform(t3d); + obj2.scale.getTransform(t3d); + bs2.transform(t3d); + obj2.rot.getTransform(t3d); + bs2.transform(t3d); + obj2.pos.getTransform(t3d); + bs2.transform(t3d); + + // BoundingSphere ���m�̏Փ˔��� + if (bs1.intersect(bs2)) f = true; + t3d = null; + bs1 = null; + bs2 = null; + } + if (f || obj1.bs == null || obj2.bs == null) { + BoundingBoxVisitor visitor1 = new BoundingBoxVisitor(part1); + BoundingBoxVisitor visitor2 = new BoundingBoxVisitor(part2); + obj1.accept(visitor1); + obj2.accept(visitor2); + int i, j; + for (i = 0; i < visitor1.getObbList().size(); i++) { + for (j = 0; j < visitor2.getObbList().size(); j++) { + cr = visitor2.getObbList().get(j).intersect(visitor1.getObbList().get(i)); + if (cr != null) { + return cr; + } + } + } + } + return null; + } +} diff --git a/src/main/java/framework/physics/Solid3D.java b/src/main/java/framework/physics/Solid3D.java new file mode 100644 index 0000000..e3e28dc --- /dev/null +++ b/src/main/java/framework/physics/Solid3D.java @@ -0,0 +1,171 @@ +package framework.physics; + +import java.util.ArrayList; + +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Vector3d; + +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; + +/** + * �����I�ȐU�镑�������镨�́i���́j��\�� + * @author �V�c���� + * + */ +public class Solid3D extends Object3D { + private Velocity3D velocity; + private AngularVelocity3D angularvelocity; + private Position3D gravityCenter = getPosition3D(); + public double e = 1.0; + public double mass = 10; + private Inertia3D inertia = null; + + // �R�s�[�R���X�g���N�^ + public Solid3D(Object3D obj) { + super(obj); + velocity = new Velocity3D(); + quaternion = new Quaternion3D(); + angularvelocity = new AngularVelocity3D(); + inertia = new Inertia3D(this); + } + + public Solid3D(Object3D obj, double mass) { + super(obj); + velocity = new Velocity3D(); + quaternion = new Quaternion3D(); + angularvelocity = new AngularVelocity3D(); + this.mass = mass; + inertia = new Inertia3D(this); + } + + public Solid3D(Solid3D solid) { + super(solid); + velocity = new Velocity3D(solid.velocity); + quaternion = new Quaternion3D(solid.getQuaternion()); + angularvelocity = new AngularVelocity3D(solid.angularvelocity); + mass = solid.mass; + inertia = new Inertia3D(this); + } + + /** + * �͊w�^���̌v�Z�i�����͂�1�‚̏ꍇ�j + * @param interval �P�ʎ��� + * @param f �� + * @param applicationPoint �͂̍�p�_ + */ + public void move(long interval, Force3D f, Position3D applicationPoint) { + // ���[�����g�̌v�Z + Vector3d moment = PhysicsUtility.calcMoment(f, getGravityCenter(), + applicationPoint); + moveSub(interval, f, moment); + } + + /** + * �͊w�^���̌v�Z�i�����ɕ����̗͂������ꍇ�j + * @param interval �P�ʎ��� + * @param forces �́i�����j + * @param appPoints ���ꂼ��̗͂̍�p�_ + */ + public void move(long interval, ArrayList forces, + ArrayList appPoints) { + // �d�S�ɉ����͂̍��v�����߂� + Force3D f = new Force3D(0.0, 0.0, 0.0); + for (int n = 0; n < forces.size(); n++) { + f.add(forces.get(n)); + } + + // ���[�����g�̍��v���v�Z���� + Position3D gc = getGravityCenter(); + Vector3d moment = new Vector3d(0.0, 0.0, 0.0); + for (int n2 = 0; n2 < forces.size(); n2++) { + moment.add(PhysicsUtility.calcMoment(forces.get(n2), gc, appPoints.get(n2))); + } + moveSub(interval, f, moment); + } + + private void moveSub(long interval, Force3D f, Vector3d moment) { + // 1.�d�S�̉^���������i�j���[�g���������j + // �����x�A���x�v�Z + Vector3d deltaV = f.getVector3d(); // �̓x�N�g���̎擾 + deltaV.scale(1.0 / mass * ((double) interval / 1000.0)); // �����x���瑬�x�̍������v�Z + Velocity3D v = getVelocity().add(deltaV); // ���x�ɍ��������Z + apply(v, false); + + // �d�S�ʒu�v�Z + Vector3d deltaP = velocity.getVector3d(); // ���x�x�N�g���̎擾 + deltaP.scale(((double) interval / 1000.0)); + Position3D p = getPosition3D().add(deltaP); // �ʒu�ɍ��������Z + apply(p, false); + + // 2.�I�C���[�̊p�^�������� + + // �p�����x�A�p���x�v�Z + AngularVelocity3D w = getAngularVelocity(); + Vector3d deltaAngularV = new Vector3d( + (moment.x + (inertia.iyy - inertia.izz) * w.getY() * w.getZ()) / inertia.ixx, + (moment.y + (inertia.izz - inertia.ixx) * w.getZ() * w.getX()) / inertia.iyy, + (moment.z + (inertia.ixx - inertia.iyy) * w.getX() * w.getY()) / inertia.izz); + deltaAngularV.scale((double) interval / 1000.0); + w.add(deltaAngularV); + apply(w, false); + + // �p���x�ɂ���]�v�Z + AxisAngle4d axisAngle = w.getAxisAngle4d(); + axisAngle.angle *= ((double) interval / 1000.0); + Quaternion3D q = getQuaternion().add(axisAngle); + apply(q, false); + } + + // ��������� + public Object3D duplicate() { + Object3D copy = new Solid3D(this); + return copy; + } + + public void scale(double s) { + super.scale(s); + inertia = new Inertia3D(this); + } + + public void scale(double sx, double sy, double sz) { + super.scale(sx, sy, sz); + inertia = new Inertia3D(this); + } + + public Velocity3D getVelocity() { + return (Velocity3D) velocity.clone(); + } + + public AngularVelocity3D getAngularVelocity() { + return (AngularVelocity3D) angularvelocity.clone(); + } + + // Velocity3D �� applyTo �ȊO����͌Ă΂Ȃ����� + void setVelocity(Velocity3D v) { + velocity = (Velocity3D) v.clone(); + } + + // AngularVelocity3D �� applyTo �ȊO����͌Ă΂Ȃ����� + void setAngularVelocity(AngularVelocity3D w) { + angularvelocity = (AngularVelocity3D) w.clone(); + } + + public void setGravityCenter(Position3D gravityCenter) { + this.gravityCenter = gravityCenter; + } + + public Position3D getGravityCenter() { + return getPosition3D().add(gravityCenter); + } + + public void setMass(double mass) { + this.mass = mass; + } + + public double getMass() { + return mass; + } + +} diff --git a/src/main/java/framework/physics/Velocity3D.java b/src/main/java/framework/physics/Velocity3D.java new file mode 100644 index 0000000..7af9315 --- /dev/null +++ b/src/main/java/framework/physics/Velocity3D.java @@ -0,0 +1,148 @@ +package framework.physics; +import javax.media.j3d.Transform3D; +import javax.vecmath.Vector3d; + +import framework.model3D.Object3D; +import framework.model3D.Property3D; + + +public class Velocity3D extends Property3D { + private double x; + private double y; + private double z; + + public Velocity3D(Velocity3D v) { + x = v.x; + y = v.y; + z = v.z; + } + + public Velocity3D(Vector3d v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } + + public Velocity3D(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Velocity3D() { + x = 0.0; + y = 0.0; + z = 0.0; + } + + public void applyTo(Object3D o) { + ((Solid3D)o).setVelocity(this); + } + + public double getX() { + // TODO Auto-generated method stub + return this.x; + } + + public double getY() { + // TODO Auto-generated method stub + return this.y; + } + + public double getZ() { + // TODO Auto-generated method stub + return this.z; + } + + public Velocity3D setX(double x) { + // TODO Auto-generated method stub + this.x = x; + return this; + } + + public Velocity3D setY(double y) { + // TODO Auto-generated method stub + this.y = y; + return this; + } + + public Velocity3D setZ(double z) { + // TODO Auto-generated method stub + this.z = z; + return this; + } + + public Velocity3D add(double x, double y, double z){ + this.x += x; + this.y += y; + this.z += z; + return this; + } + + public Velocity3D add(Vector3d v) { + // TODO Auto-generated method stub + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + } + + public Velocity3D setVector3d(Vector3d v) { + x = v.x; + y = v.y; + z = v.z; + return this; + } + + public Vector3d getVector3d() { + return new Vector3d(x,y,z); + } + + @Override + public Property3D clone() { + // TODO Auto-generated method stub + return new Velocity3D(this); + } + + public Velocity3D rotX(double a) { + Vector3d v = getVector3d(); + Transform3D rotX = new Transform3D(); + rotX.rotX(a); + rotX.transform(v); + setVector3d(v); + return this; + } + + public Velocity3D rotY(double a) { + Vector3d v = getVector3d(); + Transform3D rotY = new Transform3D(); + rotY.rotY(a); + rotY.transform(v); + setVector3d(v); + return this; + } + + public Velocity3D rotZ(double a) { + Vector3d v = getVector3d(); + Transform3D rotZ = new Transform3D(); + rotZ.rotZ(a); + rotZ.transform(v); + setVector3d(v); + return this; + } + + public Velocity3D setVelocity(double velocity) { + Vector3d v = getVector3d(); + double oldV = v.length(); + v.scale(velocity / oldV); + setVector3d(v); + return this; + } + + public Velocity3D mul(double d) { + this.x *= d; + this.y *= d; + this.z *= d; + return this; + } +} diff --git a/src/main/java/framework/scenario/Event.java b/src/main/java/framework/scenario/Event.java new file mode 100644 index 0000000..9b97c8d --- /dev/null +++ b/src/main/java/framework/scenario/Event.java @@ -0,0 +1,15 @@ +package framework.scenario; + +import java.util.ArrayList; + +public class Event { + private String name; + + public Event(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/framework/scenario/FSM.java b/src/main/java/framework/scenario/FSM.java new file mode 100644 index 0000000..3b83351 --- /dev/null +++ b/src/main/java/framework/scenario/FSM.java @@ -0,0 +1,38 @@ +package framework.scenario; + +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; + +public class FSM { + private State initialState = null; + protected State currentState = null; + private Hashtable states = new Hashtable(); + + public FSM(State initialState, Hashtable states) { + this.initialState = initialState; + this.states = states; + currentState = initialState; + Collection allStates = states.values(); + Iterator it = allStates.iterator(); + while (it.hasNext()) { + State s = it.next(); + s.setOwner(this); + } + } + + public void addState(String stateName, State s) { + states.put(stateName, s); + s.setOwner(this); + } + + public boolean trans(Event e) { + currentState = currentState.getSuccessor(e); + if (currentState == null) return false; + return true; + } + + public State getCurrentState() { + return currentState; + } +} diff --git a/src/main/java/framework/scenario/IWorld.java b/src/main/java/framework/scenario/IWorld.java new file mode 100644 index 0000000..6e506d8 --- /dev/null +++ b/src/main/java/framework/scenario/IWorld.java @@ -0,0 +1,10 @@ +package framework.scenario; + +public interface IWorld { + abstract public void dialogOpen(); + abstract public void dialogClose(); + abstract public void dialogMessage(String message); + abstract public void showOption(int n, String option); + abstract public boolean isDialogOpen(); + abstract public void action(String action, Event event, ScenarioState nextState); +} diff --git a/src/main/java/framework/scenario/ScenarioAction.java b/src/main/java/framework/scenario/ScenarioAction.java new file mode 100644 index 0000000..22651e9 --- /dev/null +++ b/src/main/java/framework/scenario/ScenarioAction.java @@ -0,0 +1,13 @@ +package framework.scenario; + +public class ScenarioAction { + private String name; + + public ScenarioAction(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/framework/scenario/ScenarioFSM.java b/src/main/java/framework/scenario/ScenarioFSM.java new file mode 100644 index 0000000..1f67517 --- /dev/null +++ b/src/main/java/framework/scenario/ScenarioFSM.java @@ -0,0 +1,21 @@ +package framework.scenario; + +import java.util.Hashtable; + +public class ScenarioFSM extends FSM { + ScenarioManager manager; + + public ScenarioFSM(State initialState, Hashtable states, ScenarioManager manager) { + super(initialState, states); + this.manager = manager; + } + + public boolean trans(Event e) { + e = ((ScenarioState)currentState).canTrans(e); + if (e == null) return false; + ScenarioAction action = ((ScenarioState)currentState).getAction(e); + boolean result = super.trans(e); + manager.action(action, e, (ScenarioState)currentState); + return result; + } +} diff --git a/src/main/java/framework/scenario/ScenarioManager.java b/src/main/java/framework/scenario/ScenarioManager.java new file mode 100644 index 0000000..44b2bd5 --- /dev/null +++ b/src/main/java/framework/scenario/ScenarioManager.java @@ -0,0 +1,183 @@ +package framework.scenario; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; +import java.util.Map.Entry; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.helpers.DefaultHandler; + +public class ScenarioManager { + private IWorld realWorld; + private Hashtable stateMachines = new Hashtable(); + private Hashtable allStates = new Hashtable(); + private Hashtable allEvents = new Hashtable(); + + public ScenarioManager(String xmlFileName, IWorld realWorld) { + this.realWorld = realWorld; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + factory.setValidating(true); + factory.setAttribute( + "http://java.sun.com/xml/jaxp/properties/schemaLanguage", + "http://www.w3.org/2001/XMLSchema"); + + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setErrorHandler(new DefaultHandler()); + Document document = builder.parse(xmlFileName); + + // �L����ԃ}�V���̍쐬�A��Ԃ̓o�^�A�C�x���g�̓o�^ + Hashtable allTrans = new Hashtable(); + NodeList scenario = document.getChildNodes(); + NodeList fsmNodes = scenario.item(0).getChildNodes(); + for (int n = 0; n < fsmNodes.getLength(); n++) { + Node fsmNode = fsmNodes.item(n); + if (fsmNode.getNodeName().equals("FSM")) { + Hashtable fsmStates = new Hashtable(); + NodeList stateNodes = fsmNode.getChildNodes(); + for (int m = 0; m < stateNodes.getLength(); m++) { + Node stateNode = stateNodes.item(m); + if (stateNode.getNodeName().equals("State")) { + ScenarioState state = new ScenarioState(); + String stateName = stateNode.getAttributes().getNamedItem("name").getNodeValue(); + fsmStates.put(stateName, state); + allStates.put(stateName, state); + Node stateMessageNode = stateNode.getAttributes().getNamedItem("message"); + if (stateMessageNode != null) state.setMessage(stateMessageNode.getNodeValue()); + NodeList eventNodes = stateNode.getChildNodes(); + allTrans.put(state, eventNodes); + for (int l = 0; l < eventNodes.getLength(); l++) { + Node eventNode = eventNodes.item(l); + if (eventNode.getNodeName().equals("Event")) { + String eventName = eventNode.getAttributes().getNamedItem("name").getNodeValue(); + Event e = allEvents.get(eventName); + if (e == null) { + e = new Event(eventName); + allEvents.put(eventName, e); + } + } + } + } + } + String initialStateName = fsmNode.getAttributes().getNamedItem("initial").getNodeValue(); + State initialState = fsmStates.get(initialStateName); + ScenarioFSM fsm = new ScenarioFSM(initialState, fsmStates, this); + String fsmName = fsmNode.getAttributes().getNamedItem("name").getNodeValue(); + stateMachines.put(fsmName, fsm); + } + } + + // ��ԑJ�ڂ�ݒ肷�� + Set> allTransEntries = allTrans.entrySet(); + Iterator> it = allTransEntries.iterator(); + while (it.hasNext()) { + Entry transEntry = it.next(); + ScenarioState state = transEntry.getKey(); + NodeList eventNodes = transEntry.getValue(); + for (int l = 0; l < eventNodes.getLength(); l++) { + Node eventNode = eventNodes.item(l); + if (eventNode.getNodeName().equals("Event")) { + Node eventNameNode = eventNode.getAttributes().getNamedItem("name"); + Event e = null; + if (eventNameNode != null) { + String eventName = eventNameNode.getNodeValue(); + e = allEvents.get(eventName); + } + Node nextStateNameNode = eventNode.getAttributes().getNamedItem("trans"); + State nextState = null; + if (nextStateNameNode != null) { + String nextStateName = nextStateNameNode.getNodeValue(); + nextState = allStates.get(nextStateName); + } + Node syncEventNameNode = eventNode.getAttributes().getNamedItem("sync"); + Event syncEvent = null; + if (syncEventNameNode != null) { + String syncEventName = syncEventNameNode.getNodeValue(); + syncEvent = allEvents.get(syncEventName); + } + ArrayList guards = new ArrayList(); + Node guardStateNameNode = eventNode.getAttributes().getNamedItem("guard"); + if (guardStateNameNode != null) { + String guardStateName = guardStateNameNode.getNodeValue(); + State guardState = allStates.get(guardStateName); + if (guardState != null) guards.add(guardState); + } + Node guardStateNameNode2 = eventNode.getAttributes().getNamedItem("guard2"); + if (guardStateNameNode2 != null) { + String guardStateName2 = guardStateNameNode2.getNodeValue(); + State guardState2 = allStates.get(guardStateName2); + if (guardState2 != null) guards.add(guardState2); + } + Node guardStateNameNode3 = eventNode.getAttributes().getNamedItem("guard3"); + if (guardStateNameNode3 != null) { + String guardStateName3 = guardStateNameNode3.getNodeValue(); + State guardState3 = allStates.get(guardStateName3); + if (guardState3 != null) guards.add(guardState3); + } + Node actionNameNode = eventNode.getAttributes().getNamedItem("action"); + ScenarioAction action = null; + if (actionNameNode != null) { + String actionName = actionNameNode.getNodeValue(); + action = new ScenarioAction(actionName); + } + state.addTransition(e, nextState, syncEvent, guards, action); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void fire(Event e){ + Collection fsms = stateMachines.values(); + Iterator it = fsms.iterator(); + while (it.hasNext()) { + ScenarioFSM fsm = it.next(); + fsm.trans(e); + } + } + + public void fire(String eventName) { + Event e = allEvents.get(eventName); + if (e == null) return; + fire(e); + } + + public void action(ScenarioAction action, Event event, ScenarioState nextState) { + if (action != null) { + String sAction = action.getName(); + if (sAction.equals("openDialog")) { + realWorld.dialogOpen(); + } else if (sAction.equals("closeDialog")) { + realWorld.dialogClose(); + } else if (sAction.equals("print")) { + System.out.println(event.getName()); + } + realWorld.action(sAction, event, nextState); + } + if (realWorld.isDialogOpen()) { + String message = nextState.getMessage(); + if (message != null) { + realWorld.dialogMessage(message); + Enumeration events = nextState.getEvents(); + int n = 0; + while (events.hasMoreElements()) { + Event ev = events.nextElement(); + realWorld.showOption(n, ev.getName()); + n++; + } + } + } + } +} diff --git a/src/main/java/framework/scenario/ScenarioState.java b/src/main/java/framework/scenario/ScenarioState.java new file mode 100644 index 0000000..f2d782a --- /dev/null +++ b/src/main/java/framework/scenario/ScenarioState.java @@ -0,0 +1,70 @@ +package framework.scenario; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; +import java.util.Map.Entry; + +public class ScenarioState extends State { + private Hashtable transitionSyncs = new Hashtable(); + private Hashtable> transitionGuards = new Hashtable>(); + private Hashtable transitionActions = new Hashtable(); + private String message = null; + + public ScenarioState() { + super(); + } + + public ScenarioState(Hashtable transitions, + Hashtable transitionSyncs, + Hashtable> transitionGuards, + Hashtable transitionActions, + String message) { + super(transitions); + this.transitionSyncs = transitionSyncs; + this.transitionGuards = transitionGuards; + this.transitionActions = transitionActions; + this.message = message; + } + + public void addTransition(Event event, State succ, Event syncEvent, ArrayList guards, ScenarioAction action) { + addTransition(event, succ); + if (syncEvent != null) transitionSyncs.put(event, syncEvent); + if (guards != null) transitionGuards.put(event, guards); + if (action != null) transitionActions.put(event, action); + } + + Event canTrans(Event event) { + Enumeration events = getEvents(); + while (events.hasMoreElements()) { + Event e = events.nextElement(); + if (event == e || event == transitionSyncs.get(e)) { + ArrayList guardStates = transitionGuards.get(e); + boolean bSatisfyGuard = true; + for (int n = 0; n < guardStates.size(); n++) { + State s = guardStates.get(n); + if (s.getOwner().getCurrentState() != s) { + bSatisfyGuard = false; + break; + } + } + if (bSatisfyGuard) return e; + } + } + return null; + } + + public ScenarioAction getAction(Event e) { + return transitionActions.get(e); + } + + public void setMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/framework/scenario/State.java b/src/main/java/framework/scenario/State.java new file mode 100644 index 0000000..9cbc80e --- /dev/null +++ b/src/main/java/framework/scenario/State.java @@ -0,0 +1,37 @@ +package framework.scenario; + +import java.util.Enumeration; +import java.util.Hashtable; + +public class State { + private FSM owner = null; + private Hashtable transitions = new Hashtable(); + + public State() { + } + + public State(Hashtable transitions) { + this.transitions = transitions; + } + + public void addTransition(Event e, State s) { + transitions.put(e, s); + } + + public Enumeration getEvents() { + return transitions.keys(); + } + + public State getSuccessor(Event e) { + if (!transitions.containsKey(e)) return null; + return transitions.get(e); + } + + public void setOwner(FSM fsm) { + owner = fsm; + } + + public FSM getOwner() { + return owner; + } +} diff --git a/src/main/java/framework/schedule/ScheduleManager.java b/src/main/java/framework/schedule/ScheduleManager.java new file mode 100644 index 0000000..202e031 --- /dev/null +++ b/src/main/java/framework/schedule/ScheduleManager.java @@ -0,0 +1,28 @@ +package framework.schedule; + +import java.util.Hashtable; + +public class ScheduleManager { + private static ScheduleManager theInstance = null; + private Hashtable taskControllerTable = new Hashtable(); + + private ScheduleManager() { + } + + public static ScheduleManager getInstance() { + if (theInstance == null) { + theInstance = new ScheduleManager(); + } + return theInstance; + } + + public TaskController registerTask(String taskName) { + TaskController controller = new TaskController(); + taskControllerTable.put(taskName, controller); + return controller; + } + + public TaskController getController(String taskName) { + return taskControllerTable.get(taskName); + } +} diff --git a/src/main/java/framework/schedule/TaskController.java b/src/main/java/framework/schedule/TaskController.java new file mode 100644 index 0000000..1722e1a --- /dev/null +++ b/src/main/java/framework/schedule/TaskController.java @@ -0,0 +1,37 @@ +package framework.schedule; + +public class TaskController { + private boolean bActive = false; + + synchronized public boolean activate() { + if (isActive()) return false; + setActive(true); + return true; + } + synchronized public void deactivate() { + synchronized(this) { + notify(); + } + setActive(false); + } + + synchronized public void waitForActivation() { + if (!isActive()) return; + try { + synchronized(this) { + wait(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + setActive(false); // �s�v��������Ȃ� + } + + private boolean isActive() { + return bActive; + } + + private void setActive(boolean flag) { + bActive = flag; + } +} diff --git a/src/main/java/framework/test/TestAnimation.java b/src/main/java/framework/test/TestAnimation.java new file mode 100644 index 0000000..30b8627 --- /dev/null +++ b/src/main/java/framework/test/TestAnimation.java @@ -0,0 +1,259 @@ +package framework.test; + +import java.awt.Component; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Texture; +import javax.media.j3d.Texture2D; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.animation.PartAnimation; +import framework.animation.Pose3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +public class TestAnimation { + + /** + * @param args + */ + public TestAnimation() { + // TODO Auto-generated method stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + +// Model3D model = ModelFactory.loadModel("data\\Head4.wrl"); + Model3D model = ModelFactory.loadModel("data\\pocha\\pocha.wrl"); + Object3D obj = model.createObject(); + Transform3D s = new Transform3D(); + ((Object3D)obj.children[0]).scale.setTransform(s); + + // --- ��������A�e�N�X�`������ւ��̃e�X�g�p�R�[�h +// BufferedImage image1 = null, image2 = null, image3 = null; +// try { +// image1 = ImageIO.read(new File("data\\black.jpg")); +// image2 = ImageIO.read(new File("data\\gray.jpg")); +// image3 = ImageIO.read(new File("data\\white.jpg")); +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// Object3D body = obj.getPart("Body"); +// Shape3D shape = body.children[0].getShape3D(); +// shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); +// shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); +// if (true) { +// // Appearance�ȉ��A�S���ݒ� +// Appearance ap = new Appearance(); +// Texture texture; +// // �e�N�X�`�����[�_���g�p �� ���܂������� +// TextureLoader loader = new TextureLoader("data\\gray.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// texture = loader.getTexture(); +// texture.setCapability(Texture.ALLOW_IMAGE_READ); +// texture.setCapability(Texture.ALLOW_IMAGE_WRITE); +// ap.setTexture(texture); +// shape.setAppearance(ap); +// } else if (true) { +// // Appearance�͍ė��p�ATexture�ȉ��A�S���ݒ� +// Texture texture; +// if (false) { +// // �e�N�X�`�����[�_���g�p �� ���܂������� +// TextureLoader loader = new TextureLoader("data\\gray.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, frame.getComponent(0)); +// texture = loader.getTexture(); +// texture.setCapability(Texture.ALLOW_IMAGE_READ); +// texture.setCapability(Texture.ALLOW_IMAGE_WRITE); +// } else if (true) { +// // �e�N�X�`�����[�_�̃C���[�W�̂ݎg�p�A�e�N�X�`���͍쐬 �� �C���[�W�T�C�Y�̖��ł��܂������Ȃ��悤���i�C���[�W��256x128�ɂ���H�j +// TextureLoader loader = new TextureLoader("data\\gray.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, frame.getComponent(0)); +// ImageComponent2D ic = loader.getImage(); +// ic.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); +// ic.setCapability(ImageComponent2D.ALLOW_FORMAT_READ); +// ic.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); +// texture = new Texture2D(Texture.BASE_LEVEL, +// Texture.RGB, +// image2.getWidth(), +// image2.getHeight()); +// texture.setCapability(Texture.ALLOW_IMAGE_READ); +// texture.setCapability(Texture.ALLOW_IMAGE_WRITE); +// texture.setImage(0, ic); +// } else { +// texture = new Texture2D(Texture.BASE_LEVEL, +// Texture.RGB, +// image2.getWidth(), +// image2.getHeight()); +// texture.setCapability(Texture.ALLOW_IMAGE_READ); +// texture.setCapability(Texture.ALLOW_IMAGE_WRITE); +// ImageComponent2D ic = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, +// image2, +// true, +// true); +// ic.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); +// ic.setCapability(ImageComponent2D.ALLOW_FORMAT_READ); +// ic.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); +// // Mipmap���x����0�̂� +// texture.setImage(0, ic); +// } +// shape.getAppearance().setTexture(texture); +// } else { +// shape.getAppearance().setCapability(Appearance.ALLOW_TEXTURE_READ); +// shape.getAppearance().setCapability(Appearance.ALLOW_TEXTURE_WRITE); +// shape.getAppearance().getTexture().setCapability(Texture.ALLOW_IMAGE_READ); +// shape.getAppearance().getTexture().setCapability(Texture.ALLOW_IMAGE_WRITE); +// shape.getAppearance().getTexture().getImage(0).setCapability(ImageComponent2D.ALLOW_FORMAT_READ); +// shape.getAppearance().getTexture().getImage(0).setCapability(ImageComponent2D.ALLOW_IMAGE_READ); +// shape.getAppearance().getTexture().getImage(0).setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); +// ((ImageComponent2D)shape.getAppearance().getTexture().getImage(0)).set(image1); +// } + // --- �����܂ŁA�e�N�X�`������ւ��̃e�X�g�p�R�[�h + + Universe universe = new Universe(); + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(0.0, 0.0, 10.0)); + camera.adjust(0L); + canvas.attachCamera(camera); + + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.placeLight(light); + + universe.place(obj); + universe.compile(); + + frame.setSize(720, 480); + frame.setVisible(true); + + // //Pose3D�̃e�X�g + // Pose3D pose = new Pose3D(); + // Position3D pos = new Position3D(0.0, 1.0, 0.0); + // Quaternion3D quat = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 4.0); + // pose.addPose("ArmL", pos, quat); + // + // Position3D pos1 = new Position3D(1.0, 0.0, 0.0); + // Quaternion3D quat1 = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 2.0); + // pose.addPose("ArmR", pos1, quat1); + // + // Position3D pos2 = new Position3D(0.0, 1.0, 0.0); + // Quaternion3D quat2 = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 4.0); + // pose.addPose("obj1", pos2, quat2); + // + // Position3D pos3 = new Position3D(0.0, 1.0, 0.0); + // Quaternion3D quat3 = new Quaternion3D(0.0, 1.0, 1.0, Math.PI / 3.0); + // pose.addPose("obj2", pos3, quat3); + // + // Position3D pos4 = new Position3D(0.0, 0.0, 1.0); + // Quaternion3D quat4 = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 4.0); + // pose.addPose("obj3", pos4, quat4); + // + // Position3D pos5 = new Position3D(0.0, 1.0, 1.0); + // Quaternion3D quat5 = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 4.0); + // pose.addPose("obj4", pos5, quat5); + // + // Position3D pos6 = new Position3D(1.0, 1.0, 0.0); + // Quaternion3D quat6 = new Quaternion3D(0.0, 0.0, 1.0, Math.PI / 4.0); + // pose.addPose("obj5", pos6, quat6); + // // obj.apply(pose); + // + // //Animation3D�̃e�X�g + // Animation3D animation = new Animation3D(); + // + // PartAnimation pa1 = new PartAnimation("ArmL"); + // pa1.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa1.add(10000, pos, quat); + // animation.addPartAnimation(pa1); + // + // PartAnimation pa2 = new PartAnimation("ArmR"); + // pa2.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa2.add(10000, pos, quat); + // animation.addPartAnimation(pa2); + // + // PartAnimation pa3 = new PartAnimation("obj1"); + // pa3.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa3.add(10000, pos, quat); + // animation.addPartAnimation(pa3); + // + // PartAnimation pa4 = new PartAnimation("obj2"); + // pa4.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa4.add(10000, pos, quat); + // animation.addPartAnimation(pa4); + // + // PartAnimation pa5 = new PartAnimation("obj3"); + // pa5.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa5.add(10000, pos, quat); + // animation.addPartAnimation(pa5); + // + // PartAnimation pa6 = new PartAnimation("obj4"); + // pa6.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa6.add(10000, pos, quat); + // animation.addPartAnimation(pa6); + // + // PartAnimation pa7 = new PartAnimation("obj5"); + // pa7.add(0, new Position3D(0.0, 0.0, 0.0), new Quaternion3D()); + // pa7.add(10000, pos, quat); + // animation.addPartAnimation(pa7); + +// // �e�N�X�`���A�j���[�V�����̃e�X�g +// Animation3D animation = new Animation3D(); +// PartAnimation pa = new PartAnimation("Body"); +// TextureLoader loader1 = new TextureLoader("data\\white.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture texture1 = loader1.getTexture(); +// TextureLoader loader2 = new TextureLoader("data\\gray.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture texture2 = loader2.getTexture(); +// TextureLoader loader3 = new TextureLoader("data\\black.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture texture3 = loader3.getTexture(); +// pa.addTexture(0, texture1, new Position3D()); +// pa.addTexture(100, texture2, new Position3D(0.4, 0.0, 0.0)); +// pa.addTexture(200, texture3, new Position3D(0.8, 0.0, 0.0)); +// pa.addTexture(300, texture2, new Position3D(0.4, 0.0, 0.0)); +// pa.addTexture(400, texture1, new Position3D()); +// animation.addPartAnimation(pa); + + // �A�j���[�V�����t�@�C���ǂݍ��݂̃e�X�g +// Animation3D animation = AnimationFactory +// .loadAnimation("data\\character\\walk.wrl"); + Animation3D animation = AnimationFactory.loadAnimation("data\\pocha\\jump.wrl"); + + for (;;) { + try { + Thread.sleep(1); + boolean b = animation.progress(1); + System.out.println(animation.time); + // if (b == false) break; + Pose3D pose2 = animation.getPose(); + obj.apply(pose2, false); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + new TestAnimation(); + } +} diff --git a/src/main/java/framework/test/TestBrick.java b/src/main/java/framework/test/TestBrick.java new file mode 100644 index 0000000..09a591a --- /dev/null +++ b/src/main/java/framework/test/TestBrick.java @@ -0,0 +1,180 @@ +package framework.test; + +import java.awt.Component; +import java.util.ArrayList; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.Node; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Stage; +import fight3D.StageManager; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.BaseObject3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.AngularVelocity3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicalSystem; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestBrick { + static final double GRAVITY = 9.8; + + + public TestBrick() { + + long oldTime = System.currentTimeMillis(); +// public ArrayList arraylist = new ArrayList(); + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Universe universe = new Universe(); + + + + PhysicalSystem p_solid = new PhysicalSystem(); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + canvas.attachCamera(camera); + + // ���C�g�̐ݒ� + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, -1.0f, -0.1f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 50000.0)); + universe.placeLight(light); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �X�e�[�W�̐ݒ� +// Object3D stageObject = ModelFactory.loadModel("data\\floor4.3ds").createObject(); +// stageObject = ModelFactory.loadModel("data\\stage3\\stage3.wrl").createObject(); + IndexedTriangleArray groundGeometry = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS, 6); + groundGeometry.setCoordinate(0, new Point3d(-1000.0, 0.0, -1000.0)); + groundGeometry.setCoordinate(1, new Point3d(1000.0, 0.0, -1000.0)); + groundGeometry.setCoordinate(2, new Point3d(1000.0, 0.0, 1000.0)); + groundGeometry.setCoordinate(3, new Point3d(-1000.0, 0.0, 1000.0)); + groundGeometry.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setCoordinateIndices(0, new int[]{0, 3, 2}); + groundGeometry.setCoordinateIndices(3, new int[]{0, 2, 1}); + Appearance ap2 = new Appearance(); + Material m = new Material(); + m.setDiffuseColor(1.0f, 1.0f, 1.0f); + m.setAmbientColor(0.5f, 0.5f, 0.5f); + m.setSpecularColor(0.0f, 0.0f, 0.0f); + m.setShininess(1.0f); + ap2.setMaterial(m); + ap2.setColoringAttributes(new ColoringAttributes(0.5f, 0.5f, 0.5f, ColoringAttributes.NICEST)); + BaseObject3D stageObject = new BaseObject3D(groundGeometry, ap2); + Ground stageGround = new Ground(stageObject); + + // �I�u�W�F�N�g�̐ݒ� + Model3D model = ModelFactory.loadModel("data\\cubeBlue.3ds"); + Object3D objBlue = model.createObject(); + Model3D model2 = ModelFactory.loadModel("data\\cubeRed.3ds"); + Object3D objRed = model2.createObject(); + Transform3D s = new Transform3D(); + objBlue.children[0].scale.setTransform(s); + + int ARRAY_SIZE_X = 5; + int ARRAY_SIZE_Y = 5; + int ARRAY_SIZE_Z = 5; + + for(int k = 0 ; k < ARRAY_SIZE_Y ; k++){ + for(int l = 0 ; l < ARRAY_SIZE_X ; l++){ + for(int j = 0 ; j < ARRAY_SIZE_Z ; j++){ + + Solid3D solid; + if((j + k + l) % 2 == 0){ + solid = new Solid3D(objBlue); + } else { + solid = new Solid3D(objRed); + } + + solid.apply(new Position3D(-5.0 + 2.0*l, 1.0+2.0*k, -5.0+2.0*j), false); + + solid.scale(2.0, 2.0, 2.0); +//// Quaternion3D q = new Quaternion3D(0.0, 0, 1.0, 0.7); +//// solid.apply(q, false); +// solid.apply(new AngularVelocity3D(-0.1, 0.0, -0.2), false); + universe.place(solid); + + camera.addTarget(solid); + + p_solid.add(solid); + } + } + } + + universe.place(stageGround); + + // �\�� + universe.compile(); + + // CollisionResult cr = new CollisionResult(); + // cr = PhysicsFacade.checkColision(solid, solid, solid2, solid2); + + int id = 0; + + for (;;) { + try { + Thread.sleep(1); + camera.adjust(0); + // w.move(17, stageObject); + Force3D f = Force3D.ZERO; +// if (solid.getPosition3D().getY() > -0.1) { +// // System.out.println(time+","+solid.getPosition3D().getY()); +// +// } + long newTime = System.currentTimeMillis(); +// p_solid.motion(id, 3, f, p_solid.objects.get(id) +// .getGravityCenter(), stageGround); + p_solid.motion(id, newTime - oldTime, f, p_solid.objects.get(id) + .getGravityCenter(), stageGround); + oldTime = newTime; + // if(cr != null){ + // p_solid.move(id, 1, f, cr.collisionPoint, stageObject); + // } + // else{ + // p_solid.move(id, 1, f, + // p_solid.objects.get(id).getGravityCenter(), stageObject); + // ) + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +// time++; + } + + } + + public static void main(String[] args) { + new TestBrick(); + } +} diff --git a/src/main/java/framework/test/TestDice.java b/src/main/java/framework/test/TestDice.java new file mode 100644 index 0000000..504eeed --- /dev/null +++ b/src/main/java/framework/test/TestDice.java @@ -0,0 +1,180 @@ +package framework.test; + +import java.awt.Component; +import java.util.ArrayList; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.Node; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Stage; +import fight3D.StageManager; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.BaseObject3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.AngularVelocity3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicalSystem; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestDice { + static final double GRAVITY = 9.8; + + + public TestDice() { + + long oldTime = System.currentTimeMillis(); +// public ArrayList arraylist = new ArrayList(); + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Universe universe = new Universe(); + + + + PhysicalSystem p_solid = new PhysicalSystem(); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + canvas.attachCamera(camera); + + // ���C�g�̐ݒ� + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, -1.0f, -0.1f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 50000.0)); + universe.placeLight(light); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �X�e�[�W�̐ݒ� +// Object3D stageObject = ModelFactory.loadModel("data\\floor4.3ds").createObject(); +// stageObject = ModelFactory.loadModel("data\\stage3\\stage3.wrl").createObject(); + IndexedTriangleArray groundGeometry = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS, 6); + groundGeometry.setCoordinate(0, new Point3d(-1000.0, 0.0, -1000.0)); + groundGeometry.setCoordinate(1, new Point3d(1000.0, 0.0, -1000.0)); + groundGeometry.setCoordinate(2, new Point3d(1000.0, 0.0, 1000.0)); + groundGeometry.setCoordinate(3, new Point3d(-1000.0, 0.0, 1000.0)); + groundGeometry.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setCoordinateIndices(0, new int[]{0, 3, 2}); + groundGeometry.setCoordinateIndices(3, new int[]{0, 2, 1}); + Appearance ap2 = new Appearance(); + Material m = new Material(); + m.setDiffuseColor(1.0f, 1.0f, 1.0f); + m.setAmbientColor(0.5f, 0.5f, 0.5f); + m.setSpecularColor(0.0f, 0.0f, 0.0f); + m.setShininess(1.0f); + ap2.setMaterial(m); + ap2.setColoringAttributes(new ColoringAttributes(0.5f, 0.5f, 0.5f, ColoringAttributes.NICEST)); + BaseObject3D stageObject = new BaseObject3D(groundGeometry, ap2); + Ground stageGround = new Ground(stageObject); + + // �I�u�W�F�N�g�̐ݒ� + Model3D model = ModelFactory.loadModel("data\\cubeBlue.3ds"); + Object3D objBlue = model.createObject(); + Model3D model2 = ModelFactory.loadModel("data\\cubeRed.3ds"); + Object3D objRed = model2.createObject(); + Transform3D s = new Transform3D(); + objBlue.children[0].scale.setTransform(s); + + int ARRAY_SIZE_X = 1; + int ARRAY_SIZE_Y = 1; + int ARRAY_SIZE_Z = 1; + + for(int k = 0 ; k < ARRAY_SIZE_Y ; k++){ + for(int l = 0 ; l < ARRAY_SIZE_X ; l++){ + for(int j = 0 ; j < ARRAY_SIZE_Z ; j++){ + + Solid3D solid; + if((j + k + l) % 2 == 0){ + solid = new Solid3D(objBlue); + } else { + solid = new Solid3D(objRed); + } + + solid.apply(new Position3D(-5.0 + 2.0*l, 10.0+2.0*k, -5.0+2.0*j), false); + + solid.scale(2.0, 2.0, 2.0); +// Quaternion3D q = new Quaternion3D(0.0, 0, 1.0, 0.7); +// solid.apply(q, false); + solid.apply(new AngularVelocity3D(-0.2, 0.0, -0.4), false); + universe.place(solid); + + camera.addTarget(solid); + + p_solid.add(solid); + } + } + } + + universe.place(stageGround); + + // �\�� + universe.compile(); + + // CollisionResult cr = new CollisionResult(); + // cr = PhysicsFacade.checkColision(solid, solid, solid2, solid2); + + int id = 0; + + for (;;) { + try { + Thread.sleep(1); + camera.adjust(0); + // w.move(17, stageObject); + Force3D f = Force3D.ZERO; +// if (solid.getPosition3D().getY() > -0.1) { +// // System.out.println(time+","+solid.getPosition3D().getY()); +// +// } + long newTime = System.currentTimeMillis(); + p_solid.motion(id, 3, f, p_solid.objects.get(id) + .getGravityCenter(), stageGround); +// p_solid.motion(id, newTime - oldTime, f, p_solid.objects.get(id) +// .getGravityCenter(), stageGround); + oldTime = newTime; + // if(cr != null){ + // p_solid.move(id, 1, f, cr.collisionPoint, stageObject); + // } + // else{ + // p_solid.move(id, 1, f, + // p_solid.objects.get(id).getGravityCenter(), stageObject); + // ) + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +// time++; + } + + } + + public static void main(String[] args) { + new TestDice(); + } +} diff --git a/src/main/java/framework/test/TestDomino.java b/src/main/java/framework/test/TestDomino.java new file mode 100644 index 0000000..8a84c18 --- /dev/null +++ b/src/main/java/framework/test/TestDomino.java @@ -0,0 +1,168 @@ +package framework.test; + +import java.awt.Component; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Stage; +import fight3D.StageManager; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.AngularVelocity3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicalSystem; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestDomino { + static final double GRAVITY = 9.8; + + public TestDomino() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Model3D model = ModelFactory.loadModel("data\\cube2.3ds"); + Object3D obj = model.createObject(); + Object3D obj2 = model.createObject(); + Transform3D s = new Transform3D(); + obj.children[0].scale.setTransform(s); + Transform3D s2 = new Transform3D(); + obj2.children[0].scale.setTransform(s2); + + // �I�u�W�F�N�g�̐ݒ� + Universe universe = new Universe(); + + Solid3D solid = new Solid3D(obj); + Solid3D solid2 = new Solid3D(obj); + Solid3D solid3 = new Solid3D(obj); + Solid3D solid4 = new Solid3D(obj); + Solid3D solid5 = new Solid3D(obj); + Solid3D solid6 = new Solid3D(obj); + Solid3D solid7 = new Solid3D(obj); + Solid3D solid8 = new Solid3D(obj); + Solid3D solid9 = new Solid3D(obj); + + solid.apply(new Position3D(-2, -4.0, 0.0), false); + solid3.apply(new Position3D(-1.2, -4.0, 0.0), false); + solid4.apply(new Position3D(-0.4, -4.0, 0.0), false); + solid5.apply(new Position3D(0.4, -4.0, 0.0), false); + solid6.apply(new Position3D(1.2, -4.0, 0.0), false); + solid7.apply(new Position3D(2.0, -4.0, 0.0), false); + solid8.apply(new Position3D(2.8, -4.0, 0.0), false); + solid9.apply(new Position3D(3.6, -4.0, 0.0), false); + solid2.apply(new Position3D(4.4, -4.0, 0.0), false); + solid.scale(0.2, 2.0, 1.0); + solid2.scale(0.2, 2.0, 1.0); + solid3.scale(0.2, 2.0, 1.0); + solid4.scale(0.2, 2.0, 1.0); + solid5.scale(0.2, 2.0, 1.0); + solid6.scale(0.2, 2.0, 1.0); + solid7.scale(0.2, 2.0, 1.0); + solid8.scale(0.2, 2.0, 1.0); + solid9.scale(0.2, 2.0, 1.0); + + solid2.apply(new AngularVelocity3D(0.0, 0.0, 1.0), false); + universe.place(solid); + universe.place(solid2); + universe.place(solid3); + universe.place(solid4); + universe.place(solid5); + universe.place(solid6); + universe.place(solid7); + universe.place(solid8); + universe.place(solid9); + + // ���C�g�̐ݒ� + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, -1.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.placeLight(light); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �X�e�[�W�̐ݒ� +// Object3D stageObject = ModelFactory.loadModel("data\\floor4.3ds").createObject(); + Object3D stageObject = ModelFactory.loadModel("data\\stage3\\stage3.wrl").createObject(); + Ground stageGround = new Ground(stageObject); + universe.place(stageGround); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + canvas.attachCamera(camera); + camera.addTarget(solid); + camera.addTarget(solid2); + camera.addTarget(solid3); + camera.addTarget(solid4); + camera.addTarget(solid5); + camera.addTarget(solid6); + camera.addTarget(solid7); + camera.addTarget(solid8); + camera.addTarget(solid9); + + // �\�� + universe.compile(); + + PhysicalSystem p_solid = new PhysicalSystem(); + p_solid.add(solid); + p_solid.add(solid2); + p_solid.add(solid3); + p_solid.add(solid4); + p_solid.add(solid5); + p_solid.add(solid6); + p_solid.add(solid7); + p_solid.add(solid8); + p_solid.add(solid9); + + // CollisionResult cr = new CollisionResult(); + // cr = PhysicsFacade.checkColision(solid, solid, solid2, solid2); + + int id = 1; + long time = 0; + for (;;) { + try { + Thread.sleep(0); + camera.adjust(0); + // w.move(17, stageObject); + Force3D f = Force3D.ZERO; + if (solid.getPosition3D().getY() > -0.1) { + // System.out.println(time+","+solid.getPosition3D().getY()); + + } + p_solid.motion(id, 3, f, p_solid.objects.get(id) + .getGravityCenter(), stageGround); + // if(cr != null){ + // p_solid.move(id, 1, f, cr.collisionPoint, stageObject); + // } + // else{ + // p_solid.move(id, 1, f, + // p_solid.objects.get(id).getGravityCenter(), stageObject); + // ) + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + time++; + } + } + + public static void main(String[] args) { + new TestDomino(); + } +} diff --git a/src/main/java/framework/test/TestMathmatics.java b/src/main/java/framework/test/TestMathmatics.java new file mode 100644 index 0000000..b582489 --- /dev/null +++ b/src/main/java/framework/test/TestMathmatics.java @@ -0,0 +1,84 @@ +package framework.test; + +import java.awt.Component; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.CollisionResult; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestMathmatics { + + public TestMathmatics() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Model3D model = ModelFactory.loadModel("data\\cube2.3ds"); + Object3D obj1 = model.createObject(); + Object3D obj2 = model.createObject(); + Transform3D s1 = new Transform3D(); + Transform3D s2 = new Transform3D(); + obj1.children[0].scale.setTransform(s1); + obj2.children[0].scale.setTransform(s2); + + Universe universe = new Universe(); + + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.place(light); + + // obj1.setPosition(new Position3D(3.0,0.0,0.0)); + // obj2.setPosition(new Position3D(-3.0,0.0,0.0)); + Solid3D sol1 = new Solid3D(obj1); + Solid3D sol2 = new Solid3D(obj2); + sol1.apply(new Position3D(1.5, 1.5, 0.0), false); + universe.place(sol1); + universe.place(sol2); + + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(0.0, 0.0, 10.0)); + camera.adjust(0L); + canvas.attachCamera(camera); + + universe.compile(); + + CollisionResult cr = PhysicsUtility + .checkCollision(sol1, null, sol2, null); + + frame.setSize(720, 480); + frame.setVisible(true); + if (cr != null) { + System.out.println("Yes!!"); + } else { + System.out.println("No!!"); + } + // for (;;) { + // + // } + } + + @SuppressWarnings("serial") + public static void main(String[] args) { + new TestMathmatics(); + } +} diff --git a/src/main/java/framework/test/TestMathmatics2.java b/src/main/java/framework/test/TestMathmatics2.java new file mode 100644 index 0000000..d255428 --- /dev/null +++ b/src/main/java/framework/test/TestMathmatics2.java @@ -0,0 +1,143 @@ +package framework.test; + +import java.awt.Component; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; +import javax.vecmath.Vector4d; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.CollisionResult; +import framework.model3D.GeometryUtility; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestMathmatics2 implements KeyListener { + + Solid3D sol1 = null; + Solid3D sol2 = null; + Ground stageGround = null; + + // �R���X�g���N�^ + @SuppressWarnings("serial") + public TestMathmatics2() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + frame.addKeyListener(this); + + Model3D model1 = ModelFactory.loadModel("data\\cube2.3ds"); + Model3D model2 = ModelFactory.loadModel("data\\cube2.3ds"); + Object3D obj1 = model1.createObject(); + Object3D obj2 = model2.createObject(); + Transform3D s1 = new Transform3D(); + Transform3D s2 = new Transform3D(); + obj1.children[0].scale.setTransform(s1); + obj2.children[0].scale.setTransform(s2); + + Universe universe = new Universe(); + + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.place(light); + + // obj1.setPosition(new Position3D(3.0,0.0,0.0)); + // obj2.setPosition(new Position3D(-3.0,0.0,0.0)); + + sol1 = new Solid3D(obj1); + sol2 = new Solid3D(obj2); + sol1.apply(new Position3D(-2.0, 0.0, 0.0), false); + sol2.apply(new Position3D(0.0, 0.0, 0.0), false); + stageGround = new Ground(sol2); + universe.place(sol1); + universe.place(stageGround); + + + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(0.0, -3.0, 30.0)); + camera.adjust(0L); + canvas.attachCamera(camera); + + universe.compile(); + + frame.setSize(720, 480); + frame.setVisible(true); + frame.requestFocus(); + + // for (;;) { + // + // } + } + + public static void main(String[] args) { + boolean f = GeometryUtility.inside(new Vector3d(0.0, 0.0, 1.0), + new Vector4d(0.0, 0.0, -1.0, 0.0)); + System.out.println(f); + new TestMathmatics2(); + } + + @Override + public void keyPressed(KeyEvent e) { + // sol2.setUndoMark(); + Position3D p = sol2.getPosition3D(); + switch (e.getKeyCode()) { + case 37: + p.setX(p.getX() - 0.1); + sol2.apply(p, false); + break; + case 39: + p.setX(p.getX() + 0.1); + sol2.apply(p, false); + break; + case 38: + p.setY(p.getY() + 0.1); + sol2.apply(p, false); + break; + case 40: + p.setY(p.getY() - 0.1); + sol2.apply(p, false); + break; + } + // CollisionResult cr = PhysicsFacade.isOnground(sol1, sol2); + CollisionResult cr = PhysicsUtility.doesIntersect(sol1, stageGround); + // CollisionResult cr = PhysicsFacade.checkColision(sol1, sol1, sol2, + // sol2); + if (cr != null) { + System.out.println("TestMathmatics2 Yes!!"); + } else { + System.out.println("TestMathmatics2 No!!"); + } + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } +} diff --git a/src/main/java/framework/test/TestModel.java b/src/main/java/framework/test/TestModel.java new file mode 100644 index 0000000..ed10dbb --- /dev/null +++ b/src/main/java/framework/test/TestModel.java @@ -0,0 +1,110 @@ +package framework.test; + +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Canvas3D; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Locale; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.universe.SimpleUniverse; + +import cv97.Constants; +import cv97.SceneGraph; +import cv97.j3d.SceneGraphJ3dObject; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTFrame3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + + + +public class TestModel extends Frame implements Constants { + SceneGraph sg; + Canvas3D c; + + TestModel(){ + super("VRML Simple Viewer"); + + + sg = new SceneGraph(SceneGraph.NORMAL_GENERATION); + setLayout(new BorderLayout()); + + GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + + c = new Canvas3D(config); + add("Center",c); + SceneGraphJ3dObject sgObject = new SceneGraphJ3dObject(c,sg); + sg.setObject(sgObject); + +// sg.load("data\\Q07077-2.3ds"); +// sg.save("newGLViewLib.wrl"); + +// setSize(400,400); +// sg.print(); +// show(); + + } + public static void main(String[] args) { +// TestModel testModel = new TestModel(); + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + +// Model3D model = ModelFactory.loadModel("data\\doordemo.wrl"); +// Model3D model = ModelFactory.loadModel("data\\cube2.3ds"); + Model3D model = ModelFactory.loadModel("data\\Head.3ds"); + Object3D obj = model.createObject(); + Transform3D s = new Transform3D(); +// s.setScale(0.01); + obj.children[0].scale.setTransform(s); + + Universe universe = new Universe(); + + DirectionalLight light = new DirectionalLight( true, + new Color3f(1.0f, 1.0f, 1.0f), + new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.place(light); + +// SimpleUniverse universe = new SimpleUniverse(testModel.c); + universe.place(obj); + universe.compile(); + + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(0.0, 0.0, 1000.0)); + camera.adjust(0L); + canvas.attachCamera(camera); + + frame.setVisible(true); + // obj.rotate(0.0, 1.0, 0.0, 2 * Math.PI / 4); +// Transform3D trans = new Transform3D(); +// Transform3D trans2 = new Transform3D(); +// obj.children[0].children[4].pos.getTransform(trans); +// obj.children[0].children[0].rot.getTransform(trans2); +// +// Vector3d vector = new Vector3d(); +// trans.get(vector); +// vector.x = vector.x + 20; +// trans.set(vector); +// +// trans2.rotY(2 * Math.PI / 8); +// +// frame.setSize(600, 480); +// obj.children[0].children[4].pos.setTransform(trans); +// obj.children[0].children[0].rot.setTransform(trans2); + } +} diff --git a/src/main/java/framework/test/TestMultiView.java b/src/main/java/framework/test/TestMultiView.java new file mode 100644 index 0000000..6e7babb --- /dev/null +++ b/src/main/java/framework/test/TestMultiView.java @@ -0,0 +1,161 @@ +package framework.test; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Texture; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTVirtualController; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.MultiViewGame; +import framework.gameMain.OvergroundActor; +import framework.model3D.BackgroundBox; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.Velocity3D; +import framework.view3D.Camera3D; + +public class TestMultiView extends MultiViewGame { + OvergroundActor pocha1; + OvergroundActor pocha2; + Ground stage; + Velocity3D pocha1Direction = new Velocity3D(5.0, 0.0, 0.0); + Velocity3D pocha2Direction = new Velocity3D(5.0, 0.0, 0.0); + + @Override + public void init(Universe universe, Camera3D camera1, Camera3D camera2) { + //�‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + //���s���� + DirectionalLight dirlight = new DirectionalLight( + true, //����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), //���̐F + new Vector3f(0.0f, -1.0f, -0.5f) //���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + + Model3D pochaModel = ModelFactory.loadModel("data\\pocha\\pocha.wrl", false, true); + Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); + + Object3D pochaBody1 = pochaModel.createObject(); + pocha1 = new OvergroundActor(pochaBody1, pochaAnimation); + pocha1.body.apply(new Position3D(3.0, 0.0, 0.0), false); + universe.place(pocha1); + + Object3D pochaBody2 = pochaModel.createObject(); + pocha2 = new OvergroundActor(pochaBody2, pochaAnimation); + pocha2.body.apply(new Position3D(-3.0, 0.0, 0.0), false); + universe.place(pocha2); + + camera1.setViewPoint(pocha1.getPosition().add(0.0, 0.5, 0.0)); + camera1.addTarget(pocha1); + camera1.setFieldOfView(1.5); + + camera2.setViewPoint(pocha2.getPosition().add(0.0, 0.5, 0.0)); + camera2.addTarget(pocha2); + camera2.setFieldOfView(1.5); + + Object3D stageObj = ModelFactory.loadModel("data\\stage3\\stage3.wrl").createObject(); + stage = new Ground(stageObj); + universe.place(stage); + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + Velocity3D curV = pocha1.getVelocity(); + if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { + pocha1Direction.rotY(0.02 * (double)(interval / 15.0)); + Quaternion3D curQuat = pocha1.body.getQuaternion(); + curQuat.add(new AxisAngle4d(0.0, 1.0, 0.0, 0.02 * (double)(interval / 15.0))); + pocha1.body.apply(curQuat, false); + } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { + pocha1Direction.rotY(-0.02 * (double)(interval / 15.0)); + Quaternion3D curQuat = pocha1.body.getQuaternion(); + curQuat.add(new AxisAngle4d(0.0, 1.0, 0.0, -0.02 * (double)(interval / 15.0))); + pocha1.body.apply(curQuat, false); + } + if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { + curV.setX(pocha1Direction.getX()); + curV.setZ(pocha1Direction.getZ()); + pocha1.body.apply(curV, false); + } else { + curV.setX(0.0); + curV.setZ(0.0); + pocha1.body.apply(curV, false); + } + if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { + if (pocha1.isOnGround()) { + curV.setY(10.0); + pocha1.body.apply(curV, false); + } + } + pocha1.motion(interval, stage); + camera1.setViewPoint(pocha1.getPosition().add(0.0, 1.5, 0.0)); + camera1.setViewLine(pocha1Direction.getVector3d()); + + curV = pocha2.getVelocity(); + if (virtualController.isKeyDown(1, RWTVirtualController.LEFT)) { + pocha2Direction.rotY(0.02 * (double)(interval / 15.0)); + Quaternion3D curQuat = pocha2.body.getQuaternion(); + curQuat.add(new AxisAngle4d(0.0, 1.0, 0.0, 0.02 * (double)(interval / 15.0))); + pocha2.body.apply(curQuat, false); + } else if (virtualController.isKeyDown(1, RWTVirtualController.RIGHT)) { + pocha2Direction.rotY(-0.02 * (double)(interval / 15.0)); + Quaternion3D curQuat = pocha2.body.getQuaternion(); + curQuat.add(new AxisAngle4d(0.0, 1.0, 0.0, -0.02 * (double)(interval / 15.0))); + pocha2.body.apply(curQuat, false); + } + if (virtualController.isKeyDown(1, RWTVirtualController.DOWN)) { + curV.setX(pocha2Direction.getX()); + curV.setZ(pocha2Direction.getZ()); + pocha2.body.apply(curV, false); + } else { + curV.setX(0.0); + curV.setZ(0.0); + pocha2.body.apply(curV, false); + } + if (virtualController.isKeyDown(1, RWTVirtualController.UP)) { + if (pocha2.isOnGround()) { + curV.setY(10.0); + pocha2.body.apply(curV, false); + } + } + pocha2.motion(interval, stage); + camera2.setViewPoint(pocha2.getPosition().add(0.0, 1.5, 0.0)); + camera2.setViewLine(pocha2Direction.getVector3d()); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setTitle("Multi View Test"); + return f; + } + + /** + * @param args + */ + public static void main(String[] args) { + TestMultiView game = new TestMultiView(); + game.start(); + } +} diff --git a/src/main/java/framework/test/TestObject.java b/src/main/java/framework/test/TestObject.java new file mode 100644 index 0000000..1ba9be2 --- /dev/null +++ b/src/main/java/framework/test/TestObject.java @@ -0,0 +1,121 @@ +package framework.test; + +import java.awt.Component; +import java.util.ArrayList; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.Node; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Stage; +import fight3D.StageManager; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.BaseObject3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.AngularVelocity3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicalSystem; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestObject { + private Object3D object; + + public TestObject() { + // �t���[���̍\�� + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + // ���E�̍쐬 + Universe universe = new Universe(); + + // ���C�g�̐ݒ� + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, -1.0f, -0.1f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 50000.0)); + universe.placeLight(light); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �X�e�[�W�̐ݒ� + IndexedTriangleArray groundGeometry = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS, 6); + groundGeometry.setCoordinate(0, new Point3d(-10.0, 0.0, -10.0)); + groundGeometry.setCoordinate(1, new Point3d(10.0, 0.0, -10.0)); + groundGeometry.setCoordinate(2, new Point3d(10.0, 0.0, 10.0)); + groundGeometry.setCoordinate(3, new Point3d(-10.0, 0.0, 10.0)); + groundGeometry.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setCoordinateIndices(0, new int[]{0, 3, 2}); + groundGeometry.setCoordinateIndices(3, new int[]{0, 2, 1}); + Appearance ap2 = new Appearance(); + Material m = new Material(); + m.setDiffuseColor(1.0f, 1.0f, 1.0f); + m.setAmbientColor(0.5f, 0.5f, 0.5f); + m.setSpecularColor(0.0f, 0.0f, 0.0f); + m.setShininess(1.0f); + ap2.setMaterial(m); + ap2.setColoringAttributes(new ColoringAttributes(0.5f, 0.5f, 0.5f, ColoringAttributes.NICEST)); + BaseObject3D stageObject = new BaseObject3D(groundGeometry, ap2); + Ground stageGround = new Ground(stageObject); + universe.place(stageGround); + + // �I�u�W�F�N�g�̐ݒ� + Model3D model = ModelFactory.loadModel("data\\cubeBlue.3ds"); // 3D���f���t�@�C���̓ǂݍ��� + object = model.createObject(); // �I�u�W�F�N�g��1���� + universe.place(object); // ���E�ɔz�u + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + canvas.attachCamera(camera); + camera.addTarget(object); + Position3D viewPoint = new Position3D(0.0, 10.0, -50.0); + camera.setViewPoint(viewPoint); + camera.adjust(0); + + // �\�� + universe.compile(); + } + + public void start() { + // �I�u�W�F�N�g�̉^�� + for (;;) { + try { + Thread.sleep(1); + Position3D p = new Position3D(0.0, 0.0, 0.0); + object.apply(p, false); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + public static void main(String[] args) { + TestObject test = new TestObject(); + test.start(); + } +} diff --git a/src/main/java/framework/test/TestPhysics.java b/src/main/java/framework/test/TestPhysics.java new file mode 100644 index 0000000..e51a020 --- /dev/null +++ b/src/main/java/framework/test/TestPhysics.java @@ -0,0 +1,105 @@ +package framework.test; + +import java.awt.Component; +import java.awt.event.KeyEvent; +import java.util.ArrayList; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Character; +import fight3D.CharacterManager; +import fight3D.Player; +import fight3D.Stage; +import fight3D.StageManager; +import fight3D.Weapon; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.Velocity3D; +import framework.view3D.Camera3D; + +public class TestPhysics { + + public TestPhysics() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Model3D model = ModelFactory.loadModel("data\\cube2.3ds"); + Object3D obj = model.createObject(); + Transform3D s = new Transform3D(); + obj.children[0].scale.setTransform(s); + + Universe universe = new Universe(); + + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.placeLight(light); + + universe.place(obj); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �v���C���[�̐ݒ� + Character c = CharacterManager.getInstance().getCharacter(0); + Player p = new Player(c); + universe.place(p); + + // ��ѓ���̐ݒ� + Weapon w = new Weapon(c.getWeaponModel(), p, 0); + universe.place(w); + w.body.apply(new Velocity3D(-5.0, 0.0, 0.0), false); + w.body.apply(new Quaternion3D(), false); + + // �X�e�[�W�̐ݒ� + Stage stage = StageManager.getInstance().getStage(0); + Object3D stageObject = stage.getModel().createObject(); + Ground stageGround = new Ground(stageObject); + universe.place(stageGround); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + camera.addTarget(p.body); + camera.addTarget(w.body); + canvas.attachCamera(camera); + + // �\�� + universe.compile(); + + // Solid3D solid = new Solid3D(obj); + Position3D applicationPoint = new Position3D(10, 10, 10); + for (;;) { + try { + Thread.sleep(17); + camera.adjust(17); + w.motion(17, stageGround); + // Force3D f = PhysicsFacade.getGravity(solid); + // solid.move(17, f, applicationPoint); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + new TestPhysics(); + } +} diff --git a/src/main/java/framework/test/TestPhysics2.java b/src/main/java/framework/test/TestPhysics2.java new file mode 100644 index 0000000..02fc3ab --- /dev/null +++ b/src/main/java/framework/test/TestPhysics2.java @@ -0,0 +1,118 @@ +package framework.test; + +import java.awt.Component; + +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.Clip; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Transform3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import fight3D.Stage; +import fight3D.StageManager; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.CollisionResult; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicalSystem; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; +import framework.view3D.Camera3D; + +public class TestPhysics2 { + static final double GRAVITY = 9.8; + + public TestPhysics2() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + RWTCanvas3D canvas = new RWTCanvas3D(); + frame.add(canvas); + + Model3D model = ModelFactory.loadModel("data\\cube2.3ds"); + Object3D obj = model.createObject(); + Object3D obj2 = model.createObject(); + Transform3D s = new Transform3D(); + obj.children[0].scale.setTransform(s); + Transform3D s2 = new Transform3D(); + obj2.children[0].scale.setTransform(s2); + + // �I�u�W�F�N�g�̐ݒ� + Universe universe = new Universe(); + + Solid3D solid = new Solid3D(obj); + solid.apply(new Position3D(0.0, 0.0, 0.0), false); + Solid3D solid2 = new Solid3D(obj2); + solid2.apply(new Position3D(0.7, 4.0, 0.0), false); + universe.place(solid); + universe.place(solid2); + + // ���C�g�̐ݒ� + DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, + 1.0f, 1.0f), new Vector3f(0.0f, 0.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 500.0)); + universe.placeLight(light); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �X�e�[�W�̐ݒ� + Object3D stageObject = ModelFactory.loadModel("data//floor4.3ds").createObject(); + Ground stageGround = new Ground(stageObject); + universe.place(stageGround); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + camera.addTarget(solid); + camera.addTarget(solid2); + canvas.attachCamera(camera); + + // �\�� + universe.compile(); + + PhysicalSystem p_solid = new PhysicalSystem(); + p_solid.add(solid); + p_solid.add(solid2); + CollisionResult cr = new CollisionResult(); + cr = PhysicsUtility.checkCollision(solid, null, solid2, null); + int id = 1; + long time = 0; + for (;;) { + try { + Thread.sleep(1); + camera.adjust(0); + // w.move(17, stageObject); + Force3D f = Force3D.ZERO; + // if(solid.getVelocity().getY()<0.1 && + // solid.getVelocity().getY()>-0.1){ + // System.out.println("��"+time+","+solid.getPosition3D().getY()); + // } + // if(solid.getPosition3D().getY()<=-4.5){ + // System.out.println("��"+time+","+solid.getPosition3D().getY()+","+solid.getVelocity().getY()); + // } + if (cr != null) { + p_solid.motion(id, 1, f, cr.collisionPoint, stageGround); + } else { + p_solid.motion(id, 1, f, p_solid.objects.get(id) + .getGravityCenter(), stageGround); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + time++; + } + } + + public static void main(String[] args) { + new TestPhysics2(); + } +} diff --git a/src/main/java/framework/test/TestShadow.java b/src/main/java/framework/test/TestShadow.java new file mode 100644 index 0000000..64eedac --- /dev/null +++ b/src/main/java/framework/test/TestShadow.java @@ -0,0 +1,199 @@ +package framework.test; + +import java.awt.Component; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.util.Map; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.GraphicsConfigTemplate3D; +import javax.media.j3d.Material; +import javax.media.j3d.PolygonAttributes; +import javax.media.j3d.QuadArray; +import javax.media.j3d.RenderingAttributes; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransparencyAttributes; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.geometry.Cylinder; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +public class TestShadow { + + public TestShadow() { + // TODO Auto-generated constructor stub + RWTFrame3D frame = new RWTFrame3D(); + + // �X�e���V���o�b�t�@���g�p���� GraphicsConfiguration �̐��� + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); + gct3D.setStencilSize(8); + GraphicsConfiguration gc = gd.getBestConfiguration(gct3D); + + RWTCanvas3D canvas = new RWTCanvas3D(gc); + frame.add(canvas); + Map canvasProperty = canvas.queryProperties(); + System.out.println(canvasProperty.get("stencilSize")); + + Universe universe = new Universe(); + + DirectionalLight light = new DirectionalLight(true, + new Color3f(1.0f, 1.0f, 1.0f), + new Vector3f(0.0f, -1.0f, -1.0f)); + light.setInfluencingBounds(new BoundingSphere(new Point3d(), 1000.0)); + universe.placeLight(light); + + // �n�ʑS�̂��e�̐F�ŕ`��i��������Z�o�b�t�@�ɏ������ށj + Appearance ap0 = new Appearance(); + Material m0 = new Material(); + m0.setDiffuseColor(0.5f, 0.5f, 0.5f); // �e�̐F���D�F�� + m0.setSpecularColor(0.0f, 0.0f, 0.0f); + ap0.setMaterial(m0); + RenderingAttributes ra0 = new RenderingAttributes(); +// ra0.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_READ); +// ra0.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE); +// ra0.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_READ); +// ra0.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE); +// ra0.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_READ); +// ra0.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_WRITE); + ra0.setStencilEnable(false); + ra0.setDepthBufferWriteEnable(true); + ra0.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); + ap0.setRenderingAttributes(ra0); + PolygonAttributes pa0 = new PolygonAttributes(); + pa0.setCullFace(PolygonAttributes.CULL_BACK); + ap0.setPolygonAttributes(pa0); + QuadArray quadArray0 = new QuadArray(4, QuadArray.COORDINATES | QuadArray.NORMALS); + quadArray0.setCoordinates(0, new Point3d[]{new Point3d(-10.0, 0.0, -10.0), + new Point3d(-10.0, 0.0, 10.0), + new Point3d(10.0, 0.0, 10.0), + new Point3d(10.0, 0.0, -10.0)}); + quadArray0.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f)); + quadArray0.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f)); + quadArray0.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f)); + quadArray0.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f)); + Shape3D box0 = new Shape3D(quadArray0, ap0); + universe.place(box0); + + // �V���h�E�{�����[���\�ʁi�X�e���V���o�b�t�@��+1�j + Appearance ap1 = new Appearance(); +// ap1.setMaterial(new Material()); + RenderingAttributes ra1 = new RenderingAttributes(); +// ra1.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_READ); +// ra1.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE); +// ra1.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_READ); +// ra1.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE); +// ra1.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_READ); +// ra1.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_WRITE); + ra1.setStencilEnable(true); + ra1.setDepthBufferWriteEnable(false); + ra1.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); + ra1.setStencilFunction(RenderingAttributes.ALWAYS, 0, ~0); + ra1.setStencilOp(RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_INCR); + ap1.setRenderingAttributes(ra1); + PolygonAttributes pa1 = new PolygonAttributes(); + pa1.setCullFace(PolygonAttributes.CULL_BACK); + ap1.setPolygonAttributes(pa1); + TransparencyAttributes ta1 = new TransparencyAttributes(); // setVisible(false)���ƃX�e���V���o�b�t�@���X�V����Ȃ��̂ŁA������ + ta1.setTransparencyMode(TransparencyAttributes.BLENDED); + ta1.setTransparency(1.0f); + ap1.setTransparencyAttributes(ta1); + Cylinder cyl1 = new Cylinder(1.0f, 10.0f, ap1); + universe.place(cyl1); + + // �V���h�E�{�����[�����ʁi�X�e���V���o�b�t�@��-1�j + Appearance ap2 = new Appearance(); +// ap2.setMaterial(new Material()); + RenderingAttributes ra2 = new RenderingAttributes(); +// ra2.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_READ); +// ra2.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE); +// ra2.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_READ); +// ra2.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE); +// ra2.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_READ); +// ra2.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_WRITE); + ra2.setStencilEnable(true); + ra2.setDepthBufferWriteEnable(false); + ra2.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); + ra2.setStencilFunction(RenderingAttributes.ALWAYS, 0, ~0); + ra2.setStencilOp(RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_DECR); + ap2.setRenderingAttributes(ra2); + PolygonAttributes pa2 = new PolygonAttributes(); + pa2.setCullFace(PolygonAttributes.CULL_FRONT); + ap2.setPolygonAttributes(pa2); + TransparencyAttributes ta2 = new TransparencyAttributes(); // setVisible(false)���ƃX�e���V���o�b�t�@���X�V����Ȃ��̂ŁA������ + ta2.setTransparencyMode(TransparencyAttributes.BLENDED); + ta2.setTransparency(1.0f); + ap2.setTransparencyAttributes(ta2); + Cylinder cyl2 = new Cylinder(1.0f, 10.0f, ap2); + universe.place(cyl2); + + // �e�̕������������n�� + Appearance ap3 = new Appearance(); + Material m3 = new Material(); + ap3.setMaterial(m3); + RenderingAttributes ra3 = new RenderingAttributes(); +// ra3.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_READ); +// ra3.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE); +// ra3.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_READ); +// ra3.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE); +// ra3.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_READ); +// ra3.setCapability(RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_WRITE); + ra3.setStencilEnable(true); + ra3.setDepthBufferWriteEnable(true); + ra3.setDepthTestFunction(RenderingAttributes.LESS_OR_EQUAL); + ra3.setStencilFunction(RenderingAttributes.GREATER_OR_EQUAL, 0, ~0); // �X�e���V���o�b�t�@�̒l��1�ȏ�̂Ƃ��`�悵�Ȃ� + ra3.setStencilOp(RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_KEEP, RenderingAttributes.STENCIL_KEEP); + ap3.setRenderingAttributes(ra3); + PolygonAttributes pa3 = new PolygonAttributes(); + pa3.setCullFace(PolygonAttributes.CULL_BACK); + ap3.setPolygonAttributes(pa3); + QuadArray quadArray1 = new QuadArray(4, QuadArray.COORDINATES); + quadArray1.setCoordinates(0, new Point3d[]{new Point3d(-10.0, 0.0, -10.0), + new Point3d(-10.0, 0.0, 10.0), + new Point3d(10.0, 0.0, 10.0), + new Point3d(10.0, 0.0, -10.0)}); + Shape3D box1 = new Shape3D(quadArray1, ap3); + universe.place(box1); + + frame.setSize(720, 480); + frame.setVisible(true); + + // �J�����̐ݒ� + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(20.0, 20.0, 20.0)); + camera.addTarget(new Position3D(0.0, 0.0, 0.0)); + canvas.attachCamera(camera); + + // �\�� + universe.compile(); + + for (;;) { + try { + Thread.sleep(17); + camera.adjust(17); + // Force3D f = PhysicsFacade.getGravity(solid); + // solid.move(17, f, applicationPoint); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + new TestShadow(); + } +} diff --git a/src/main/java/framework/test/TestShadow2.java b/src/main/java/framework/test/TestShadow2.java new file mode 100644 index 0000000..176d3f6 --- /dev/null +++ b/src/main/java/framework/test/TestShadow2.java @@ -0,0 +1,132 @@ +package framework.test; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.GraphicsConfigTemplate3D; +import javax.media.j3d.IndexedTriangleArray; +import javax.media.j3d.Material; +import javax.media.j3d.PointLight; +import javax.media.j3d.PolygonAttributes; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + + +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.Cone; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.universe.SimpleUniverse; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.gameMain.SimpleGame; +import framework.model3D.BaseObject3D; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +public class TestShadow2 extends SimpleGame { + Object3D box; + BaseObject3D ground; + double a = 0.0; + + public static void main(String[] args) { + TestShadow2 game = new TestShadow2(); + game.setFramePolicy(100, false); + game.start(); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setShadowCasting(true); + f.setTitle("Flag Rush"); + return f; + } + + @Override + public void init(Universe universe, Camera3D camera) { + // �����̐ݒ� + DirectionalLight dirlight = new DirectionalLight( + true, //����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), //���̐F + new Vector3f(1.0f, -1.0f, -0.5f) //���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight, 100.0); + + PointLight pointLight = new PointLight( + true, //����ON/OFF + new Color3f(1.0f, 0.3f, 0.0f), //���̐F + new Point3f(0.0f, 25.0f, 0.0f), //�����̈ʒu + new Point3f(0.1f, 0.0f, 0.001f) //���̌��� + ); + pointLight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(pointLight); + + Appearance ap1 = new Appearance(); + Material m1 = new Material(); + m1.setDiffuseColor(1.0f, 1.0f, 0.0f); + ap1.setMaterial(m1); + ColoringAttributes ca = new ColoringAttributes(); + ca.setShadeModel(ColoringAttributes.NICEST); + ap1.setColoringAttributes(ca); + box = new Object3D("occuluder", new Box(2.0f, 2.0f, 2.0f, ap1)); + box.apply(new Position3D(0.0, 10.0, 0.0), false); +// box = new Object3D("occuluder", boxGeometry, ap1); + universe.placeAsAnOcculuder(box); + + IndexedTriangleArray groundGeometry = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS, 6); + groundGeometry.setCoordinate(0, new Point3d(-20.0, 0.0, -20.0)); + groundGeometry.setCoordinate(1, new Point3d(20.0, 0.0, -20.0)); + groundGeometry.setCoordinate(2, new Point3d(20.0, 0.0, 20.0)); + groundGeometry.setCoordinate(3, new Point3d(-20.0, 0.0, 20.0)); + groundGeometry.setNormal(0, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(1, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(2, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setNormal(3, new Vector3f(0.0f, 1.0f, 0.0f)); + groundGeometry.setCoordinateIndices(0, new int[]{0, 3, 2}); + groundGeometry.setCoordinateIndices(3, new int[]{0, 2, 1}); + Appearance ap2 = new Appearance(); + Material m = new Material(); + m.setDiffuseColor(1.0f, 1.0f, 1.0f); + m.setAmbientColor(0.5f, 0.5f, 0.5f); + m.setSpecularColor(0.0f, 0.0f, 0.0f); + m.setShininess(1.0f); + ap2.setMaterial(m); + ap2.setColoringAttributes(new ColoringAttributes(0.5f, 0.5f, 0.5f, ColoringAttributes.NICEST)); + ground = new BaseObject3D(groundGeometry, ap2); + universe.placeAsAReceiver(ground); + + // �J�����̐ݒ� + camera.setViewPoint(new Position3D(50.0, 50.0, 50.0)); + camera.addTarget(new Position3D(0.0, 0.0, 0.0)); + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { +// Position3D pos = box.getPosition3D(); +// pos.add(0.1, 0.0, 0.0); +// box.apply(pos, false); + Quaternion3D q = new Quaternion3D(1.0, 0.0, 0.0, a); + box.apply(q, false); + a += .1; + if (a > Math.PI * 2) a -= Math.PI * 2; + } +} diff --git a/src/main/java/framework/view3D/Camera3D.java b/src/main/java/framework/view3D/Camera3D.java new file mode 100644 index 0000000..3eb68d3 --- /dev/null +++ b/src/main/java/framework/view3D/Camera3D.java @@ -0,0 +1,438 @@ +package framework.view3D; +import java.util.ArrayList; + +import javax.media.j3d.BadTransformException; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.PhysicalBody; +import javax.media.j3d.PhysicalEnvironment; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.View; +import javax.media.j3d.ViewPlatform; +import javax.vecmath.SingularMatrixException; +import javax.vecmath.Vector3d; + +import com.sun.j3d.utils.universe.ViewingPlatform; + +import framework.model3D.GeometryUtility; +import framework.model3D.Object3D; +import framework.model3D.Placeable; +import framework.model3D.Position3D; +import framework.model3D.Universe; + +/** + * ��p�����@�\���t�����J����
+ * ���_�A�����ΏہA�����̂���2�‚��w�肵�Ďg���B + * @author �V�c���� + * + */ +public class Camera3D { + private static final double NEAREST = 3.0; + private static final Vector3d VIEW_FORWARD = new Vector3d(0.0, 0.0, -1.0); + private static final Vector3d VIEW_DOWN = new Vector3d(0.0, -1.0, 0.0); + private Universe universe = null; + private View view = null; + private TransformGroup viewPlatformTransform = null; + protected ArrayList targetObjList = null; + protected ArrayList targetList = null; + protected Position3D viewPoint = null; + protected Object3D viewPointObj = null; + private Vector3d viewLine = null; + private Vector3d cameraBack = null; + + // �ȉ��̕ϐ��͏ȃ��������̂��ߓ��� + private Transform3D worldToView = new Transform3D(); + private double matrix[] = new double[]{1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + + private Transform3D cameraTransform = new Transform3D(); + + public Camera3D(Universe universe) { + this.universe = universe; + view = new View(); + view.setPhysicalBody(new PhysicalBody()); + view.setPhysicalEnvironment(new PhysicalEnvironment()); + view.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_GEOMETRY); + view.setBackClipDistance(10000.0); + ViewPlatform viewPlatform = new ViewPlatform(); + view.attachViewPlatform(viewPlatform); + viewPlatformTransform = new TransformGroup(); + viewPlatformTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + viewPlatformTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + viewPlatformTransform.addChild(viewPlatform); + universe.place(viewPlatformTransform); + } + + public Universe getUniverse() { + return universe; + } + + public View getView() { + return view; + } + + /** + * �J�����̒����_��lj����� + * + * @param target + * �����_ + */ + public void addTarget(Position3D target) { + if (targetList == null) targetList = new ArrayList(); + targetList.add(target); + } + + /** + * �J�����̒����Ώۂ�lj����� + * + * @param target + * �����Ώ� + */ + public void addTarget(Object3D target) { + if (targetObjList == null) targetObjList = new ArrayList(); + targetObjList.add(target); + } + + /** + * �J�����̒����Ώۂ�lj����� + * + * @param target + * �����Ώ� + */ + public void addTarget(Placeable target) { + if (targetObjList == null) targetObjList = new ArrayList(); + if (target.getBody() instanceof Object3D) { + targetObjList.add((Object3D)target.getBody()); + } + } + + /** + * �J�����̎��_��ݒ肷�� + * + * @param viewPoint + * ���_ + */ + public void setViewPoint(Position3D viewPoint) { + this.viewPoint = viewPoint; + } + + /** + * �J�����̎��_��ݒ肷�� + * + * @param viewPoint + * ���_�ƂȂ�I�u�W�F�N�g + */ + public void setViewPoint(Object3D viewPointObj) { + this.viewPointObj = viewPointObj; + } + + /** + * �J�����̎��_��ݒ肷�� + * + * @param viewPoint + * ���_�ƂȂ�o�ꕨ + */ + public void setViewPoint(Placeable viewPointActor) { + if (viewPointActor.getBody() instanceof Object3D) { + viewPointObj = (Object3D)viewPointActor.getBody(); + } + } + + /** + * ��O����̎����ɐݒ肷�� + */ + public void setSideView() { + viewLine = VIEW_FORWARD; + } + + /** + * �ォ�猩���낵�������ɐݒ肷�� + */ + public void setTopView() { + viewLine = VIEW_DOWN; + } + + /** + * ������ݒ肷�� + */ + public void setViewLine(Vector3d viewLine) { + this.viewLine = viewLine; + } + + /** + * �����Ώۂɑ΂��ăJ���������������Ƌ�����ݒ肷�� + * @param cameraBack + */ + public void setCameraBack(Vector3d cameraBack) { + this.cameraBack = cameraBack; + } + + public Vector3d getCameraBack() { + return cameraBack; + } + + /** + * ����p��ݒ肷�� + * @param a ����p + */ + public void setFieldOfView(double a) { + view.setFieldOfView(a); + } + + /** + * ����p���擾���� + * @return ����p + */ + public double getFieldOfView() { + return view.getFieldOfView(); + } + + /** + * �t�����g�N���b�v������ݒ肷�� + * @param d + */ + public void setFrontClipDistance(double d) { + view.setFrontClipDistance(d); + } + + /** + * �o�b�N�N���b�v������ݒ肷�� + * @param d + */ + public void setBackClipDistance(double d) { + view.setBackClipDistance(d); + } + + /** + * �����Ώۂ⎋�_�̈ړ��A�����̕ω��ɔ�����p���� + */ + public void adjust(long interval) { + // �J�������W�n�ivx, vy, vz�j���v�Z���� + Vector3d vx = new Vector3d(), vy = new Vector3d(), vz = new Vector3d(); + if (viewLine == null) { + // �������ݒ肳��Ă��Ȃ��ꍇ + if ((viewPoint == null && viewPointObj == null) + || ((targetObjList == null || targetObjList.size() == 0) + && (targetList == null || targetList.size() == 0))) { + // ���_�܂��͒����Ώۂ��ݒ肳��Ă��Ȃ��ꍇ�A��O����̎����ɂ��� + vz.negate(VIEW_FORWARD); + } else { + // �����Ώۂ̏d�S�𒍎��_�Ƃ��� + Vector3d center = new Vector3d(); + if (targetObjList != null && targetObjList.size() != 0) { + for (int i = 0; i < targetObjList.size(); i++) { + Position3D position = targetObjList.get(i).getPosition3D(); + center.add(position.getVector3d()); + } + center.scale(1.0 / targetObjList.size()); + } else if (targetList != null && targetList.size() != 0) { + for (int i = 0; i < targetList.size(); i++) { + Position3D position = targetList.get(i); + center.add(position.getVector3d()); + } + center.scale(1.0 / targetList.size()); + } + if (viewPoint != null) { + center.sub(viewPoint.getVector3d()); + } else { + center.sub(viewPointObj.getPosition3D().getVector3d()); + } + center.normalize(); + vz.negate(center); + } + } else { + // �������ݒ肳��Ă���ꍇ vz ���������� �Ƌt�����ɐݒ肷�� + viewLine.normalize(); + vz.negate(viewLine); + } + vx.cross(vz, VIEW_DOWN); + if (vx.length() > GeometryUtility.TOLERANCE) { + vx.normalize(); + } else { + vx = new Vector3d(1.0, 0.0, 0.0); + } + vy.cross(vz, vx); + + // ���E���W����J�������W�ւ̕ϊ����v�Z���� + if (viewPoint != null || viewPointObj != null) { + // ���_���ݒ肳��Ă���ꍇ + Vector3d vp; + if (viewPoint != null) { + vp = viewPoint.getVector3d(); + } else { + vp = viewPointObj.getPosition3D().getVector3d(); + } + matrix[0] = vx.x; matrix[1] = vx.y; matrix[2] = vx.z; matrix[3] = 0.0; + matrix[4] = vy.x; matrix[5] = vy.y; matrix[6] = vy.z; matrix[7] = 0.0; + matrix[8] = vz.x; matrix[9] = vz.y; matrix[10] = vz.z; matrix[11] = 0.0; + matrix[12] = 0.0; matrix[13] = 0.0; matrix[14] = 0.0; matrix[15] = 1.0; + worldToView.set(matrix); + try { + worldToView.invert(); + } catch (SingularMatrixException e) { + return; + } + worldToView.setTranslation(vp); + } else { + // ���_���ݒ肳��Ă��Ȃ��ꍇ�A�����ΏۂƎ�������i�J�������W�n��ł́j���_���t�v�Z���� + if ((targetObjList == null || targetObjList.size() == 0) + && (targetList == null || targetList.size() == 0)) return; // ���_�������Ώۂ��ݒ肳��Ă��Ȃ� + double xmax = 0; + double xmin = 0; + double ymax = 0; + double ymin = 0; + + // ���W�̎擾 + Vector3d center = new Vector3d(); + if (targetObjList != null && targetObjList.size() != 0) { + for (int i = 0; i < targetObjList.size(); i++) { + Position3D position = targetObjList.get(i).getPosition3D(); + center.add(position.getVector3d()); + double px = position.getVector3d().dot(vx); + double py = position.getVector3d().dot(vy); + if (i == 0) { + xmax = xmin = px; + ymax = ymin = py; + } else { + if (xmax < px) + xmax = px; + if (xmin > px) + xmin = px; + if (ymax < py) + ymax = py; + if (ymin > py) + ymin = py; + } + } + center.scale(1.0 / targetObjList.size()); + } else if (targetList != null && targetList.size() != 0) { + for (int i = 0; i < targetList.size(); i++) { + Position3D position = targetList.get(i); + center.add(position.getVector3d()); + double px = position.getVector3d().dot(vx); + double py = position.getVector3d().dot(vy); + if (i == 0) { + xmax = xmin = px; + ymax = ymin = py; + } else { + if (xmax < px) + xmax = px; + if (xmin > px) + xmin = px; + if (ymax < py) + ymax = py; + if (ymin > py) + ymin = py; + } + } + center.scale(1.0 / targetList.size()); + } + + double x = (xmax + xmin) / 2; + double y = (ymax + ymin) / 2; + double x_diff = Math.abs(xmax - x); + double y_diff = Math.abs(ymax - y); + if (x_diff < NEAREST) + x_diff = NEAREST; + if (y_diff < NEAREST) + y_diff = NEAREST; + double z; + if (x_diff < y_diff) { + z = y_diff / Math.tan(Math.PI / 18.0); + } else { + z = x_diff / Math.tan(Math.PI / 18.0); + } + Vector3d eye = new Vector3d(center.dot(vx), center.dot(vy), center.dot(vz)); + if (cameraBack != null) { + eye.add(cameraBack); + } else { + eye.z += z; + } + + matrix[0] = vx.x; matrix[1] = vx.y; matrix[2] = vx.z; matrix[3] = -eye.x; + matrix[4] = vy.x; matrix[5] = vy.y; matrix[6] = vy.z; matrix[7] = -eye.y; + matrix[8] = vz.x; matrix[9] = vz.y; matrix[10] = vz.z; matrix[11] = -eye.z; + matrix[12] = 0.0; matrix[13] = 0.0; matrix[14] = 0.0; matrix[15] = 1.0; + worldToView.set(matrix); + try { + worldToView.invert(); + } catch (SingularMatrixException e) { + return; + } + } + try { + if (viewPlatformTransform != null) viewPlatformTransform.setTransform(worldToView); + } catch (BadTransformException e) { + + } + } + + public Position3D getViewPoint() { + if (viewPoint != null) return viewPoint; + if (viewPointObj != null) return viewPointObj.getPosition3D(); + return null; + } + + public Vector3d getViewLine() { + return viewLine; + } + + public void setWorldToView(Position3D vp, Vector3d vl) { + // �J�����p�����[�^�ւ̔��f + if (viewPoint != null) { + viewPoint.setVector3d(vp.getVector3d()); + } else if (viewPointObj != null) { + viewPointObj.apply(vp, false); + } + if (viewLine != null) { + viewLine.set(vl); + } + + // �J�������W�n�ivx, vy, vz�j���v�Z���� + Vector3d vx = new Vector3d(), vy = new Vector3d(), vz = new Vector3d(); + viewLine.normalize(); + vz.negate(viewLine); + vx.cross(vz, VIEW_DOWN); + if (vx.length() > GeometryUtility.TOLERANCE) { + vx.normalize(); + } else { + vx = new Vector3d(1.0, 0.0, 0.0); + } + vy.cross(vz, vx); + matrix[0] = vx.x; matrix[1] = vx.y; matrix[2] = vx.z; matrix[3] = 0.0; + matrix[4] = vy.x; matrix[5] = vy.y; matrix[6] = vy.z; matrix[7] = 0.0; + matrix[8] = vz.x; matrix[9] = vz.y; matrix[10] = vz.z; matrix[11] = 0.0; + matrix[12] = 0.0; matrix[13] = 0.0; matrix[14] = 0.0; matrix[15] = 1.0; + worldToView.set(matrix); + try { + worldToView.invert(); + } catch (SingularMatrixException e) { + return; + } + worldToView.setTranslation(vp.getVector3d()); + try { + if (viewPlatformTransform != null) viewPlatformTransform.setTransform(worldToView); + } catch (BadTransformException e) { + } + } + + public Transform3D getWorldToView() { + adjust(1L); + Transform3D trans = new Transform3D(); + trans.set(matrix); + trans.invert(); + return trans; + } + + public void transformView(Transform3D delta) { + viewPlatformTransform.getTransform(cameraTransform); + cameraTransform.mul(delta); + try { + viewPlatformTransform.setTransform(cameraTransform); + } catch (BadTransformException e) { + + } + } +} diff --git a/src/main/java/framework/view3D/Dot3BumpMapShader.java b/src/main/java/framework/view3D/Dot3BumpMapShader.java new file mode 100644 index 0000000..ef61a1e --- /dev/null +++ b/src/main/java/framework/view3D/Dot3BumpMapShader.java @@ -0,0 +1,151 @@ +package framework.view3D; + +import java.awt.image.BufferedImage; + +import javax.media.j3d.Appearance; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.TextureCubeMap; +import javax.media.j3d.TextureUnitState; +import javax.vecmath.Vector3f; +import javax.vecmath.Vector4f; + +import framework.model3D.BumpMapGenerator; + +public class Dot3BumpMapShader { + private TextureCubeMap normalMappingTexture = null; + private static Vector3f yAxis = new Vector3f(0.0f, 1.0f, 0.0f); + + public void init(DirectionalLight dirlight) { + Vector3f lightDir = new Vector3f(); + dirlight.getDirection(lightDir); + lightDir.negate(); // �@�������������Ƌt�����̖ʂ���Ԗ��邢 + lightDir.normalize(); + + BufferedImage topLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage bottomLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage eastLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage westLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage northLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage southLightMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(-1.0f, ((float)t - 256.0f) / 256.0f, ((float)s - 256.0f) / 256.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + southLightMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(1.0f, ((float)t - 256.0f) / 256.0f, (256.0f - (float)s) / 256.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + northLightMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, ((float)t - 256.0f) / 256.0f, 1.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + eastLightMapping.setRGB(s, t, rgb); + } + } + + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f((256.0f - (float)s) / 256.0f, ((float)t - 256.0f) / 256.0f, -1.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + westLightMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, 1.0f, (256.0f - (float)t) / 256.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + topLightMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, -1.0f, ((float)t - 256.0f) / 256.0f); + int rgb = calcRelativeLightDir(lightDir, texZ); + bottomLightMapping.setRGB(s, t, rgb); + } + } + + ImageComponent2D topImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, topLightMapping, true, false); + ImageComponent2D bottomImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, bottomLightMapping, true, false); + ImageComponent2D eastImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, eastLightMapping, true, false); + ImageComponent2D westImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, westLightMapping, true, false); + ImageComponent2D northImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, northLightMapping, true, false); + ImageComponent2D southImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, southLightMapping, true, false); + normalMappingTexture = new TextureCubeMap(TextureCubeMap.BASE_LEVEL, TextureCubeMap.RGB, topLightMapping.getWidth()); + normalMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Y, topImage); + normalMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Y, bottomImage); + normalMappingTexture.setImage(0, TextureCubeMap.POSITIVE_X, northImage); + normalMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_X, southImage); + normalMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Z, eastImage); + normalMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Z, westImage); + } + + public void updateAppearance(Appearance ap, BumpMapGenerator bumpMapGenerator, Camera3D camera) { + if (normalMappingTexture == null) return; + if (!bumpMapGenerator.hasMapped()) { + int n = ap.getTextureUnitCount(); + TextureUnitState newUnitStates[] = new TextureUnitState[n + 2]; + if (ap.getTextureUnitState() != null) System.arraycopy(ap.getTextureUnitState(), 0, newUnitStates, 2, n); + TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.NORMAL_MAP, TexCoordGeneration.TEXTURE_COORDINATE_3); + TextureAttributes ta = new TextureAttributes(); + ta.setTextureMode(TextureAttributes.REPLACE); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + // TexCoordGeneration.NORMAL_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta.setTextureTransform(camera.getWorldToView()); + // �e�N�X�`�����j�b�g�̈�ԍŏ��ɖ@���}�b�s���O��ݒ肷�� + newUnitStates[0] = new TextureUnitState(normalMappingTexture, ta, tcg); + + ta = new TextureAttributes(); + ta.setTextureMode(TextureAttributes.COMBINE); + ta.setCombineRgbMode(TextureAttributes.COMBINE_DOT3); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + // �e�N�X�`�����j�b�g�̍ŏ������ԖڂɃo���v�}�b�s���O��ݒ肷�� + newUnitStates[1] = new TextureUnitState(bumpMapGenerator.getBumpMap(), ta, bumpMapGenerator.getTexCoordGeneration()); + + ap.setTextureUnitState(newUnitStates); + bumpMapGenerator.setMapped(); + } else { + TextureAttributes ta = ap.getTextureUnitState(0).getTextureAttributes(); + // TexCoordGeneration.NORMZAL_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta.setTextureTransform(camera.getWorldToView()); + } + } + + private int calcRelativeLightDir(Vector3f lightDir, Vector3f texZ) { + texZ.normalize(); + Vector3f texX = new Vector3f(); + texX.cross(yAxis, texZ); + if (texX.length() == 0.0f) { + texX = new Vector3f(1.0f, 0.0f, 0.0f); + } else { + texX.normalize(); + } + Vector3f texY = new Vector3f(); + texY.cross(texZ, texX); + float x = lightDir.dot(texX); + float y = lightDir.dot(texY); + float z = lightDir.dot(texZ); + int r = (int)(x * 127.5f + 127.5f); + int g = (int)(y * 127.5f + 127.5f); + int b = (int)(z * 127.5f + 127.5f); + int rgb = (r << 16) + (g << 8) + b; + return rgb; + } +} diff --git a/src/main/java/framework/view3D/FlatDot3BumpMapShader.java b/src/main/java/framework/view3D/FlatDot3BumpMapShader.java new file mode 100644 index 0000000..9264c01 --- /dev/null +++ b/src/main/java/framework/view3D/FlatDot3BumpMapShader.java @@ -0,0 +1,64 @@ +package framework.view3D; + +import javax.media.j3d.Appearance; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Material; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.TextureUnitState; +import javax.vecmath.Color3f; +import javax.vecmath.Vector3f; + +import framework.model3D.BumpMapGenerator; + +public class FlatDot3BumpMapShader { + private static Vector3f yAxis = new Vector3f(0.0f, 1.0f, 0.0f); + private static Color3f color; + + public void init(DirectionalLight dirlight) { + Vector3f lightDir = new Vector3f(); + dirlight.getDirection(lightDir); + lightDir.negate(); // �@�������������Ƌt�����̖ʂ���Ԗ��邢 + lightDir.normalize(); + color = calcRelativeLightDir(lightDir, yAxis); + } + + public void updateAppearance(Appearance ap, BumpMapGenerator bumpMapGenerator, Camera3D camera) { + if (!bumpMapGenerator.hasMapped()) { + ap.setMaterial(null); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(color); + ap.setColoringAttributes(ca); + int n = ap.getTextureUnitCount(); + TextureUnitState newUnitStates[] = new TextureUnitState[n + 1]; + if (ap.getTextureUnitState() != null) System.arraycopy(ap.getTextureUnitState(), 0, newUnitStates, 1, n); + TextureAttributes ta = new TextureAttributes(); + ta.setTextureMode(TextureAttributes.COMBINE); + ta.setCombineRgbMode(TextureAttributes.COMBINE_DOT3); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + // �e�N�X�`�����j�b�g�̍ŏ������ԖڂɃo���v�}�b�s���O��ݒ肷�� + newUnitStates[0] = new TextureUnitState(bumpMapGenerator.getBumpMap(), ta, bumpMapGenerator.getTexCoordGeneration()); + + ap.setTextureUnitState(newUnitStates); + bumpMapGenerator.setMapped(); + } + } + + private Color3f calcRelativeLightDir(Vector3f lightDir, Vector3f texZ) { + texZ.normalize(); + Vector3f texX = new Vector3f(); + texX.cross(yAxis, texZ); + if (texX.length() == 0.0f) { + texX = new Vector3f(1.0f, 0.0f, 0.0f); + } else { + texX.normalize(); + } + Vector3f texY = new Vector3f(); + texY.cross(texZ, texX); + float x = lightDir.dot(texX); + float y = lightDir.dot(texY); + float z = lightDir.dot(texZ); + return new Color3f((x + 1.0f) / 2.0f, (y + 1.0f) / 2.0f, (z + 1.0f) / 2.0f); + } +} diff --git a/src/main/java/framework/view3D/FresnelsReflectionMapShader.java b/src/main/java/framework/view3D/FresnelsReflectionMapShader.java new file mode 100644 index 0000000..c279063 --- /dev/null +++ b/src/main/java/framework/view3D/FresnelsReflectionMapShader.java @@ -0,0 +1,186 @@ +package framework.view3D; + +import java.awt.Image; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; + +import javax.media.j3d.Appearance; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.TextureCubeMap; +import javax.media.j3d.TextureUnitState; +import javax.vecmath.Vector3f; + +import framework.model3D.BackgroundBox; +import framework.model3D.FresnelsReflectionMapGenerator; +import framework.model3D.ReflectionMapGenerator; + +public class FresnelsReflectionMapShader { + boolean bTransparent = false; + TextureCubeMap reflectionMappingTexture = null; + TextureCubeMap fresnelsMappingTexture = null; + + public void init(BackgroundBox skyBox) { + // �‹����˂̃e�N�X�`�� + reflectionMappingTexture = new TextureCubeMap(TextureCubeMap.BASE_LEVEL, TextureCubeMap.RGBA, skyBox.getTopImage().getWidth()); + ImageComponent2D topSkyImage = skyBox.getTopImage(); + ImageComponent2D bottomSkyImage = skyBox.getBottomImage(); + ImageComponent2D eastSkyImage = skyBox.getEastImage(); + ImageComponent2D westSkyImage = skyBox.getWestImage(); + ImageComponent2D northSkyImage = skyBox.getNorthImage(); + ImageComponent2D southSkyImage = skyBox.getSouthImage(); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Y, topSkyImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Y, bottomSkyImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Z, westSkyImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Z, eastSkyImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_X, northSkyImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_X, southSkyImage); + + // �t���l�����ˌW�����v�Z���e�N�X�`���ɖ��ߍ��� + BufferedImage topFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage bottomFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage eastFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage westFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage northFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + BufferedImage southFresnelsMapping = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(-1.0f, ((float)t - 256.0f) / 256.0f, ((float)s - 256.0f) / 256.0f); + int rgb = calcFresnels(texZ); + southFresnelsMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(1.0f, ((float)t - 256.0f) / 256.0f, (256.0f - (float)s) / 256.0f); + int rgb = calcFresnels(texZ); + northFresnelsMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, ((float)t - 256.0f) / 256.0f, 1.0f); + int rgb = calcFresnels(texZ); + eastFresnelsMapping.setRGB(s, t, rgb); + } + } + + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f((256.0f - (float)s) / 256.0f, ((float)t - 256.0f) / 256.0f, -1.0f); + int rgb = calcFresnels(texZ); + westFresnelsMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, 1.0f, (256.0f - (float)t) / 256.0f); + int rgb = calcFresnels(texZ); + topFresnelsMapping.setRGB(s, t, rgb); + } + } + + for (int t = 0; t < 512; t++) { + for (int s = 0; s < 512; s++) { + Vector3f texZ = new Vector3f(((float)s - 256.0f) / 256.0f, -1.0f, ((float)t - 256.0f) / 256.0f); + int rgb = calcFresnels(texZ); + bottomFresnelsMapping.setRGB(s, t, rgb); + } + } + + ImageComponent2D topImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, topFresnelsMapping, true, false); + ImageComponent2D bottomImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, bottomFresnelsMapping, true, false); + ImageComponent2D eastImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, eastFresnelsMapping, true, false); + ImageComponent2D westImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, westFresnelsMapping, true, false); + ImageComponent2D northImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, northFresnelsMapping, true, false); + ImageComponent2D southImage = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, southFresnelsMapping, true, false); + fresnelsMappingTexture = new TextureCubeMap(TextureCubeMap.BASE_LEVEL, TextureCubeMap.RGBA, topFresnelsMapping.getWidth()); + fresnelsMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Y, topImage); + fresnelsMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Y, bottomImage); + fresnelsMappingTexture.setImage(0, TextureCubeMap.POSITIVE_X, northImage); + fresnelsMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_X, southImage); + fresnelsMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Z, eastImage); + fresnelsMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Z, westImage); + } + + public void updateAppearance(Appearance ap, FresnelsReflectionMapGenerator reflectionMapGenerator, Camera3D camera) { + if (reflectionMappingTexture == null) return; + if (!reflectionMapGenerator.hasMapped()) { + TexCoordGeneration tcg1 = new TexCoordGeneration(TexCoordGeneration.REFLECTION_MAP, TexCoordGeneration.TEXTURE_COORDINATE_3); + TextureAttributes ta1 = new TextureAttributes(); + ta1.setTextureMode(TextureAttributes.COMBINE); + ta1.setCombineRgbMode(TextureAttributes.COMBINE_ADD_SIGNED); +// ta1.setCombineRgbMode(TextureAttributes.COMBINE_INTERPOLATE); + ta1.setCombineRgbSource(0, TextureAttributes.COMBINE_TEXTURE_COLOR); + ta1.setCombineRgbSource(1, TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE); + ta1.setCombineRgbSource(2, TextureAttributes.COMBINE_CONSTANT_COLOR); + ta1.setCombineRgbFunction(0, TextureAttributes.COMBINE_SRC_COLOR); + ta1.setCombineRgbFunction(1, TextureAttributes.COMBINE_SRC_COLOR); + ta1.setCombineRgbFunction(2, TextureAttributes.COMBINE_SRC_COLOR); + ta1.setTextureBlendColor(reflectionMapGenerator.getBlendColor()); + ta1.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta1.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + // TexCoordGeneration.REFLECTION_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta1.setTextureTransform(camera.getWorldToView()); + + TexCoordGeneration tcg2 = new TexCoordGeneration(TexCoordGeneration.REFLECTION_MAP, TexCoordGeneration.TEXTURE_COORDINATE_3); + TextureAttributes ta2 = new TextureAttributes(); + + if (reflectionMapGenerator.isTransparent()) { + ta2.setTextureMode(TextureAttributes.BLEND); + } else { + ta2.setTextureMode(TextureAttributes.COMBINE); + ta2.setCombineRgbMode(TextureAttributes.COMBINE_INTERPOLATE); + ta2.setCombineRgbSource(0, TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE); + ta2.setCombineRgbSource(1, TextureAttributes.COMBINE_OBJECT_COLOR); + ta2.setCombineRgbSource(2, TextureAttributes.COMBINE_TEXTURE_COLOR); + ta2.setCombineRgbFunction(0, TextureAttributes.COMBINE_SRC_COLOR); + ta2.setCombineRgbFunction(1, TextureAttributes.COMBINE_SRC_COLOR); + ta2.setCombineRgbFunction(2, TextureAttributes.COMBINE_SRC_ALPHA); + } + + int n = ap.getTextureUnitCount(); + if (n > 0) { + // �e�N�X�`�����j�b�g�̈�ԍŌ�ɔ��˃}�b�s���O�ƃt���l�����ˌW����ݒ肷�� + TextureUnitState newUnitStates[] = new TextureUnitState[n + 2]; + if (ap.getTextureUnitState() != null) System.arraycopy(ap.getTextureUnitState(), 0, newUnitStates, 0, n); + newUnitStates[n] = new TextureUnitState(reflectionMappingTexture, ta1, tcg1); + newUnitStates[n].setCapability(TextureUnitState.ALLOW_STATE_READ); + newUnitStates[n].setCapability(TextureUnitState.ALLOW_STATE_WRITE); + newUnitStates[n+1] = new TextureUnitState(fresnelsMappingTexture, ta2, tcg2); + + ap.setTextureUnitState(newUnitStates); + } else { + TextureUnitState newUnitStates[] = new TextureUnitState[2]; + newUnitStates[0] = new TextureUnitState(reflectionMappingTexture, ta1, tcg1); + newUnitStates[0].setCapability(TextureUnitState.ALLOW_STATE_READ); + newUnitStates[0].setCapability(TextureUnitState.ALLOW_STATE_WRITE); + newUnitStates[1] = new TextureUnitState(fresnelsMappingTexture, ta2, tcg2); + + ap.setTextureUnitState(newUnitStates); + } + reflectionMapGenerator.setMapped(); + } else { + int n = ap.getTextureUnitCount(); + if (n > 1) { + TextureAttributes ta = ap.getTextureUnitState(n - 2).getTextureAttributes(); + // TexCoordGeneration.REFLECTION_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta.setTextureTransform(camera.getWorldToView()); + } + } + } + + private int calcFresnels(Vector3f texZ) { + texZ.normalize(); + int a = (int)(-texZ.z * 127.5f + 127.5f); + int rgb = (a << 24) + (0 << 16) + (0 << 8) + 0; + return rgb; + } +} diff --git a/src/main/java/framework/view3D/ReflectionMapShader.java b/src/main/java/framework/view3D/ReflectionMapShader.java new file mode 100644 index 0000000..22f5fb8 --- /dev/null +++ b/src/main/java/framework/view3D/ReflectionMapShader.java @@ -0,0 +1,77 @@ +package framework.view3D; + +import javax.media.j3d.Appearance; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.TextureCubeMap; +import javax.media.j3d.TextureUnitState; + +import framework.model3D.BackgroundBox; +import framework.model3D.ReflectionMapGenerator; + +public class ReflectionMapShader { + TextureCubeMap reflectionMappingTexture = null; + + public void init(BackgroundBox skyBox) { + reflectionMappingTexture = new TextureCubeMap(TextureCubeMap.BASE_LEVEL, TextureCubeMap.RGB, skyBox.getTopImage().getWidth()); + ImageComponent2D topImage = (ImageComponent2D)skyBox.getTopImage(); + ImageComponent2D bottomImage = (ImageComponent2D)skyBox.getBottomImage(); + ImageComponent2D eastImage = (ImageComponent2D)skyBox.getEastImage(); + ImageComponent2D westImage = (ImageComponent2D)skyBox.getWestImage(); + ImageComponent2D northImage = (ImageComponent2D)skyBox.getNorthImage(); + ImageComponent2D southImage = (ImageComponent2D)skyBox.getSouthImage(); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Y, topImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Y, bottomImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_Z, eastImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_Z, westImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.POSITIVE_X, northImage); + reflectionMappingTexture.setImage(0, TextureCubeMap.NEGATIVE_X, southImage); + } + + + public void updateAppearance(Appearance ap, ReflectionMapGenerator reflectionMapGenerator, Camera3D camera) { + if (reflectionMappingTexture == null) return; + if (!reflectionMapGenerator.hasMapped()) { + TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.REFLECTION_MAP, TexCoordGeneration.TEXTURE_COORDINATE_3); + TextureAttributes ta = new TextureAttributes(); + ta.setTextureMode(TextureAttributes.COMBINE); + ta.setCombineRgbMode(TextureAttributes.COMBINE_INTERPOLATE); + ta.setCombineRgbSource(0, TextureAttributes.COMBINE_TEXTURE_COLOR); + ta.setCombineRgbSource(1, TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE); + ta.setCombineRgbSource(2, TextureAttributes.COMBINE_CONSTANT_COLOR); + ta.setCombineRgbFunction(0, TextureAttributes.COMBINE_SRC_COLOR); + ta.setCombineRgbFunction(1, TextureAttributes.COMBINE_SRC_COLOR); + ta.setCombineRgbFunction(2, TextureAttributes.COMBINE_SRC_COLOR); + ta.setTextureBlendColor(reflectionMapGenerator.getBlendColor()); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_READ); + ta.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE); + // TexCoordGeneration.REFLECTION_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta.setTextureTransform(camera.getWorldToView()); + int n = ap.getTextureUnitCount(); + if (n > 0) { + // �e�N�X�`�����j�b�g�̈�ԍŌ�ɔ��˃}�b�s���O��ݒ肷�� + TextureUnitState newUnitStates[] = new TextureUnitState[n + 1]; + if (ap.getTextureUnitState() != null && n > 0) System.arraycopy(ap.getTextureUnitState(), 0, newUnitStates, 0, n); + newUnitStates[n] = new TextureUnitState(reflectionMappingTexture, ta, tcg); + + ap.setTextureUnitState(newUnitStates); + } else { + ap.setTexture(reflectionMappingTexture); + ap.setTextureAttributes(ta); + ap.setTexCoordGeneration(tcg); + } + reflectionMapGenerator.setMapped(); + } else { + TextureAttributes ta; + int n = ap.getTextureUnitCount(); + if (n > 0) { + ta = ap.getTextureUnitState(ap.getTextureUnitCount() - 1).getTextureAttributes(); + } else { + ta = ap.getTextureAttributes(); + } + // TexCoordGeneration.REFLECTION_MAP �͎����ɑ΂��ČŒ�Ȃ̂ŁA�����̌����ɍ��킹�ăe�N�X�`������] + ta.setTextureTransform(camera.getWorldToView()); + } + } +} diff --git a/src/main/java/framework/view3D/Viewer3D.java b/src/main/java/framework/view3D/Viewer3D.java new file mode 100644 index 0000000..a315f92 --- /dev/null +++ b/src/main/java/framework/view3D/Viewer3D.java @@ -0,0 +1,215 @@ +package framework.view3D; + +import java.util.ArrayList; +import java.util.Enumeration; + +import javax.media.j3d.Appearance; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.DistanceLOD; +import javax.media.j3d.Geometry; +import javax.media.j3d.GraphicsContext3D; +import javax.media.j3d.LOD; +import javax.media.j3d.Light; +import javax.media.j3d.Node; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3d; + +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.Cone; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Primitive; +import com.sun.j3d.utils.geometry.Sphere; + +import framework.model3D.BackgroundBox; +import framework.model3D.BaseObject3D; +import framework.model3D.BumpMapGenerator; +import framework.model3D.FresnelsReflectionMapGenerator; +import framework.model3D.IViewer3D; +import framework.model3D.Object3D; +import framework.model3D.ReflectionMapGenerator; + +public class Viewer3D implements IViewer3D { + GraphicsContext3D graphicsContext3D = null; + ReflectionMapShader reflectionMappingShader = null; + FresnelsReflectionMapShader fresnelsReflectionMappingShader = null; + Dot3BumpMapShader dot3BumpMappingShader = null; + FlatDot3BumpMapShader flatDot3BumpMappingShader = null; + ArrayList lights = null; + BackgroundBox skyBox = null; + Camera3D camera = null; + + // �ȉ��͏ȃ��������̂��ߓ��� + static private Point3f center = new Point3f(); + static private Point3f origin = new Point3f(); + + public Viewer3D(Camera3D camera) { + this.camera = camera; + reflectionMappingShader = new ReflectionMapShader(); + fresnelsReflectionMappingShader = new FresnelsReflectionMapShader(); + dot3BumpMappingShader = new Dot3BumpMapShader(); + flatDot3BumpMappingShader = new FlatDot3BumpMapShader(); + } + + @Override + public void setGraphicsContext3D(GraphicsContext3D graphicsContext3D) { + this.graphicsContext3D = graphicsContext3D; + } + + + @Override + public void update(ArrayList lights, BackgroundBox skyBox) { + // �����̍X�V + if (this.lights != lights) { + this.lights = lights; + for (int n = 0; n < lights.size(); n++) { + if (lights.get(n) instanceof DirectionalLight) { + // ���s�����̏ꍇ + DirectionalLight dirlight = (DirectionalLight)lights.get(n); + dot3BumpMappingShader.init(dirlight); + flatDot3BumpMappingShader.init(dirlight); + break; + } + } + } + + // �X�J�C�{�b�N�X�̍X�V + if (this.skyBox != skyBox) { + this.skyBox = skyBox; + reflectionMappingShader.init(skyBox); + fresnelsReflectionMappingShader.init(skyBox); + } + } + + public void draw(BaseObject3D obj) { + + // GraphicsContext3D ���̌����̍X�V + if (lights != null && lights.size() != graphicsContext3D.numLights()) { + for (int n = 0; n < lights.size(); n++) { + graphicsContext3D.addLight(lights.get(n)); + } + } + + Enumeration primitives = obj.getPrimitiveNodes(); + ReflectionMapGenerator reflectionMapGenerator = obj.getReflectionMappingInfo(); + BumpMapGenerator bumpMapGenerator = obj.getBumpMappingInfo(); + int n = 0; + while (primitives.hasMoreElements()) { + if (obj instanceof Object3D && ((Object3D)obj).isLODSet()) { + // LOD �̔��� + LOD lodNode = ((Object3D)obj).getLOD(); + if (lodNode instanceof DistanceLOD) { + double nearSide = 0.0; + double farSide = 0.0; + DistanceLOD distanceLOD = ((DistanceLOD)lodNode); + if (n > distanceLOD.numDistances()) break; + if (n > 0) nearSide = distanceLOD.getDistance(n - 1); + if (n < distanceLOD.numDistances()) farSide = distanceLOD.getDistance(n); + + distanceLOD.getPosition(center); + Transform3D trans = new Transform3D(); + graphicsContext3D.getModelTransform(trans); + trans.transform(center); // �I�u�W�F�N�g�̒��S���W�i���E���W��j + trans = camera.getWorldToView(); + trans.transform(center); // �I�u�W�F�N�g�̒��S���W�i�J�������W��j + double distance = (double)center.distance(origin); + if (distance < nearSide) { + break; + } else if (distance > farSide && n < distanceLOD.numDistances()) { + n++; + continue; + } + } + } + Node primitive = primitives.nextElement(); + if (primitive instanceof Shape3D) { + // Shape3D�������_�����O + Appearance ap = ((Shape3D)primitive).getAppearance(); + if (bumpMapGenerator != null) { + // obj �ɂ̓o���v�}�b�s���O���ݒ肳��Ă��� + if (!bumpMapGenerator.isHorizontal()) { + dot3BumpMappingShader.updateAppearance(ap, bumpMapGenerator, camera); + } else { + // �����̃|���S���ɑ΂��ẮA���e�N�X�`�����j�b�g�̏���ʂ����Ȃ� FlatDot3BumpMapShader ���g�� + flatDot3BumpMappingShader.updateAppearance(ap, bumpMapGenerator, camera); + } + } + if (reflectionMapGenerator != null) { + // obj �ɂ͔��˃}�b�s���O���ݒ肳��Ă��� + if (reflectionMapGenerator instanceof FresnelsReflectionMapGenerator) { + // �t���l�����˂��g�p + fresnelsReflectionMappingShader.updateAppearance(ap, (FresnelsReflectionMapGenerator)reflectionMapGenerator, camera); + } else { + reflectionMappingShader.updateAppearance(ap, reflectionMapGenerator, camera); + } + } + + if (((Shape3D)primitive).getGeometry() != null) { + graphicsContext3D.draw((Shape3D)primitive); + } + } else if (primitive instanceof Primitive) { + Appearance ap = ((Primitive)primitive).getAppearance(); + if (bumpMapGenerator != null) { + // obj �ɂ̓o���v�}�b�s���O���ݒ肳��Ă��� + if (!bumpMapGenerator.isHorizontal()) { + dot3BumpMappingShader.updateAppearance(ap, bumpMapGenerator, camera); + } else { + // �����̃|���S���ɑ΂��ẮA���e�N�X�`�����j�b�g�̏���ʂ����Ȃ� FlatDot3BumpMapShader ���g�� + flatDot3BumpMappingShader.updateAppearance(ap, bumpMapGenerator, camera); + } + } + if (reflectionMapGenerator != null) { + // obj �ɂ͔��˃}�b�s���O���ݒ肳��Ă��� + if (reflectionMapGenerator instanceof FresnelsReflectionMapGenerator) { + // �t���l�����˂��g�p + fresnelsReflectionMappingShader.updateAppearance(ap, (FresnelsReflectionMapGenerator)reflectionMapGenerator, camera); + } else { + reflectionMappingShader.updateAppearance(ap, reflectionMapGenerator, camera); + } + } + graphicsContext3D.setAppearance(ap); + if (primitive instanceof Cone) { + // Cone�������_�����O + Geometry g = ((Cone)primitive).getShape(Cone.BODY).getGeometry(); + graphicsContext3D.draw(g); + g = ((Cone)primitive).getShape(Cone.CAP).getGeometry(); + graphicsContext3D.draw(g); + } else if (primitive instanceof Cylinder) { + // Cylinder�������_�����O + Geometry g = ((Cylinder)primitive).getShape(Cylinder.BODY).getGeometry(); + graphicsContext3D.draw(g); + g = ((Cylinder)primitive).getShape(Cylinder.TOP).getGeometry(); + graphicsContext3D.draw(g); + g = ((Cylinder)primitive).getShape(Cylinder.BOTTOM).getGeometry(); + graphicsContext3D.draw(g); + } else if (primitive instanceof Box) { + // Box�������_�����O + Geometry g = ((Box)primitive).getShape(Box.TOP).getGeometry(); + graphicsContext3D.draw(g); + g = ((Box)primitive).getShape(Box.BOTTOM).getGeometry(); + graphicsContext3D.draw(g); + g = ((Box)primitive).getShape(Box.FRONT).getGeometry(); + graphicsContext3D.draw(g); + g = ((Box)primitive).getShape(Box.BACK).getGeometry(); + graphicsContext3D.draw(g); + g = ((Box)primitive).getShape(Box.LEFT).getGeometry(); + graphicsContext3D.draw(g); + g = ((Box)primitive).getShape(Box.RIGHT).getGeometry(); + graphicsContext3D.draw(g); + } else if (primitive instanceof Sphere) { + // Sphere�������_�����O + Geometry g = ((Sphere)primitive).getShape().getGeometry(); + graphicsContext3D.draw(g); + } + } + n++; + } + } + + @Override + public void setModelTransform(Transform3D t) { + graphicsContext3D.setModelTransform(t); + } +} diff --git a/src/main/java/sample/SampleGame.java b/src/main/java/sample/SampleGame.java new file mode 100644 index 0000000..0bafb78 --- /dev/null +++ b/src/main/java/sample/SampleGame.java @@ -0,0 +1,91 @@ +package sample; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3f; + + +import framework.RWT.*; +import framework.gameMain.*; +import framework.model3D.*; +import framework.animation.*; +import framework.physics.*; +import framework.view3D.Camera3D; + + +public class SampleGame extends SimpleGame { + OvergroundActor pocha; + Ground stage; + + @Override + public void init(Universe universe, Camera3D camera) { + //�‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.5f, 0.5f, 0.5f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + //���s���� + DirectionalLight dirlight = new DirectionalLight( + true, //����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), //���̐F + new Vector3f(0.0f, -1.0f, -0.5f) //���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + + Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); + Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); + pocha = new OvergroundActor(pochaBody, pochaAnimation); + pocha.setPosition(new Position3D(3.87, 0.0, 24.0)); + universe.place(pocha); + + Object3D stageObj = ModelFactory.loadModel("data\\konan\\konan3.wrl").createObject(); + stage = new Ground(stageObj); + universe.place(stage); + + camera.setViewPoint(pocha.getPosition().add(0.0, 1.5, 0.0)); + camera.setViewLine(pocha.getDirection()); + camera.setFieldOfView(1.5); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setTitle("Sample"); + return f; + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + Velocity3D curV = pocha.getVelocity(); + if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { + pocha.rotY(0.02 * (double)(interval / 15.0)); + } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { + pocha.rotY(-0.02 * (double)(interval / 15.0)); + } + if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { + curV.setX(pocha.getDirection().getX() * 5.0); + curV.setZ(pocha.getDirection().getZ() * 5.0); + pocha.setVelocity(curV); + } else { + curV.setX(0.0); + curV.setZ(0.0); + pocha.setVelocity(curV); + } + if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { + if (pocha.isOnGround()) { + curV.setY(10.0); + pocha.setVelocity(curV); + } + } + pocha.motion(interval, stage); + camera.setViewPoint(pocha.getPosition().add(0.0, 1.5, 0.0)); + camera.setViewLine(pocha.getDirection()); + } + +} diff --git a/src/main/java/sample/SampleMain.java b/src/main/java/sample/SampleMain.java new file mode 100644 index 0000000..88362e6 --- /dev/null +++ b/src/main/java/sample/SampleMain.java @@ -0,0 +1,14 @@ +package sample; + +public class SampleMain { + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + SampleGame game = new SampleGame(); + game.start(); + } + +} diff --git a/src/main/java/template/RPG/FightContainer.java b/src/main/java/template/RPG/FightContainer.java new file mode 100644 index 0000000..612e339 --- /dev/null +++ b/src/main/java/template/RPG/FightContainer.java @@ -0,0 +1,53 @@ +package template.RPG; + +import java.awt.Color; +import java.awt.Font; +import java.awt.GraphicsConfiguration; + +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTLabel; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.gameMain.BaseScenarioGameContainer; +import framework.scenario.ScenarioManager; + +/** + * �퓬�p��� + * @author Nitta + * + */ +public class FightContainer extends BaseScenarioGameContainer { + + public FightContainer(ScenarioManager scenario) { + super(scenario); + } + + @Override + public void build(GraphicsConfiguration gc) { + super.build(gc); + canvas.setRelativePosition(0.0f, 0.0f); // 3D�\�����̍���[ + canvas.setRelativeSize(0.75f, 1.0f); // 3D�\�����̃T�C�Y + addCanvas(canvas); + dialog.setRelativePosition(0.75f, 0.75f); // �_�C�A���O�̍���[ + dialog.setFont(new Font("", Font.PLAIN, 12)); // �����̃t�H���g + dialog.setColor(Color.WHITE); // �����̐F + addWidget(dialog); + repaint(); + } + + @Override + public void keyPressed(RWTVirtualKey key) { + } + + @Override + public void keyReleased(RWTVirtualKey key) { + if (key.getPlayer() == 0 && key.getVirtualKey() == RWTVirtualController.BUTTON_A) { + scenario.fire("�퓬�I��"); + } + } + + @Override + public void keyTyped(RWTVirtualKey key) { + } +} diff --git a/src/main/java/template/RPG/Player.java b/src/main/java/template/RPG/Player.java new file mode 100644 index 0000000..3407864 --- /dev/null +++ b/src/main/java/template/RPG/Player.java @@ -0,0 +1,17 @@ +package template.RPG; + +import framework.animation.Animation3D; +import framework.gameMain.OvergroundActor; +import framework.model3D.Object3D; + +/** + * �v���C���[ + * @author �V�c���� + * + */ +public class Player extends OvergroundActor { + + public Player(Object3D body, Animation3D animation) { + super(body, animation); + } +} diff --git a/src/main/java/template/RPG/ScenarioGameContainer.java b/src/main/java/template/RPG/ScenarioGameContainer.java new file mode 100644 index 0000000..de5570b --- /dev/null +++ b/src/main/java/template/RPG/ScenarioGameContainer.java @@ -0,0 +1,53 @@ +package template.RPG; + +import java.awt.Color; +import java.awt.Font; +import java.awt.GraphicsConfiguration; + +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTLabel; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.gameMain.BaseScenarioGameContainer; +import framework.scenario.ScenarioManager; + +/** + * �V�i���I�Q�[���p��� + * @author Nitta + * + */ +public class ScenarioGameContainer extends BaseScenarioGameContainer { + + public ScenarioGameContainer(ScenarioManager scenario) { + super(scenario); + } + + @Override + public void build(GraphicsConfiguration gc) { + super.build(gc); + canvas.setRelativePosition(0.0f, 0.0f); // 3D�\�����̍���[ + canvas.setRelativeSize(0.75f, 1.0f); // 3D�\�����̃T�C�Y + addCanvas(canvas); + dialog.setRelativePosition(0.75f, 0.75f); // �_�C�A���O�̍���[ + dialog.setFont(new Font("", Font.PLAIN, 12)); // �����̃t�H���g + dialog.setColor(Color.WHITE); // �����̐F + addWidget(dialog); + repaint(); + } + + @Override + public void keyPressed(RWTVirtualKey key) { + } + + @Override + public void keyReleased(RWTVirtualKey key) { + if (key.getPlayer() == 0 && key.getVirtualKey() == RWTVirtualController.BUTTON_A) { + scenario.fire("A"); + } + } + + @Override + public void keyTyped(RWTVirtualKey key) { + } +} diff --git a/src/main/java/template/RPG/TemplateScenarioGame.java b/src/main/java/template/RPG/TemplateScenarioGame.java new file mode 100644 index 0000000..d26bad8 --- /dev/null +++ b/src/main/java/template/RPG/TemplateScenarioGame.java @@ -0,0 +1,237 @@ +package template.RPG; + +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.GraphicsConfigTemplate3D; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTVirtualController; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.BaseScenarioGameContainer; +import framework.gameMain.SimpleScenarioGame; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; +import framework.scenario.Event; +import framework.scenario.IWorld; +import framework.scenario.ScenarioManager; +import framework.scenario.ScenarioState; +import framework.view3D.Camera3D; + +/** + * �V�i���I�쓮�^�Q�[���̂��߂̃e���v���[�g + * @author �V�c���� + * + */ +public class TemplateScenarioGame extends SimpleScenarioGame implements IWorld { + private Player player; // �v���C���[ + private Player king; // ���l + private Ground stage; // �X�e�[�W + private RWTFrame3D frame; + + // �T�u��ʗp + private Universe subUniverse; + private Camera3D subCamera; + private BaseScenarioGameContainer subContainer = null; + + @Override + public void init(Universe universe, Camera3D camera) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + + // �L�����N�^�[��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); + Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); + player = new Player(pochaBody, pochaAnimation); + player.setPosition(new Position3D(-77.68, 0.0, -1.9)); + universe.place(player); + + // ���l��z�u�i�L�����N�^�[�͗��p�j + king = new Player(pochaBody, pochaAnimation); + king.setPosition(new Position3D(3.87, -11.92, 21.39)); + universe.place(king); + + // �X�e�[�W��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D stageObj = ModelFactory.loadModel("data\\konan\\konan3.wrl").createObject(); + stage = new Ground(stageObj); + universe.place(stage); + + // �J�����̐ݒ�i���Վ��_�ɂ���j + camera.addTarget(player); + camera.setViewLine(new Vector3d(0.0, -10.0, -10.0)); + camera.setFieldOfView(1.5); + } + + /** + * �퓬��ʂ̏����� + * @param universe + * @param camera + */ + private void subInit(Universe universe, Camera3D camera) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + + // �G�L�����N�^�[��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D enemy = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); + enemy.apply(new Position3D(0.0, 0.0, 0.0), false); + enemy.apply(new Quaternion3D(0.0, 1.0, 0.0, Math.PI / 2.0), false); + universe.place(enemy); + + // �J�����̐ݒ�i�����_�ɂ���j + camera.addTarget(enemy.getPosition3D().add(0.0, 1.0, 0.0)); + camera.setViewLine(new Vector3d(0.0, -2.0, 10.0)); + camera.setCameraBack(new Vector3d(0.0, 0.0, 2.0)); + camera.setFieldOfView(1.5); + } + + @Override + public RWTFrame3D createFrame3D() { + frame = new RWTFrame3D(); + frame.setSize(800, 600); + frame.setTitle("Template for Role Playing Games"); + frame.setBackground(Color.BLACK); + return frame; + } + + @Override + protected RWTContainer createRWTContainer() { + scenario = new ScenarioManager("data\\sampleScenario\\scenario2.xml", this); // �V�i���I�t�@�C���̓ǂݍ��� + container = new ScenarioGameContainer(scenario); + return container; + } + + // �퓬�p��ʂ̍쐬 + protected RWTContainer createSubRWTContainer() { + subContainer = new FightContainer(scenario); + return subContainer; + } + + // �퓬�p��ʂւ̐؂�ւ� + protected void changeToSubContainer() { + if (subContainer == null) { + subContainer = (BaseScenarioGameContainer)createSubRWTContainer(); + frame.setContentPane(subContainer); + GraphicsConfiguration gc = null; + if (frame.isShadowCasting()) { + // �e��t����ꍇ + // �X�e���V���o�b�t�@���g�p���� GraphicsConfiguration �̐��� + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); + gct3D.setStencilSize(8); + gc = gd.getBestConfiguration(gct3D); + } + subContainer.build(gc); + + subUniverse = new Universe(); + subCamera = new Camera3D(subUniverse); + subInit(subUniverse, subCamera); + subCamera.adjust(0L); + subContainer.getPrimaryRWTCanvas3D().attachCamera(subCamera); + subUniverse.compile(); + } else { + frame.setContentPane(subContainer); + subContainer.repaint(); + } + } + + // �퓬�p��ʂ��烁�C����ʂւ̐؂�ւ� + protected void changeToMainContainer() { + frame.setContentPane(container); + container.repaint(); + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + // �ȉ��ɃL�[����̃v���O���������� + Velocity3D curV = player.getVelocity(); + if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { + player.setDirection(new Vector3d(-1.0, 0.0, 0.0)); + curV.setX(-10.0); + curV.setZ(0.0); + } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { + player.setDirection(new Vector3d(1.0, 0.0, 0.0)); + curV.setX(10.0); + curV.setZ(0.0); + } else if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { + player.setDirection(new Vector3d(0.0, 0.0, -1.0)); + curV.setZ(-10.0); + curV.setX(0.0); + } else if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { + player.setDirection(new Vector3d(0.0, 0.0, 1.0)); + curV.setZ(10.0); + curV.setX(0.0); + } else { + curV.setX(0.0); + curV.setZ(0.0); + } + player.setVelocity(curV); + + // �v���C���[�𓮂��� + player.motion(interval, stage); + + // �Փ˔��� + if (PhysicsUtility.checkCollision(player.body, null, king.body, null) != null) { + // �v���C���[�Ɖ��l���Ԃ‚������ꍇ + scenario.fire("���l�ƂԂ‚���"); // �u���l�ƂԂ‚���v�Ƃ����C�x���g�𔭐�����i�V�i���I���i�ށj + } + } + + @Override + public void action(String action, Event event, ScenarioState nextState) { + // �V�i���I�i�s�ɂ�鐢�E�ւ̍�p�������ɏ��� + if (action.equals("startFight")) { + changeToSubContainer(); + } else if (action.equals("endFight")) { + changeToMainContainer(); + } + } + + /** + * �Q�[���̃��C�� + * @param args + */ + public static void main(String[] args) { + TemplateScenarioGame game = new TemplateScenarioGame(); + game.start(); + } +} diff --git a/src/main/java/template/racing/Automobile.java b/src/main/java/template/racing/Automobile.java new file mode 100644 index 0000000..72301e8 --- /dev/null +++ b/src/main/java/template/racing/Automobile.java @@ -0,0 +1,342 @@ +package template.racing; + +import java.util.ArrayList; + +import javax.media.j3d.Transform3D; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; + +import framework.animation.Animation3D; +import framework.gameMain.OvergroundActor; +import framework.model3D.Position3D; +import framework.physics.AngularVelocity3D; +import framework.physics.Force3D; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Solid3D; +import framework.physics.Velocity3D; + +public class Automobile extends OvergroundActor { + double frontWheelRot; // �O�֊p�x + double maxSpeed = 90.0; // �ō����x(m/s) + double maxSteering = Math.PI * 0.25; // �ő�NJp + double mass = 1100; // �ԏd + + static final double halfWheelbase = 2.45 / 2.0; // �z�C�[���x�[�X + static final double a = 8041.0; // �쓮�� + static final double b = 88.9; // ���������x�i127�~���C�W���j + static final double b2 = 10.0; // ���R�����W�� + static final double s = 3.0; // �T�C�h�t�H�[�X�ő�Î~���C�W�� + static final double s2 = 0.8; // �T�C�h�t�H�[�X�����C�W�� + static final Vector3d eX = new Vector3d(1.0, 0.0, 0.0); + static final Vector3d eY = new Vector3d(0.0, 1.0, 0.0); + + ArrayList forces = new ArrayList(); + ArrayList appPoints = new ArrayList(); + + public static final double EPSILON = 2.220446049250313E-16d; + + public Automobile(Solid3D body, Animation3D animation) { + super(body, animation); + body.setMass(mass); // �ԏd1t + setInitialDirection(eX); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + appPoints.add(body.getGravityCenter()); + appPoints.add(body.getGravityCenter()); + appPoints.add(body.getGravityCenter()); + appPoints.add(body.getGravityCenter()); + appPoints.add(body.getGravityCenter()); + appPoints.add(body.getGravityCenter()); + } + + /** + * �A�N�Z���𓥂�ʼn������� + */ + public void accelrate() { + // �쓮�͂̌v�Z�i�O�ւ������Ă�������ɉ�������j + if (getFrontWheelVelocity().getVector3d().length() > maxSpeed) return; // �ō����x�𒴂����ꍇ + Vector3d frontWheelDir = getFrontWheelDir(); // �O�ւ̕����x�N�g�� + frontWheelDir.scale(a); + forces.set(0, new Force3D(frontWheelDir)); + + // �O�ւ̈ʒu�i�쓮�͂̍�p�_�ɂȂ�j + appPoints.set(0, getFrontPosition()); + } + + /** + * �u���[�L�𓥂�Ō������� + */ + public void brake() { + // �O�ւ̐����͂̌v�Z + Vector3d frontWheelDir = getFrontWheelDir(); // �O�ւ̕����x�N�g�� + double dir = frontWheelDir.dot(getFrontWheelVelocity().getVector3d()); + if (dir > EPSILON) { + dir = 1.0; + } else if (dir < -EPSILON) { + dir = -1.0; + } else { + dir = 0.0; + } + frontWheelDir.scale(-b * dir * ((Solid3D)body).getMass()); + forces.set(3, new Force3D(frontWheelDir)); + + // �O�ւ̈ʒu�i�O�ւ̐����͂̍�p�_�ɂȂ�j + appPoints.set(3, getFrontPosition()); + + // ��ւ̐����͂̌v�Z + Vector3d rearWheelDir = getDirection(); // ��ւ̕����x�N�g�� + dir = rearWheelDir.dot(getRearWheelVelocity().getVector3d()); + if (dir > EPSILON) { + dir = 1.0; + } else if (dir < -EPSILON) { + dir = -1.0; + } else { + dir = 0.0; + } + rearWheelDir.scale(-b * dir * ((Solid3D)body).getMass()); + forces.set(4, new Force3D(rearWheelDir)); + + // ��ւ̈ʒu�i��ւ̐����͂̍�p�_�ɂȂ�j + appPoints.set(4, getRearPosition()); + } + + /** + * �A�N�Z�����u���[�L�������ăG���W���u���[�L���|���� + * @param interval + */ + public void engineBrake(long interval) { + // �O�ւ̐����͂̌v�Z + Vector3d frontWheelDir = getFrontWheelDir(); // �O�ւ̕����x�N�g�� + double dir = frontWheelDir.dot(getFrontWheelVelocity().getVector3d()); + if (dir > EPSILON) { + dir = 1.0; + } else if (dir < -EPSILON) { + dir = -1.0; + } else { + dir = 0.0; + } + frontWheelDir.scale(-b2 * dir * ((Solid3D)body).getMass()); + forces.set(3, new Force3D(frontWheelDir)); + + // �O�ւ̈ʒu�i�O�ւ̐����͂̍�p�_�ɂȂ�j + appPoints.set(3, getFrontPosition()); + + // ��ւ̐����͂̌v�Z + Vector3d rearWheelDir = getDirection(); // ��ւ̕����x�N�g�� + dir = rearWheelDir.dot(getRearWheelVelocity().getVector3d()); + if (dir > EPSILON) { + dir = 1.0; + } else if (dir < -EPSILON) { + dir = -1.0; + } else { + dir = 0.0; + } + rearWheelDir.scale(-b2 * dir * ((Solid3D)body).getMass()); + forces.set(4, new Force3D(rearWheelDir)); + + // ��ւ̈ʒu�i��ւ̐����͂̍�p�_�ɂȂ�j + appPoints.set(4, getRearPosition()); + } + + /** + * �n���h�������ɐ؂� + * @param interval + */ + public void turnLeft(long interval) { + if (frontWheelRot <= -maxSteering) { + // �ő�NJp�𒴂��� + frontWheelRot = -maxSteering; + return; + } + frontWheelRot -= 4.0 * (double) (interval / 1000.0); // �O�ւ̉�]�p�x + + } + + /** + * �n���h�����E�ɐ؂� + * @param interval + */ + public void turnRight(long interval) { + if (frontWheelRot >= maxSteering) { + // �ő�NJp�𒴂��� + frontWheelRot = maxSteering; + return; + } + frontWheelRot += 4.0 * (double) (interval / 1000.0); // �O�ւ̉�]�p�x + } + + /** + * �n���h���𗣂��Ď��R�Ɍ��̈ʒu�ɕ��������� + * @param interval + */ + public void steeringSelfCentering(long interval) { + if (frontWheelRot > EPSILON) { + frontWheelRot -= 2.0 * (double) (interval / 1000.0); + + } else if (frontWheelRot < -EPSILON) { + frontWheelRot += 2.0 * (double) (interval / 1000.0); + + } else { + frontWheelRot = 0.0; + } + } + + public void motion(long interval, Ground ground) { + if (interval == 0L) return; + + // �O�ւɂ��T�C�h�t�H�[�X�̌v�Z + Vector3d frontWheelDir = getFrontWheelDir(); // �O�ւ̕����x�N�g�� + Vector3d frontWheelSideDir = new Vector3d(); + frontWheelSideDir.cross(eY, frontWheelDir); // �O�ւ̉������x�N�g�� + Vector3d frontWheelVelocity = getFrontWheelVelocity().getVector3d(); + double frontWheelSideSlip = frontWheelSideDir.dot(frontWheelVelocity); // �O�ւ̉����葬�x + double omega = ((Solid3D)body).getAngularVelocity().getVector3d().dot(eY); // �p���x + frontWheelSideSlip -= frontWheelDir.dot(frontWheelVelocity) * Math.tan(omega / 2.0 * ((double)interval / 1000.0)); // �ԑ̂̉�]�ɔ����O�ւ̉�]�̌��ʂ��������� + double frontWheelSideForce; // �O�ւ̉������̖��C�� + // �Î~���C�W���̌v�Z + double frontWheelSideAccel = frontWheelSideSlip / ((double)interval / 1000.0); // �����Ă��Ȃ���Ԃ�����������Ɖ��肷�� + if (frontWheelSideAccel > s * PhysicsUtility.GRAVITY) { + // �ő�Î~���C�W���𒴂����ꍇ�A�����C�͂̌v�Z�ɐ؂�ւ� + frontWheelSideForce = -s2 * PhysicsUtility.getGravity((Solid3D)body).getSeverity(); +//System.out.println("�O�֗\�������葬�x(�����C�ɐ؂�ւ�):" + frontWheelSideAccel); + } else if (frontWheelSideAccel < -s * PhysicsUtility.GRAVITY) { + // �ő�Î~���C�W���𒴂����ꍇ�A�����C�͂̌v�Z�ɐ؂�ւ� + frontWheelSideForce = s2 * PhysicsUtility.getGravity((Solid3D)body).getSeverity(); +//System.out.println("�O�֗\�������葬�x(�����C�ɐ؂�ւ�):" + frontWheelSideAccel); + } else { + // �ő�Î~���C�W���ȓ��̏ꍇ�i�������̑��x��ł������j + frontWheelSideForce = -frontWheelSideAccel * ((Solid3D)body).getMass(); +//System.out.println("�O�֗\�������葬�x:" + frontWheelSideAccel); + } + frontWheelSideDir.scale(frontWheelSideForce); + forces.set(1, new Force3D(frontWheelSideDir)); + + // �O�ւ̈ʒu�i�O�ւɑ΂���T�C�h�t�H�[�X�̍�p�_�ɂȂ�j + appPoints.set(1, getFrontPosition()); + + // ��ւɂ��T�C�h�t�H�[�X�̌v�Z + Vector3d rearWheelDir = getDirection(); // ��ւ̕����x�N�g�� + Vector3d rearWheelSideDir = new Vector3d(); + rearWheelSideDir.cross(eY, rearWheelDir); // ��ւ̉������x�N�g�� + Vector3d rearWheelVelocity = getRearWheelVelocity().getVector3d(); + double rearWheelSideSlip = rearWheelSideDir.dot(rearWheelVelocity); // ��ւ̉����葬�x + rearWheelSideSlip -= rearWheelDir.dot(rearWheelVelocity) * Math.tan(omega / 2.0 * ((double)interval / 1000.0)); // �ԑ̂̉�]�ɔ�����ւ̉�]�̌��ʂ��������� + double rearWheelSideForce; // ��ւ̉������̖��C�� + // �Î~���C�W���̌v�Z + double rearWheelSideAccel = rearWheelSideSlip / ((double)interval / 1000.0); // �����Ă��Ȃ���Ԃ�����������Ɖ��肷�� + if (rearWheelSideAccel > s * PhysicsUtility.GRAVITY) { + // �ő�Î~���C�W���𒴂����ꍇ�A�����C�͂̌v�Z�ɐ؂�ւ� + rearWheelSideForce = -s2 * PhysicsUtility.getGravity((Solid3D)body).getSeverity(); +//System.out.println("��֗\�������葬�x(�����C�ɐ؂�ւ�):" + rearWheelSideAccel); + } else if (rearWheelSideAccel < -s * PhysicsUtility.GRAVITY) { + // �ő�Î~���C�W���𒴂����ꍇ�A�����C�͂̌v�Z�ɐ؂�ւ� + rearWheelSideForce = s2 * PhysicsUtility.getGravity((Solid3D)body).getSeverity(); +//System.out.println("��֗\�������葬�x(�����C�ɐ؂�ւ�):" + rearWheelSideAccel); + } else { + // �ő�Î~���C�W���ȓ��̏ꍇ�i�������̑��x��ł������j + rearWheelSideForce = -rearWheelSideAccel * ((Solid3D)body).getMass(); +//System.out.println("��֗\�������葬�x:" + rearWheelSideAccel); + } + rearWheelSideDir.scale(rearWheelSideForce); + forces.set(2, new Force3D(rearWheelSideDir)); + + // ��ւ̈ʒu�i��ւɑ΂���T�C�h�t�H�[�X�̍�p�_�ɂȂ�j + appPoints.set(2, getRearPosition()); + +//System.out.println(frontWheelRot); + + // �������Z�A�Փ˔���A�Փˉ��� + super.motion(interval, ground, forces, appPoints); + + // �v�Z���I�������N���A������ɔ����� + forces.clear(); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + forces.add(Force3D.ZERO); + appPoints.clear(); + appPoints.add(((Solid3D) body).getGravityCenter()); + appPoints.add(((Solid3D) body).getGravityCenter()); + appPoints.add(((Solid3D) body).getGravityCenter()); + appPoints.add(((Solid3D) body).getGravityCenter()); + appPoints.add(((Solid3D) body).getGravityCenter()); + appPoints.add(((Solid3D) body).getGravityCenter()); + } + + /** + * �O�ւ̈ʒu�����߂� + * @return �O�ւ̈ʒu + */ + private Position3D getFrontPosition() { + Vector3d front = ((Solid3D) body).getGravityCenter().getVector3d(); + Vector3d direction = getDirection(); + direction.normalize(); + direction.scale(halfWheelbase); + front.add(direction); + return new Position3D(front); + } + + /** + * ��ւ̈ʒu�����߂� + * @return ��ւ̈ʒu + */ + private Position3D getRearPosition() { + Vector3d rear = ((Solid3D) body).getGravityCenter().getVector3d(); + Vector3d direction = getDirection(); + direction.normalize(); + direction.scale(-halfWheelbase); + rear.add(direction); + return new Position3D(rear); + } + + /** + * �O�ւ̕����x�N�g�������߂� + * @return �O�ւ̕����x�N�g�� + */ + private Vector3d getFrontWheelDir() { + Vector3d ftV; + ftV = getDirection(); + Transform3D trans = new Transform3D(); + trans.rotY(-frontWheelRot); + trans.transform(ftV); + return ftV; + } + + /** + * �O�ւ̑��x�x�N�g�������߂� + * @return �O�ւ̑��x�x�N�g�� + */ + private Velocity3D getFrontWheelVelocity() { + Velocity3D velocity = ((Solid3D) body).getVelocity(); + Vector3d angularVelocity = ((Solid3D) body).getAngularVelocity() + .getVector3d(); + Vector3d direction = getDirection(); + direction.normalize(); + direction.scale(halfWheelbase); + angularVelocity.cross(angularVelocity, direction); // �p���x�x�N�g���ƒ��S����̈ʒu�x�N�g���̊O�ς����]�ɂ�鑊�Α��x�ɂȂ� + return velocity.add(angularVelocity); + } + + /** + * ��ւ̑��x�x�N�g�������߂� + * @return ��ւ̑��x�x�N�g�� + */ + private Velocity3D getRearWheelVelocity() { + Velocity3D velocity = ((Solid3D) body).getVelocity(); + Vector3d angularVelocity = ((Solid3D) body).getAngularVelocity() + .getVector3d(); + Vector3d direction = getDirection(); + direction.normalize(); + direction.scale(-halfWheelbase); + angularVelocity.cross(angularVelocity, direction); // �p���x�x�N�g���ƒ��S����̈ʒu�x�N�g���̊O�ς����]�ɂ�鑊�Α��x�ɂȂ� + return velocity.add(angularVelocity); + } +} diff --git a/src/main/java/template/racing/TemplateRacing.java b/src/main/java/template/racing/TemplateRacing.java new file mode 100644 index 0000000..533970e --- /dev/null +++ b/src/main/java/template/racing/TemplateRacing.java @@ -0,0 +1,190 @@ +package template.racing; + +import java.awt.Image; +import java.awt.image.BufferedImage; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.ColoringAttributes; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.ImageComponent2D; +import javax.media.j3d.Material; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.Texture; +import javax.media.j3d.Texture2D; +import javax.media.j3d.TextureAttributes; +import javax.media.j3d.TextureUnitState; +import javax.swing.ImageIcon; +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; +import javax.vecmath.Vector4f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTVirtualController; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.MultiViewGame; +import framework.gameMain.OvergroundActor; +import framework.model3D.BackgroundBox; +import framework.model3D.Model3D; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Quaternion3D; +import framework.model3D.Terrain3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.Solid3D; +import framework.physics.Velocity3D; +import framework.test.TestMultiView; +import framework.view3D.Camera3D; + +public class TemplateRacing extends MultiViewGame { + Automobile car1; + Automobile car2; + Ground ground; + + @Override + public void init(Universe universe, Camera3D camera1, Camera3D camera2) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight + .setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(amblight); + + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight + .setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + universe.placeLight(dirlight); + + Model3D carModel = ModelFactory.loadModel("data\\GTR\\GTR.wrl", + false, true); + + Object3D carBody1 = carModel.createObject(); + car1 = new Automobile(new Solid3D(carBody1), null); + car1.body.apply(new Position3D(200.0, 3.0, 50.0), false); + universe.place(car1); + + Object3D carBody2 = carModel.createObject(); + car2 = new Automobile(new Solid3D(carBody2), null); + car2.body.apply(new Position3D(-150.0, 3.0, 50.0), false); + universe.place(car2); + + camera1.addTarget(car1); + camera1.setViewLine(car1.getDirection()); + camera1.setCameraBack(new Vector3d(0.0, 3.0, 5.0)); + camera1.setFieldOfView(1.5); + + camera2.addTarget(car2); + camera2.setViewLine(car2.getDirection()); + camera2.setCameraBack(new Vector3d(0.0, 3.0, 5.0)); + camera2.setFieldOfView(1.5); + + Object3D stageObj = + ModelFactory.loadModel("data\\Road\\RoadStage.WRL").createObject(); + ground = new Ground(stageObj); + universe.place(ground); + + buildSkyBox(universe); + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + // TODO Auto-generated method stub + if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { + car1.turnLeft(interval); + } else if (virtualController + .isKeyDown(0, RWTVirtualController.RIGHT)) { + car1.turnRight(interval); + } else { + car1.steeringSelfCentering(interval); + } + if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { + car1.brake(); + } else if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { + car1.accelrate(); + } else { + car1.engineBrake(interval); + } + car1.motion(interval, ground); + camera1.setViewLine(car1.getDirection()); + + if (virtualController.isKeyDown(1, RWTVirtualController.LEFT)) { + car2.turnLeft(interval); + } else if (virtualController + .isKeyDown(1, RWTVirtualController.RIGHT)) { + car2.turnRight(interval); + } else { + car2.steeringSelfCentering(interval); + } + if (virtualController.isKeyDown(1, RWTVirtualController.DOWN)) { + car2.brake(); + } else if (virtualController.isKeyDown(1, RWTVirtualController.UP)) { + car2.accelrate(); + } else { + car2.engineBrake(interval); + } + car2.motion(interval, ground); + camera2.setViewLine(car2.getDirection()); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setTitle("RadishRacing"); +// f.setShadowCasting(true); + return f; + } + + /** + * @param args + */ + public static void main(String[] args) { + TemplateRacing game = new TemplateRacing(); + game.start(); + + } + + private void buildSkyBox(Universe universe) { +// TextureLoader loaderTop = new TextureLoader("data\\texture\\top.jpg", +// TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture textureTop = loaderTop.getTexture(); +// TextureLoader loaderBottom = new TextureLoader( +// "data\\texture\\bottom.jpg", TextureLoader.BY_REFERENCE +// | TextureLoader.Y_UP, null); +// Texture textureBottom = loaderBottom.getTexture(); +// TextureLoader loaderNorth = new TextureLoader( +// "data\\texture\\north.jpg", TextureLoader.BY_REFERENCE +// | TextureLoader.Y_UP, null); +// Texture textureNorth = loaderNorth.getTexture(); +// TextureLoader loaderSouth = new TextureLoader( +// "data\\texture\\south.jpg", TextureLoader.BY_REFERENCE +// | TextureLoader.Y_UP, null); +// Texture textureSouth = loaderSouth.getTexture(); +// TextureLoader loaderWest = new TextureLoader("data\\texture\\west.jpg", +// TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture textureWest = loaderWest.getTexture(); +// TextureLoader loaderEast = new TextureLoader("data\\texture\\east.jpg", +// TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); +// Texture textureEast = loaderEast.getTexture(); +// +// BackgroundBox background = new BackgroundBox(textureNorth, textureWest, +// textureSouth, textureEast, textureTop, textureBottom); +// BoundingSphere bs = new BoundingSphere(); +// bs.setRadius(1000); +// background.setApplicationBounds(bs); +// universe.place(background); + } +} diff --git a/src/main/java/template/shooting/BattleField.java b/src/main/java/template/shooting/BattleField.java new file mode 100644 index 0000000..7977a43 --- /dev/null +++ b/src/main/java/template/shooting/BattleField.java @@ -0,0 +1,417 @@ +package template.shooting; + +import java.awt.Container; +import java.util.ArrayList; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Light; +import javax.media.j3d.Node; +import javax.vecmath.Tuple3f; +import javax.vecmath.Vector3d; + +import framework.AI.GeometryGraph; +import framework.AI.IState; +import framework.AI.Location; +import framework.model3D.BaseObject3D; +import framework.model3D.CollisionResult; +import framework.model3D.GeometryCollector; +import framework.model3D.Object3D; +import framework.model3D.Placeable; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; + +/** + * �v���C���[�ƓG��������� + * @author �V�c���� + * + */ +public class BattleField { + private Universe universe; + private Ground stage; + private Player player; + private ArrayList enemies = new ArrayList(); + private ArrayList playersBullets = new ArrayList(); + private ArrayList enemiesBullets = new ArrayList(); + private GeometryGraph geometryGraph = null; + private PlayersBulletModel playersBulletModel; + private EnemyModel enemyModel; + private EnemiesBulletModel enemiesBulletModel; + private boolean bPlayerHit = false; + private int hitEnemyCount = 0; + + // �萔 + public static final int MAX_ENEMIES = 4; // �G�̍ő吔 + + public BattleField(Universe universe) { + this.universe = universe; + + // �����̒e�̃��f�����쐬 + playersBulletModel = new PlayersBulletModel("data\\models\\bullet.3ds", null); + + // �G�̃��f�����쐬 + enemyModel = new EnemyModel("data\\Head4.wrl", "data\\pocha\\walk.wrl"); + + // �G�̒e�̃��f�����쐬 + enemiesBulletModel = new EnemiesBulletModel("data\\pocha\\bubble.wrl", null); + } + + /** + * �I�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void place(Node obj) { + universe.place(obj); + } + + /** + * �I�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void place(Placeable obj) { + if (obj instanceof Player) { + player = (Player)obj; + } else if (obj instanceof Ground) { + stage = (Ground)obj; + GeometryCollector v = new GeometryCollector(); + BaseObject3D baseObj = stage.getBody(); + if (baseObj instanceof Object3D) { + if (obj instanceof Stage) { + baseObj = ((Object3D)baseObj).getPart(((Stage)obj).getTerrainPart()); + } + ((Object3D)baseObj).accept(v); + geometryGraph = new GeometryGraph(v.getGeometry()); + } + } + universe.place(obj); + } + + /** + * ��Ŏ�菜����悤�ɃI�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeDisplacable(Node obj) { + universe.placeDisplacable(obj); + } + + /** + * ��Ŏ�菜����悤�ɃI�u�W�F�N�g��z�u���� + * @param obj �z�u����I�u�W�F�N�g + */ + public void placeDisplacable(Placeable obj) { + universe.placeDisplacable(obj); + } + + /** + * �����̒lj� + * @param light �lj�������� + */ + public void placeLight(Light light) { + universe.place(light); + } + + /** + * ���ׂĂ̍\���v�f����Ăɓ����� + * @param interval �O��Ăяo���ꂽ�Ƃ�����̌o�ߎ��ԁi�~���b�j + */ + public void motion(long interval) { + // �v���C���[�𓮂��� + player.motion(interval, stage); + + // ���ׂĂ̓G�𓮂����Ɠ����ɁA�v���C���[�ƏՓ˔��肵�A�X�ɓG�̒e�𔭎˂��� + for (int n = 0; n < enemies.size(); n++) { + Enemy enemy = enemies.get(n); // �G����̎��o�� + enemy.motion(interval, stage, player, geometryGraph); // �G�𓮂��� + + // �G�ƃv���C���[�̏Փ˔��� + CollisionResult collisionResult = PhysicsUtility.checkCollision( + enemy.body, null, + player.body, null); + if (collisionResult != null) { + // �v���C���[�ɓ������� + bPlayerHit = true; + } + } + + // ���ׂẴv���C���[�̒e�𓮂����Ɠ����ɁA�G�ƏՓ˔��� + for (int n = 0; n < playersBullets.size(); n++) { + PlayersBullet bullet = playersBullets.get(n); // �v���C���[�̒e����Ž��o�� + if (bullet.isAlive()) { + bullet.motion(interval, stage); // �v���C���[�̒e�𓮂��� + + for (int m = 0; m < enemies.size(); m++) { + Enemy enemy = enemies.get(m); // �G����̎��o�� + // �v���C���[�̒e�ƓG�̏Փ˔��� + CollisionResult collisionResult = PhysicsUtility.checkCollision( + bullet.body, null, + enemy.body, null); + if (collisionResult != null) { + // �G�ɓ������� + removeEnemy(enemy); // �G������ + removePlayersBullet(bullet); // ���������e������ + n--; + hitEnemyCount++; + break; + } + } + } else { + removePlayersBullet(bullet); // �e������ + n--; + } + } + + // ���ׂĂ̓G�̒e�𓮂����Ɠ����ɁA�v���C���[�ƏՓ˔��� + for (int n = 0; n < enemiesBullets.size(); n++) { + EnemiesBullet bullet = enemiesBullets.get(n); // �G�̒e����Ž��o�� + if (bullet.isAlive()) { + bullet.motion(interval, stage); // �G�̒e�𓮂��� + + // �G�̒e�ƃv���C���[�̏Փ˔��� + CollisionResult collisionResult = PhysicsUtility.checkCollision( + bullet.body, null, + player.body, null); + if (collisionResult != null) { + // �v���C���[�ɓ������� + removeEnemiesBullet(bullet); // ���������e������ + n--; + bPlayerHit = true; + break; + } + } else { + // �e���ǂɓ��������肵�ď������ꍇ + removeEnemiesBullet(bullet); + n--; + } + } + } + + /** + * �v���C���[�̈ʒu���擾���� + * @return �v���C���[�̈ʒu�x�N�g�� + */ + public Position3D getPlayerPosition() { + return player.getPosition(); + } + + /** + * �v���C���[�̈ʒu��ݒ肷�� + * @param pos �v���C���[�̈ʒu�x�N�g�� + */ + public void setPlayerPosition(Position3D pos) { + player.setPosition(pos); + } + + /** + * �v���C���[�����E�ɉ�]������ + * @param ang ��]�p�x�i���W�A���A�����������j + */ + public void playerTurn(double ang) { + player.rotY(ang); + } + + /** + * �v���C���[�����݌����Ă�������ɕ������� + * @param vel �������x + */ + public void playerWalk(double vel) { + Velocity3D curV = player.getVelocity(); + curV.setX(player.getDirection().getX() * vel); + curV.setZ(player.getDirection().getZ() * vel); + player.setVelocity(curV); + } + + /** + * �v���C���[��Î~������ + */ + public void playerStop() { + playerWalk(0.0); + } + + /** + * �v���C���[���W�����v������ + * @param vel �W�����v����ۂ̏����x + */ + public void playerJump(double vel) { + Velocity3D curV = player.getVelocity(); + curV.setY(vel); + player.setVelocity(curV); + } + + /** + * �v���C���������Ă���������擾���� + * @return �v���C���[�������Ă�������x�N�g�� + */ + public Vector3d getPlayerDirection() { + return player.getDirection(); + } + + /** + * �v���C���[���w�肵�������Ɍ������� + * @param dir �v���C���[��������������x�N�g�� + */ + public void setPlayerDirection(Vector3d dir) { + player.setDirection(dir); + } + + /** + * �v���C���[�̌��݂̈ړ����x���擾���� + * @return �v���C���[�̈ړ����x�x�N�g�� + */ + public Velocity3D getPlayerVelocity() { + return player.getVelocity(); + } + + /** + * �v���C���[�̈ړ����x��ݒ肷�� + * @param vel �v���C���[�ɐݒ肷��ړ����x�x�N�g�� + */ + public void setPlayerVelocity(Velocity3D vel) { + player.setVelocity(vel); + } + + /** + * �v���C���[���n�ʂ̏�ɏ���Ă��邩�ǂ����𔻒肷�� + * @return true --- �n�ʂ̏�ɏ���Ă���, false --- ���ɕ����Ă��� + */ + public boolean isPlayerOnGround() { + return player.isOnGround(); + } + + /** + * �v���C���[�ɒe���������� + */ + public void playerShoots() { + PlayersBullet bullet = playersBulletModel.createPlayersBullet(); + Vector3d bulletVelocity = (Vector3d)player.getDirection().clone(); + bulletVelocity.normalize(); + bulletVelocity.scale(10.0); + bullet.setVelocity(new Velocity3D(bulletVelocity)); + bullet.setPosition(player.getPosition().add(0.0, 1.0, 0.0)); + addPlayersBullet(bullet); + } + + /** + * �v���C���[���U�����󂯂����H + * @return true --- �U�����󂯂�, false --- �U�����󂯂Ă��Ȃ� + */ + public boolean isPlayerHit() { + boolean hit = bPlayerHit; + bPlayerHit = false; + return hit; + } + + /** + * �G�𔭐������� + * @return ���������G�̃I�u�W�F�N�g + */ + public Enemy createEnemy() { + if (getEnemyCount() < MAX_ENEMIES) { + Enemy newEnemy = enemyModel.createEnemy(); + ArrayList locations = geometryGraph.getStates(); + Location startLoc; + for (;;) { + startLoc = (Location)locations.get((int)(Math.random() * locations.size())); + if (startLoc.getNormal().dot(new Vector3d(0.0, 1.0, 0.0)) >= 0.95) break; + } + newEnemy.setPosition(new Position3D(new Vector3d(startLoc.getCenter())).add(0.0, 2.0, 0.0)); + addEnemy(newEnemy); + return newEnemy; + } + return null; + } + + /** + * �G�̑������擾���� + * @return �G�̑��� + */ + public int getEnemyCount() { + return enemies.size(); + } + + /** + * �w�肵���ԍ��̓G���擾���� + * @param n �G�̔ԍ�(0�`) + * @return �G�̃I�u�W�F�N�g + */ + public Enemy getEnemy(int n) { + return enemies.get(n); + } + + /** + * �G������ + * @param enemy �����G + */ + public void removeEnemy(Enemy enemy) { + enemies.remove(enemy); + universe.displace(enemy); + } + + /** + * �����őI�񂾓G�ɒe���������� + */ + public void enemyShoots() { + if (enemies.size() > 0) { + Enemy enemy = enemies.get((int)(Math.random() * (double)enemies.size())); + EnemiesBullet enemiesBullet = enemy.shoot(player, enemiesBulletModel); + addEnemiesBullet(enemiesBullet); + } + } + + /** + * �|�����G�̐����擾���� + * @return �V���ɓ|�����G�̐� + */ + public int getHitEnemyCount() { + int hit = hitEnemyCount; + hitEnemyCount = 0; + return hit; + } + + /** + * �G��o�ꂳ���� + * @param enemy�@�o�ꂷ��G + */ + private void addEnemy(Enemy enemy) { + enemies.add(enemy); + universe.placeDisplacable(enemy); + } + + /** + * �v���C���[�̒e�𔭎˂��� + * @param playersBullet ���˂���v���C���[�̒e + */ + private void addPlayersBullet(PlayersBullet playersBullet) { + playersBullets.add(playersBullet); + universe.placeDisplacable(playersBullet); + } + + /** + * �G�̒e�𔭎˂��� + * @param enemy ���˂���G + */ + private void addEnemiesBullet(EnemiesBullet enemiesBullet) { + enemiesBullets.add(enemiesBullet); + universe.placeDisplacable(enemiesBullet); + } + + /** + * �v���C���[�̒e������ + * @param playersBullet �����e + */ + private void removePlayersBullet(PlayersBullet playersBullet) { + playersBullets.remove(playersBullet); + universe.displace(playersBullet); + } + + /** + * �G�̒e������ + * @param enemiesBullet �����e + */ + private void removeEnemiesBullet(EnemiesBullet enemiesBullet) { + enemiesBullets.remove(enemiesBullet); + universe.displace(enemiesBullet); + } +} diff --git a/src/main/java/template/shooting/EnemiesBullet.java b/src/main/java/template/shooting/EnemiesBullet.java new file mode 100644 index 0000000..d4e0b57 --- /dev/null +++ b/src/main/java/template/shooting/EnemiesBullet.java @@ -0,0 +1,58 @@ +package template.shooting; + +import framework.AI.GeometryGraph; +import framework.animation.Animation3D; +import framework.gameMain.Actor; +import framework.model3D.CollisionResult; +import framework.model3D.Object3D; +import framework.physics.Force3D; +import framework.physics.Ground; + +/** + * �G�̒e + * @author �V�c���� + * + */ +public class EnemiesBullet extends Actor { + private boolean bAlive = true; + private long left = 0; + + // �萔 + public static final long LIFE_TIME = 2000L; // �e�̎��� + + public EnemiesBullet(Object3D body, Animation3D animation) { + super(body, animation); + left = LIFE_TIME; + } + + public void motion(long interval, Ground ground) { + left -= interval; + if (left < 0L) { + bAlive = false; + } + super.motion(interval, ground); + } + + @Override + public void onEndFall() { + } + + @Override + public void onIntersect(CollisionResult normal, long interval) { + bAlive = false; + } + + @Override + public void onEndAnimation() { + } + + @Override + public Force3D getGravity() { + // �e�͗������Ȃ��̂ŏd�͂��[���Ƃ��� + return Force3D.ZERO; + } + + public boolean isAlive() { + return bAlive; + } +} diff --git a/src/main/java/template/shooting/EnemiesBulletModel.java b/src/main/java/template/shooting/EnemiesBulletModel.java new file mode 100644 index 0000000..d35fbc6 --- /dev/null +++ b/src/main/java/template/shooting/EnemiesBulletModel.java @@ -0,0 +1,24 @@ +package template.shooting; + +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.ActorModel; +import framework.physics.Solid3D; + +public class EnemiesBulletModel extends ActorModel { + String animationFileName = null; + Animation3D animation = null; + + public EnemiesBulletModel(String modelFileName, String animationFileName) { + super(modelFileName); + this.animationFileName = animationFileName; + } + + public EnemiesBullet createEnemiesBullet() { + Solid3D body = new Solid3D(getModel().createObject()); + if (animationFileName != null && animation == null) { + animation = AnimationFactory.loadAnimation(animationFileName); + } + return new EnemiesBullet(body, animation); + } +} diff --git a/src/main/java/template/shooting/Enemy.java b/src/main/java/template/shooting/Enemy.java new file mode 100644 index 0000000..65ff031 --- /dev/null +++ b/src/main/java/template/shooting/Enemy.java @@ -0,0 +1,113 @@ +package template.shooting; + +import java.util.LinkedList; + +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; + +import framework.AI.AStar; +import framework.AI.GeometryGraph; +import framework.AI.Location; +import framework.AI.Plan; +import framework.animation.Animation3D; +import framework.gameMain.OvergroundActor; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.physics.Ground; +import framework.physics.Velocity3D; + +/** + * �G + * @author �V�c���� + * + */ +public class Enemy extends OvergroundActor { + private AStar aStar = new AStar(); + private Plan plan = null; + + // �萔 + public static final double ENEMY_SPEED = 3.0; + public static final double BULLET_SPEED = 10.0; + + public Enemy(Object3D body, Animation3D animation) { + super(body, animation); + } + + /** + * �P�ʎ��Ԃ��Ƃ̓���i�Փ˔��菈�����s���j + * @param interval --- �O��Ăяo���ꂽ�Ƃ�����̌o�ߎ��ԁi�~���b�P�ʁj + * @param ground --- �n�ʁi�\�����j + * @param player --- �v���C���[�̈ʒu���l�����Ĉړ��v��𗧂Ă�̂ŕK�v + * @param geometryGraph --- �O���t�ɂ���ĒP���������n�� + */ + public void motion(long interval, Ground ground, Player player, GeometryGraph geometryGraph) { + if (!doPlan(plan) || Math.random() < 0.005) { + // �v�悪�������邩�A�C�܂���ŐV�����v��𗧂Ă� + plan = planning(player, geometryGraph); + startPlan(plan); + } + super.motion(interval, ground); + } + + private Plan planning(Player player, GeometryGraph geometryGraph) { + Location startLoc; + Location goalLoc; + startLoc = geometryGraph.getNearestLocation(getPosition()); + goalLoc = geometryGraph.getNearestLocation(player.getPosition()); + Plan aStarPlan = aStar.getPath(startLoc, goalLoc); + if (aStarPlan != null) { + return aStarPlan; // A�X�^�[�A���S���Y�����g�����v�� + } + startLoc = new Location(new Point3d(getPosition().getVector3d())); + goalLoc = new Location(new Point3d(player.getPosition().getVector3d())); + return new Plan(startLoc, goalLoc); // �X�^�[�g�ƃS�[���𒼐��Ō��Ԍv�� + } + + private void startPlan(Plan plan) { + if (plan == null) return; // ���������܂������v��𗧂ĂĂ��Ȃ� + Location nextLoc = plan.getNextLocation(); + if (nextLoc == null) return; // �v��̃S�[���ɒH�蒅���� + // �v���̎��̒ʉߓ_�ڎw���Ĉړ����x�Ƒ̂̌�����ύX + Vector3d direction = new Vector3d(nextLoc.getCenter()); + if (direction.length() > 0.0) { + direction.sub(getPosition().getVector3d()); + direction.normalize(); + direction.scale(ENEMY_SPEED); + setVelocity(new Velocity3D(direction)); // �ړ����x�̐ݒ� + direction.setY(0.0); + direction.normalize(); + setDirection(direction); // �̂̌����̐ݒ� + } + } + + private boolean doPlan(Plan plan) { + if (plan == null) return false; // ���������܂������v��𗧂ĂĂ��Ȃ� + if (plan.updateCurrentLocation(getPosition())) { + Location loc = plan.getCurrentLocation(); + if (loc == null) return false; // �v��̃S�[���ɒH�蒅���� + // �v���̎��̒ʉߓ_�ڎw���Ĉړ����x�Ƒ̂̌�����ύX + Vector3d direction = new Vector3d(loc.getCenter()); + if (direction.length() > 0.0) { + direction.sub(getPosition().getVector3d()); + direction.normalize(); + direction.scale(ENEMY_SPEED); + setVelocity(new Velocity3D(direction)); // �ړ����x�̐ݒ� + direction.setY(0.0); + direction.normalize(); + setDirection(direction); // �̂̌����̐ݒ� + } + } + return true; + } + + public EnemiesBullet shoot(Player player, EnemiesBulletModel enemiesBulletModel) { + EnemiesBullet enemiesBullet = enemiesBulletModel.createEnemiesBullet(); + // �v���C���[���߂����đł� + Vector3d bulletVelocity = player.getPosition().sub(this.getPosition()).getVector3d(); + bulletVelocity.normalize(); + bulletVelocity.scale(BULLET_SPEED); + enemiesBullet.setVelocity(new Velocity3D(bulletVelocity)); + enemiesBullet.setPosition(this.getPosition().add(-0.5, 0.0, 0.0)); + return enemiesBullet; + } +} diff --git a/src/main/java/template/shooting/EnemyModel.java b/src/main/java/template/shooting/EnemyModel.java new file mode 100644 index 0000000..4599713 --- /dev/null +++ b/src/main/java/template/shooting/EnemyModel.java @@ -0,0 +1,24 @@ +package template.shooting; + +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.ActorModel; +import framework.physics.Solid3D; + +public class EnemyModel extends ActorModel { + String animationFileName = null; + Animation3D animation = null; + + public EnemyModel(String modelFileName, String animationFileName) { + super(modelFileName); + this.animationFileName = animationFileName; + } + + public Enemy createEnemy() { + Solid3D body = new Solid3D(getModel().createObject()); + if (animationFileName != null && animation == null) { + animation = AnimationFactory.loadAnimation(animationFileName); + } + return new Enemy(body, animation); + } +} diff --git a/src/main/java/template/shooting/Player.java b/src/main/java/template/shooting/Player.java new file mode 100644 index 0000000..6a6b3d8 --- /dev/null +++ b/src/main/java/template/shooting/Player.java @@ -0,0 +1,17 @@ +package template.shooting; + +import framework.animation.Animation3D; +import framework.gameMain.OvergroundActor; +import framework.model3D.Object3D; + +/** + * �v���C���[ + * @author �V�c���� + * + */ +public class Player extends OvergroundActor { + + public Player(Object3D body, Animation3D animation) { + super(body, animation); + } +} diff --git a/src/main/java/template/shooting/PlayersBullet.java b/src/main/java/template/shooting/PlayersBullet.java new file mode 100644 index 0000000..af8812c --- /dev/null +++ b/src/main/java/template/shooting/PlayersBullet.java @@ -0,0 +1,56 @@ +package template.shooting; + +import framework.animation.Animation3D; +import framework.gameMain.Actor; +import framework.model3D.CollisionResult; +import framework.model3D.Object3D; +import framework.physics.Force3D; +import framework.physics.Ground; + +/** + * �v���C���[�̒e + * @author �V�c���� + * + */ +public class PlayersBullet extends Actor { + private boolean bAlive = true; + private long left = 0; + + // �萔 + public static final long LIFE_TIME = 2000L; // �e�̎��� + + public PlayersBullet(Object3D body, Animation3D animation) { + super(body, null); + left = LIFE_TIME; + } + + public void motion(long interval, Ground ground) { + left -= interval; + if (left < 0L) { + bAlive = false; + } + super.motion(interval, ground); + } + + @Override + public void onEndFall() { + } + + @Override + public void onIntersect(CollisionResult normal, long interval) { + } + + @Override + public void onEndAnimation() { + } + + @Override + public Force3D getGravity() { + // �e�͗������Ȃ��̂ŏd�͂��[���Ƃ��� + return Force3D.ZERO; + } + + public boolean isAlive() { + return bAlive; + } +} diff --git a/src/main/java/template/shooting/PlayersBulletModel.java b/src/main/java/template/shooting/PlayersBulletModel.java new file mode 100644 index 0000000..926e4af --- /dev/null +++ b/src/main/java/template/shooting/PlayersBulletModel.java @@ -0,0 +1,24 @@ +package template.shooting; + +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.ActorModel; +import framework.physics.Solid3D; + +public class PlayersBulletModel extends ActorModel { + String animationFileName = null; + Animation3D animation = null; + + public PlayersBulletModel(String modelFileName, String animationFileName) { + super(modelFileName); + this.animationFileName = animationFileName; + } + + public PlayersBullet createPlayersBullet() { + Solid3D body = new Solid3D(getModel().createObject()); + if (animationFileName != null && animation == null) { + animation = AnimationFactory.loadAnimation(animationFileName); + } + return new PlayersBullet(body, animation); + } +} diff --git a/src/main/java/template/shooting/PreSeminarShooting.java b/src/main/java/template/shooting/PreSeminarShooting.java new file mode 100644 index 0000000..4bd2cc1 --- /dev/null +++ b/src/main/java/template/shooting/PreSeminarShooting.java @@ -0,0 +1,203 @@ +package template.shooting; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.util.ArrayList; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Geometry; +import javax.media.j3d.Texture; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.AI.GeometryGraph; +import framework.AI.IState; +import framework.AI.Location; +import framework.RWT.RWTBoard; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTLabel; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.SimpleGame; +import framework.model3D.BackgroundBox; +import framework.model3D.CollisionResult; +import framework.model3D.GeometryCollector; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; +import framework.view3D.Camera3D; + +/** + * �V���[�e�B���O�Q�[���̂��߂̃e���v���[�g + * @author �V�c���� + * + */ +public class PreSeminarShooting extends SimpleBattleGame { + private boolean bShot = false; + private RWTContainer container; // �v���C��ʂ̃R���e�i + private RWTLabel gameOver = null; // �Q�[���I�[�o�[�\���p + private RWTLabel scoreDisplay = null; // �X�R�A�\���p + private int score = 0; // �X�R�A + + @Override + public void init(BattleField field, Camera3D camera) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + field.placeLight(amblight); + + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + field.placeLight(dirlight); + + // �L�����N�^�[��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); + Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); + Player player = new Player(pochaBody, pochaAnimation); + player.setPosition(new Position3D(120.0, 30.0, 30.0)); + player.setDirection(new Vector3d(0.0, 0.0, 1.0)); + field.place(player); + + // �X�e�[�W��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D stageObj = ModelFactory.loadModel("data\\Neuschwanstein\\Neuschwanstein.wrl").createObject(); + Ground stage = new Ground(stageObj); + field.place(stage); + + // �w�i���쐬���� + buildSkyBox(field); + + // �J�����̐ݒ�i�O�l�̎��_�ɂ���j + camera.addTarget(player); + camera.setCameraBack(new Vector3d(0.0, 4.0, 7.0)); + camera.setViewLine(player.getDirection()); + camera.setFieldOfView(1.5); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setTitle("Pre-Seminar Shooting Game"); + f.setMouseCapture(true); + return f; + } + + protected RWTContainer createRWTContainer() { + container = new RWTContainer() { + @Override + public void build(GraphicsConfiguration gc) { + RWTCanvas3D canvas; + if (gc != null) { + canvas = new RWTCanvas3D(gc, true); + } else { + canvas = new RWTCanvas3D(true); + } + canvas.setRelativePosition(0.0f, 0.0f); + canvas.setRelativeSize(1.0f, 1.0f); + gameOver = new RWTLabel(0.25f, 0.5f, "Game Over!!", Color.RED, new Font("", Font.ITALIC, 36)); + gameOver.setVisible(false); + canvas.addWidget(gameOver); + RWTBoard scoreBoard = new RWTBoard(0.72f, 0.035f, 0.27f, 0.08f, new Color(1.0f, 1.0f, 1.0f, 0.3f)); + scoreBoard.setVisible(true); + canvas.addWidget(scoreBoard); + scoreDisplay = new RWTLabel(0.75f, 0.1f, "Score: " + score, Color.WHITE, new Font("", Font.PLAIN, 20)); + scoreDisplay.setVisible(true); + canvas.addWidget(scoreDisplay); + addCanvas(canvas); + repaint(); + } + // RWT���ł̓C�x���g���������Ȃ� + @Override + public void keyPressed(RWTVirtualKey key) {} + @Override + public void keyReleased(RWTVirtualKey key) {} + @Override + public void keyTyped(RWTVirtualKey key) {} + }; + return container; + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + // ������ �ȉ��ɃL�[����̃v���O���������� ������ + + // ���̂��ׂĂ̓o�ꕨ�i�v���C���[��G�Ȃǁj����Ăɓ����� + battleField.motion(interval); + + // ������ �Q�[���I�[�o�[���ۂ��𔻒肷�� ������ + + // ������ �_���v�Z ������ + + // �J�����̉�] + camera.setViewLine(battleField.getPlayerDirection()); + } + + /** + * �Q�[���̃��C�� + * @param args + */ + public static void main(String[] args) { + PreSeminarShooting game = new PreSeminarShooting(); + game.setFramePolicy(5, 33, false); + game.start(); + } + + /** + * �w�i���쐬���� + * @param field + */ + private void buildSkyBox(BattleField field) { + TextureLoader loaderTop = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureTop = loaderTop.getTexture(); + TextureLoader loaderBottom = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureBottom = loaderBottom.getTexture(); + TextureLoader loaderNorth = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureNorth = loaderNorth.getTexture(); + TextureLoader loaderSouth = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureSouth = loaderSouth.getTexture(); + TextureLoader loaderWest = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureWest = loaderWest.getTexture(); + TextureLoader loaderEast = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureEast = loaderEast.getTexture(); + + BackgroundBox background = new BackgroundBox(textureNorth, textureWest, + textureSouth, textureEast, textureTop, textureBottom); + BoundingSphere bs = new BoundingSphere(); + bs.setRadius(1000); + background.setApplicationBounds(bs); + field.place(background); + } +} diff --git a/src/main/java/template/shooting/SimpleBattleGame.java b/src/main/java/template/shooting/SimpleBattleGame.java new file mode 100644 index 0000000..511bd5d --- /dev/null +++ b/src/main/java/template/shooting/SimpleBattleGame.java @@ -0,0 +1,31 @@ +package template.shooting; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.GraphicsConfigTemplate3D; + +import framework.RWT.RWTContainer; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTVirtualController; +import framework.gameMain.SimpleGame; +import framework.model3D.Universe; +import framework.view3D.Camera3D; + +/** + * �v���C���[�ƓG�������Q�[���i�A�N�V�����Q�[����V���[�e�B���O�Q�[���j�̊�{�N���X + * @author �V�c���� + * + */ +abstract public class SimpleBattleGame extends SimpleGame { + BattleField battleField; + + @Override + public void init(Universe universe, Camera3D camera) { + battleField = new BattleField(universe); + init(battleField, camera); + } + + abstract public void init(BattleField battleField, Camera3D camera); +} diff --git a/src/main/java/template/shooting/Stage.java b/src/main/java/template/shooting/Stage.java new file mode 100644 index 0000000..5b2c1cb --- /dev/null +++ b/src/main/java/template/shooting/Stage.java @@ -0,0 +1,21 @@ +package template.shooting; + +import framework.model3D.BaseObject3D; +import framework.physics.Ground; + +public class Stage extends Ground { + private String terrainPart; + + public Stage(BaseObject3D obj) { + super(obj); + } + + public Stage(BaseObject3D obj, String terrainPart) { + super(obj); + this.terrainPart = terrainPart; + } + + public String getTerrainPart() { + return terrainPart; + } +} diff --git a/src/main/java/template/shooting/TemplateShooting.java b/src/main/java/template/shooting/TemplateShooting.java new file mode 100644 index 0000000..945c624 --- /dev/null +++ b/src/main/java/template/shooting/TemplateShooting.java @@ -0,0 +1,266 @@ +package template.shooting; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.util.ArrayList; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Geometry; +import javax.media.j3d.Texture; +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.image.TextureLoader; + +import framework.AI.GeometryGraph; +import framework.AI.IState; +import framework.AI.Location; +import framework.RWT.RWTBoard; +import framework.RWT.RWTCanvas3D; +import framework.RWT.RWTContainer; +import framework.RWT.RWTFrame3D; +import framework.RWT.RWTLabel; +import framework.RWT.RWTVirtualController; +import framework.RWT.RWTVirtualKey; +import framework.animation.Animation3D; +import framework.animation.AnimationFactory; +import framework.gameMain.SimpleGame; +import framework.model3D.BackgroundBox; +import framework.model3D.CollisionResult; +import framework.model3D.GeometryCollector; +import framework.model3D.ModelFactory; +import framework.model3D.Object3D; +import framework.model3D.Position3D; +import framework.model3D.Universe; +import framework.physics.Ground; +import framework.physics.PhysicsUtility; +import framework.physics.Velocity3D; +import framework.view3D.Camera3D; + +/** + * �V���[�e�B���O�Q�[���̂��߂̃e���v���[�g + * @author �V�c���� + * + */ +public class TemplateShooting extends SimpleBattleGame { + private boolean bShot = false; + private RWTContainer container; // �v���C��ʂ̃R���e�i + private RWTLabel gameOver = null; // �Q�[���I�[�o�[�\���p + private RWTLabel scoreDisplay = null; // �X�R�A�\���p + private int score = 0; // �X�R�A + + @Override + public void init(BattleField field, Camera3D camera) { + // �‹��� + AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); + + amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + field.placeLight(amblight); + + // ���s���� + DirectionalLight dirlight = new DirectionalLight(true, // ����ON/OFF + new Color3f(1.0f, 1.0f, 1.0f), // ���̐F + new Vector3f(0.0f, -1.0f, -0.5f) // ���̕����x�N�g�� + ); + dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); + field.placeLight(dirlight); + + // �L�����N�^�[��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); + Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); + Player player = new Player(pochaBody, pochaAnimation); + player.setPosition(new Position3D(-5.0, 0.0, 0.0)); + player.setDirection(new Vector3d(0.0, 0.0, 1.0)); + field.place(player); + + // �X�e�[�W��3D�f�[�^��ǂݍ��ݔz�u���� + Object3D stageObj = ModelFactory.loadModel("data\\konan\\konan3.wrl", false, true).createObject(); + Stage stage = new Stage(stageObj, "jimen1"); + field.place(stage); + + // �w�i���쐬���� + buildSkyBox(field); + + // �J�����̐ݒ�i��l�̎��_�ɂ���j + camera.setViewPoint(player.getPosition().add(0.0, 1.5, 0.0)); + camera.setViewLine(player.getDirection()); + camera.setFieldOfView(1.5); + } + + @Override + public RWTFrame3D createFrame3D() { + RWTFrame3D f = new RWTFrame3D(); + f.setSize(800, 600); + f.setTitle("Template for Shooting Games"); + f.setMouseCapture(true); + return f; + } + + protected RWTContainer createRWTContainer() { + container = new RWTContainer() { + @Override + public void build(GraphicsConfiguration gc) { + RWTCanvas3D canvas; + if (gc != null) { + canvas = new RWTCanvas3D(gc, true); + } else { + canvas = new RWTCanvas3D(true); + } + canvas.setRelativePosition(0.0f, 0.0f); + canvas.setRelativeSize(1.0f, 1.0f); + gameOver = new RWTLabel(0.25f, 0.5f, "Game Over!!", Color.RED, new Font("", Font.ITALIC, 36)); + gameOver.setVisible(false); + canvas.addWidget(gameOver); + RWTBoard scoreBoard = new RWTBoard(0.72f, 0.035f, 0.27f, 0.08f, new Color(1.0f, 1.0f, 1.0f, 0.3f)); + scoreBoard.setVisible(true); + canvas.addWidget(scoreBoard); + scoreDisplay = new RWTLabel(0.75f, 0.1f, "Score: " + score, Color.WHITE, new Font("", Font.PLAIN, 20)); + scoreDisplay.setVisible(true); + canvas.addWidget(scoreDisplay); + addCanvas(canvas); + repaint(); + } + // RWT���ł̓C�x���g���������Ȃ� + @Override + public void keyPressed(RWTVirtualKey key) {} + @Override + public void keyReleased(RWTVirtualKey key) {} + @Override + public void keyTyped(RWTVirtualKey key) {} + }; + return container; + } + + @Override + public void progress(RWTVirtualController virtualController, long interval) { + // �}�E�X����̏��� + double yaw = (virtualController.getMouseX() - .5) * Math.PI * 2.0; + double pitch = (virtualController.getMouseY() - .5) * Math.PI; + Vector3d direction = new Vector3d(Math.sin(yaw) * Math.cos(pitch), -Math.sin(pitch), -Math.cos(yaw) * Math.cos(pitch)); + battleField.setPlayerDirection(direction); + + // �L�[����̏��� + Velocity3D curV = battleField.getPlayerVelocity(); + if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { + curV.setX(battleField.getPlayerDirection().getZ() * 5.0); + curV.setZ(battleField.getPlayerDirection().getX() * -5.0); + battleField.setPlayerVelocity(curV); + } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { + curV.setX(battleField.getPlayerDirection().getZ() * -5.0); + curV.setZ(battleField.getPlayerDirection().getX() * 5.0); + battleField.setPlayerVelocity(curV); + } else if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { + curV.setX(battleField.getPlayerDirection().getX() * 5.0); + curV.setZ(battleField.getPlayerDirection().getZ() * 5.0); + battleField.setPlayerVelocity(curV); + } else if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { + curV.setX(battleField.getPlayerDirection().getX() * -5.0); + curV.setZ(battleField.getPlayerDirection().getZ() * -5.0); + battleField.setPlayerVelocity(curV); + } else { + curV.setX(0.0); + curV.setZ(0.0); + battleField.setPlayerVelocity(curV); + } + if (virtualController.isKeyDown(0, RWTVirtualController.BUTTON_A)) { + // �W�����v + if (battleField.isPlayerOnGround()) { + curV.setY(10.0); + battleField.setPlayerVelocity(curV); + } + } + if (virtualController.isMouseButtonDown(0)) { + // �e�̔��� + if (!bShot) { + battleField.playerShoots(); + } + bShot = true; + } else { + bShot = false; + } + + // ���̊m���œG�𔭐� + if (Math.random() < 0.01) { + battleField.createEnemy(); + } + + // ���̊m���œG�̒e�𔭎� + if (Math.random() < 0.005) { + battleField.enemyShoots(); + } + + // ���̂��ׂĂ̓o�ꕨ�i�v���C���[��G�Ȃǁj����Ăɓ����� + battleField.motion(interval); + + // �Q�[���I�[�o�[���ۂ��𔻒肷�� + if (battleField.isPlayerHit()) { + // �v���C���[�ɓ������� + gameOver.setVisible(true); + } + + // �_���v�Z + int hits = battleField.getHitEnemyCount(); + if (hits > 0) { + score += hits * 100; + scoreDisplay.setString("Score: " + score); + } + + // �J�����̈ړ��A��] + camera.setViewPoint(battleField.getPlayerPosition().add(0.0, 1.5, 0.0)); + camera.setViewLine(direction); + } + + /** + * �Q�[���̃��C�� + * @param args + */ + public static void main(String[] args) { + TemplateShooting game = new TemplateShooting(); + game.setFramePolicy(5, 33, false); + game.start(); + } + + /** + * �w�i���쐬���� + * @param field + */ + private void buildSkyBox(BattleField field) { + TextureLoader loaderTop = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureTop = loaderTop.getTexture(); + TextureLoader loaderBottom = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureBottom = loaderBottom.getTexture(); + TextureLoader loaderNorth = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureNorth = loaderNorth.getTexture(); + TextureLoader loaderSouth = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureSouth = loaderSouth.getTexture(); + TextureLoader loaderWest = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureWest = loaderWest.getTexture(); + TextureLoader loaderEast = new TextureLoader("data\\konan\\sky.jpg", + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + null); + Texture textureEast = loaderEast.getTexture(); + + BackgroundBox background = new BackgroundBox(textureNorth, textureWest, + textureSouth, textureEast, textureTop, textureBottom); + BoundingSphere bs = new BoundingSphere(); + bs.setRadius(1000); + background.setApplicationBounds(bs); + field.place(background); + } +} diff --git a/src/test/java/test/app/App.java b/src/test/java/test/app/App.java new file mode 100644 index 0000000..0bd8958 --- /dev/null +++ b/src/test/java/test/app/App.java @@ -0,0 +1,12 @@ +package test.app; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +import org.glassfish.jersey.server.ResourceConfig; + +@SuppressWarnings("unused") +@ApplicationPath("/rest") +public class App extends ResourceConfig { + +} \ No newline at end of file diff --git a/src/test/java/test/com/Test.java b/src/test/java/test/com/Test.java new file mode 100644 index 0000000..7f99d9e --- /dev/null +++ b/src/test/java/test/com/Test.java @@ -0,0 +1,26 @@ +package test.com; + +import java.util.Random; + +import javax.servlet.http.HttpServlet; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +@Path("/app") +public class Test extends HttpServlet { + private static final long serialVersionUID = 1L; + private static int num; + @Path("/get") + @GET + @Produces(MediaType.TEXT_HTML) + public String test() { + return "Hello, World!" + new Random().nextLong() + "
" + num; + } + @Path("/put") + @GET + @Produces(MediaType.TEXT_HTML) + public String setnum(@QueryParam("num") int set) { + num = set; + return (String.valueOf(num)); + } +} diff --git a/vecmath.jar b/vecmath.jar new file mode 100644 index 0000000..6d8b3a1 --- /dev/null +++ b/vecmath.jar Binary files differ diff --git a/yasson-1.0.jar b/yasson-1.0.jar new file mode 100644 index 0000000..4a35790 --- /dev/null +++ b/yasson-1.0.jar Binary files differ