diff --git a/.gitignore b/.gitignore index 5b82029..d9f7d9c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /.idea/libraries /.idea/modules.xml /.idea/workspace.xml +/.idea/caches .DS_Store /build /captures diff --git a/app/build.gradle b/app/build.gradle index 14b2299..b424cec 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,6 +21,10 @@ } } buildToolsVersion '27.0.3' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e329a11..7c3c703 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTDrawable.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTDrawable.java new file mode 100644 index 0000000..7fcc412 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTDrawable.java @@ -0,0 +1,34 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import org.ntlab.radishforandroidstudio.java3d.GraphicsContext3D; + +/** + * 描画可能な要素を示すインタフェース + * + * @author s.iwatani + */ +public interface RWTDrawable { + /** + * 描画を行う + * + * @author s.iwatani + * @param gc3D + */ + public void draw(GraphicsContext3D gc3D); + + /** + * 描画するかしないかをセット + * + * @author s.iwatani + * @param isDraw trueで描画する + */ + public void setIsDraw(boolean isDraw); + + /** + * 描画するかしないかを取得 + * + * @author s.iwatani + * @return boolean + */ + public boolean getIsDraw(); +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTImageLoader.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTImageLoader.java new file mode 100644 index 0000000..b571577 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTImageLoader.java @@ -0,0 +1,100 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.DisplayMetrics; + +import org.ntlab.radishforandroidstudio.framework.model3D.Position3D; +import org.ntlab.radishforandroidstudio.java3d.ImageComponent2D; +import org.ntlab.radishforandroidstudio.java3d.Texture; +import org.ntlab.radishforandroidstudio.java3d.Texture2D; + +import java.io.InputStream; + +/** + * 画像ローダー + * java3d.TextureLoaderから取ってきた + * 物体に貼り付けるテクスチャとかには使えないと思われる + * RWTSprite用 + * + * @author s.iwatani + */ +public class RWTImageLoader { + public static final int BY_REFERENCE = 2; + public static final int Y_UP = 4; + private InputStream in = null; + private Resources res = null; + private int id = 0; + private Bitmap bitmap; + private int format, texFormat; + private Position3D size = null; + + public RWTImageLoader(InputStream in, int flags) { + this.in = in; + } + + public RWTImageLoader(Resources res, int id, int flags) { + this(res, id, flags, ImageComponent2D.FORMAT_RGB); + } + + /** + * TextureLoaderコンストラクタ + * + * @author s.iwatani + * @param res Resources + * @param id リソースID + * @param flags 知らん + * @param format 画像がRGBかRGBAか ImageComponent2D.FORMAT_RGBまたはImageComponent2D.FORMAT_RGBA + */ + public RWTImageLoader(Resources res, int id, int flags, int format) { + this.res = res; + this.id = id; + setFormat(format); + } + + /** + * 画像がRGBかRGBAかをセット + * + * @param format ImageComponent2D.FORMAT_RGBまたはImageComponent2D.FORMAT_RGBA + */ + public void setFormat(int format) { + this.format = format; + if (this.format == ImageComponent2D.FORMAT_RGB) { + texFormat = Texture.RGB; + } + else { + texFormat = Texture.RGBA; + } + } + + public ImageComponent2D getImage() { + if (in != null) { + bitmap = BitmapFactory.decodeStream(in); + } else if (res != null) { + bitmap = BitmapFactory.decodeResource(res, id); + } + if (format == ImageComponent2D.FORMAT_RGBA) { + bitmap.setHasAlpha(true); + } + + size = new Position3D(bitmap.getWidth(), bitmap.getHeight(), 0.0); + return new ImageComponent2D(format, bitmap); + } + + public Position3D getSize() { + return size; + } + + public ImageComponent2D setImage(Bitmap bitmap) { + this.bitmap = bitmap; + return new ImageComponent2D(format, this.bitmap); + } + + public Texture getTexture() { + ImageComponent2D ic2 = getImage(); + Texture tex = new Texture2D(Texture.BASE_LEVEL, texFormat, bitmap.getWidth(), bitmap.getHeight()); + tex.setImage(0, ic2); + return tex; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTPad.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTPad.java new file mode 100644 index 0000000..d756d18 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTPad.java @@ -0,0 +1,102 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import org.ntlab.radishforandroidstudio.framework.event.PadEvent; +import org.ntlab.radishforandroidstudio.framework.listener.PadListener; +import org.ntlab.radishforandroidstudio.framework.listener.SamplePadListener; +import org.ntlab.radishforandroidstudio.framework.subject.PadSubject; + +public class RWTPad extends RWTView { + private MotionEvent touchInfo = null; + private Point circlePos = null; + + public RWTPad(Context context) { + super(context); + init(); + } + + public RWTPad(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public RWTPad(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + @Override + public void init() { + super.init(); + // Listenerサンプル + addListener(new SamplePadListener()); + } + + // TODO: 見た目の調整 + @Override + public void onDraw(Canvas canvas) { + // super.onDraw(canvas); + Paint paint = this.createRedPaint(); + canvas.drawCircle(getSize().x / 2, getSize().x / 2, getSize().x / 2, paint); + + // TODO: あとでいい感じになるように修正 + // このクラス内の他の部分も同様 + paint.setColor(Color.BLUE); + if (circlePos == null) { + circlePos = new Point(getSize().x / 2, getSize().y / 2); + } + canvas.drawCircle(circlePos.x, circlePos.y, getSize().x / 6, paint); + } + + private Paint createRedPaint() { + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setColor(Color.RED); + // 以下の値が小さいと点が見えない可能性があります + paint.setStrokeWidth(10); + return paint; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // 中央からの距離を取得 + float dx = event.getX() - getSize().x / 2; + float dy = event.getY() - getSize().y / 2; + float rawLen = (float)Math.sqrt(dx*dx + dy*dy); + float angle = (float)Math.atan2(dy, dx); + float maxLen = getSize().x / 2; + float len = rawLen / maxLen; + float fixLen = Math.max(Math.min(1.f, len), -1.f); + + circlePos.x = (int)event.getX(); + circlePos.y = (int)event.getY(); + + if (len > 1) { + circlePos.x = (int)(fixLen * Math.cos(angle) * maxLen + maxLen); + circlePos.y = (int)(fixLen * Math.sin(angle) * maxLen + maxLen); + } + + touchInfo = event; + PadEvent padEvent = new PadEvent(event, fixLen, angle); + PadSubject.getInstance().notifyListeners(padEvent); + + if (event.getAction() == MotionEvent.ACTION_UP) { + circlePos.x = getSize().x / 2; + circlePos.y = getSize().y / 2; + } + + invalidate(); + return true; + } + + public void addListener(PadListener listener) { + PadSubject.getInstance().addListener(listener); + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTRenderer.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTRenderer.java index 8213ff5..ca2a4c7 100644 --- a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTRenderer.java +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTRenderer.java @@ -1,26 +1,27 @@ package org.ntlab.radishforandroidstudio.framework.RWT; -import android.opengl.GLSurfaceView.Renderer; - -import java.util.ArrayList; - import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; +import android.opengl.GLSurfaceView.Renderer; + import org.ntlab.radishforandroidstudio.framework.view3D.Camera3D; import org.ntlab.radishforandroidstudio.framework.view3D.Viewer3D; import org.ntlab.radishforandroidstudio.java3d.GraphicsContext3D; import org.ntlab.radishforandroidstudio.java3d.Light; +import java.util.ArrayList; + public class RWTRenderer implements Renderer { protected Viewer3D viewer; protected Camera3D camera; protected GraphicsContext3D gc3D = null; + protected GL10 gl; public RWTRenderer() { super(); } - + public void attachCamera(Camera3D camera) { // onSurfaceCreated()より先に呼ばれる this.camera = camera; @@ -29,6 +30,7 @@ @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { + this.gl = gl; gc3D = new GraphicsContext3D(gl); ArrayList lights = camera.getUniverse().getLights(); for (int i = 0; i < lights.size(); i++){ diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSprite.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSprite.java new file mode 100644 index 0000000..ffebc9e --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSprite.java @@ -0,0 +1,156 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import android.content.res.Resources; +import android.opengl.GLUtils; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.TableLayout; + +import org.ntlab.radishforandroidstudio.framework.model3D.Position3D; +import org.ntlab.radishforandroidstudio.java3d.GraphicsContext3D; +import org.ntlab.radishforandroidstudio.java3d.ImageComponent2D; +import org.ntlab.radishforandroidstudio.java3d.Texture; +import org.ntlab.radishforandroidstudio.java3d.TextureLoader; + +import java.util.ArrayList; + +/** + * 画像管理クラス + * 座標は左下が原点であることに注意(DirectXは左上のため) + * + * @author s.iwatani + */ +public class RWTSprite implements RWTDrawable { + private int[] textureId = null; + private ImageComponent2D image = null; + private boolean isDraw = true; + + // 表示座標 + private Position3D pos = new Position3D(0.f, 0.f, 0.f); + private Position3D texSize = new Position3D(0.f, 0.f, 0.f); + private Position3D texPos = new Position3D(0.f, 0.f, 0.f); + private Position3D viewSize = new Position3D(0.f, 0.f, 0.f); + + public RWTSprite() { + } + + /** + * 表示する座標を取得 + * + * @author s.iwatani + * @return Position3D + */ + final public Position3D getPosition() { + return pos; + } + + /** + * 表示サイズを取得 + * + * @author s.iwatani + * @return Position3D + */ + final public Position3D getViewSize() { + return viewSize; + } + + /** + * 画像サイズを取得 + * + * @author s.iwatani + * @return Position3D + */ + final public Position3D getTextureSize() { + return texSize; + } + + /** + * 描画する座標をセット + * + * @author s.iwatani + * @param x x座標 + * @param y y座標 + */ + public void setPosition(float x, float y) { + pos.setX(x); + pos.setY(y); + } + + /** + * 描画する座標をセット + * @param pos Position3D + */ + public void setPosition(Position3D pos) { + setPosition((float)pos.getX(), (float)pos.getY()); + } + + /** + * テクスチャをセット + * + * @author s.iwatani + * @param res Resources + * @param id リソースのID R.drawable.なんちゃらみたいなやつ + * + * TODO: 画像サイズが元と違うため,そのサイズが元のものになるようにする + * Bitmap.createScaledBitmap(robot, 100, 100, false);のやつ + */ + public void setTexture(Resources res, int id, boolean isEnableAlpha) { + RWTImageLoader texLoader = new RWTImageLoader(res, id, + TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, + isEnableAlpha ? ImageComponent2D.FORMAT_RGBA : ImageComponent2D.FORMAT_RGB); + image = texLoader.getImage(); + Texture tex = texLoader.getTexture(); + Log.v("moji", "faaa"); + Log.v("moji", ((Double)(texLoader.getSize().getX())).toString() + ", " + ((Double)(texLoader.getSize().getY())).toString()); + Log.v("moji", "faaa"); + + texPos.setX(0.f); + texPos.setY(image.getBitmap().getHeight()); + texSize.setX(image.getBitmap().getWidth()); + texSize.setY(-image.getBitmap().getHeight()); + pos.set(0.0, 0.0, 0.0); + viewSize.setX((float)image.getBitmap().getWidth()); + viewSize.setY((float)image.getBitmap().getHeight()); + } + + /** + * 画像を描画する + * + * @author s.iwatani + * @param gc3D GL10 + */ + public void draw(GraphicsContext3D gc3D) { + if (!getIsDraw()) { + return; + } + + if (textureId == null) { + textureId = new int[1]; + textureId[0] = gc3D.loadImage(image); + } + gc3D.draw(textureId[0], pos, texPos, texSize, viewSize); + } + + /** + * 描画するかしないかをセット + * + * @author s.iwatani + * @param isDraw trueで描画する + */ + @Override + public void setIsDraw(boolean isDraw) { + this.isDraw = isDraw; + } + + /** + * 描画するかしないかを取得 + * + * @author s.iwatani + * @return boolean + */ + @Override + public boolean getIsDraw() { + return isDraw; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSurfaceView.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSurfaceView.java index 2aa9093..aa7b742 100644 --- a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSurfaceView.java +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTSurfaceView.java @@ -11,18 +11,17 @@ public RWTSurfaceView(Context context) { this(context, true); } - + public RWTSurfaceView(Context context, boolean bInitRenderer) { super(context); if (bInitRenderer) { renderer = new RWTRenderer(); setEGLConfigChooser(8, 8, 8, 8, 16, 0); - this.setRenderer(renderer); + this.setRenderer(renderer); } } public void attachCamera(Camera3D camera) { renderer.attachCamera(camera); } - } diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTUIFragment.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTUIFragment.java new file mode 100644 index 0000000..1dd6ff2 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTUIFragment.java @@ -0,0 +1,34 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import org.ntlab.radishforandroidstudio.R; + +import static android.view.View.*; + +public class RWTUIFragment extends Fragment implements OnTouchListener { + public RWTUIFragment() {} + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.ui_fragment, null); + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + System.out.println("RWTUIFragment touch"); + return false; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTView.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTView.java new file mode 100644 index 0000000..f3b00d1 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/RWT/RWTView.java @@ -0,0 +1,65 @@ +package org.ntlab.radishforandroidstudio.framework.RWT; + +import android.content.Context; +import android.graphics.Point; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; + +public abstract class RWTView extends View { + private float dp = 1; + private Point size = null; + private Point pos = null; + + public RWTView(Context context) { + super(context); + init(); + } + + public RWTView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(); + } + + public RWTView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + public void init() { + dp = getResources().getDisplayMetrics().density; + } + + /** + * 画面上に表示されるサイズを取得 + * @return Point + */ + public Point getSize() { + if (size == null) { + size = new Point(getWidth(), getHeight()); + } + return size; + } + + /** + * 画面上に表示される左上の座標を取得 + * @return Point + */ + public Point getPosition() { + if (pos == null) { + pos = new Point(getLeft(), getTop()); + } + return pos; + } + + /** + * DPを乗算する + * @param a + * @return int + */ + public int applyDp(int a) { + return (int)(a * dp); + } + + +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/MyEvent.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/MyEvent.java new file mode 100644 index 0000000..37c04b4 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/MyEvent.java @@ -0,0 +1,15 @@ +package org.ntlab.radishforandroidstudio.framework.event; + +import android.view.MotionEvent; + +public class MyEvent { + MotionEvent e; + + public MyEvent(MotionEvent e) { + this.e = e; + } + + public final MotionEvent getMotionEvent() { + return e; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/PadEvent.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/PadEvent.java new file mode 100644 index 0000000..8e5d25e --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/event/PadEvent.java @@ -0,0 +1,33 @@ +package org.ntlab.radishforandroidstudio.framework.event; + +import android.view.MotionEvent; + +public class PadEvent extends MyEvent{ + private MotionEvent e; + + /** + * パッドを倒した距離 + * 範囲は 0<=length<=1 + */ + private float length; + + /** + * パッドを倒した方向 + * 単位radian + */ + private float angle; + + public PadEvent(MotionEvent e, float length, float angle) { + super(e); + this.length = length; + this.angle = angle; + } + + public final float getLength() { + return length; + } + + public final float getAngle() { + return angle; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTime3DActivity.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTime3DActivity.java index 2bb5dd7..2e6592d 100644 --- a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTime3DActivity.java +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTime3DActivity.java @@ -15,7 +15,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); universe = new Universe(); - + camera = new Camera3D(universe); view = new RWTSurfaceView(this); diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTimeActivity.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTimeActivity.java index 29025ca..0d8c19c 100644 --- a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTimeActivity.java +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/gameMain/RealTimeActivity.java @@ -18,7 +18,7 @@ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - } + } protected void start(long interval){ this.interval = interval; diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/MyListener.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/MyListener.java new file mode 100644 index 0000000..fa5a7a8 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/MyListener.java @@ -0,0 +1,7 @@ +package org.ntlab.radishforandroidstudio.framework.listener; + +import org.ntlab.radishforandroidstudio.framework.event.MyEvent; + +public interface MyListener { + boolean onEvent(EventType event); +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/PadListener.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/PadListener.java new file mode 100644 index 0000000..6c5e1a8 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/PadListener.java @@ -0,0 +1,5 @@ +package org.ntlab.radishforandroidstudio.framework.listener; + +import org.ntlab.radishforandroidstudio.framework.event.PadEvent; + +public interface PadListener extends MyListener {} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/SamplePadListener.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/SamplePadListener.java new file mode 100644 index 0000000..c7d4751 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/listener/SamplePadListener.java @@ -0,0 +1,11 @@ +package org.ntlab.radishforandroidstudio.framework.listener; + +import org.ntlab.radishforandroidstudio.framework.event.PadEvent; + +public class SamplePadListener implements PadListener { + @Override + public boolean onEvent(PadEvent event) { + System.out.println("PadListener Length:" + event.getLength() + " angle:" + event.getAngle()); + return false; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/MySubject.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/MySubject.java new file mode 100644 index 0000000..7b10a88 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/MySubject.java @@ -0,0 +1,26 @@ +package org.ntlab.radishforandroidstudio.framework.subject; + +import android.view.InputEvent; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.ntlab.radishforandroidstudio.framework.event.MyEvent; +import org.ntlab.radishforandroidstudio.framework.listener.MyListener; + +// TODO: removeListenerの追加 +public abstract class MySubject { + protected Set listenerSet = new CopyOnWriteArraySet<>(); + + public MySubject() {} + + public void addListener(ListenerType listener) { + listenerSet.add(listener); + } + + public void notifyListeners(EventType event) { + for (ListenerType listener : listenerSet) { + listener.onEvent(event); + } + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/PadSubject.java b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/PadSubject.java new file mode 100644 index 0000000..441dad9 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/framework/subject/PadSubject.java @@ -0,0 +1,16 @@ +package org.ntlab.radishforandroidstudio.framework.subject; + +import org.ntlab.radishforandroidstudio.framework.event.PadEvent; +import org.ntlab.radishforandroidstudio.framework.listener.PadListener; + +// 実装いらない説 +// Listener側と同じようにC++のテンプレート特殊化的なことだけして中身なしにするかも +public class PadSubject extends MySubject { + public final static PadSubject own = new PadSubject(); + + private PadSubject() { super(); } + + public static PadSubject getInstance() { + return own; + } +} diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/java3d/GraphicsContext3D.java b/app/src/main/java/org/ntlab/radishforandroidstudio/java3d/GraphicsContext3D.java index cb0fe2e..cd13e19 100644 --- a/app/src/main/java/org/ntlab/radishforandroidstudio/java3d/GraphicsContext3D.java +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/java3d/GraphicsContext3D.java @@ -1,5 +1,6 @@ package org.ntlab.radishforandroidstudio.java3d; +import android.graphics.Bitmap; import android.opengl.GLU; import android.opengl.GLUtils; @@ -10,6 +11,8 @@ import java.util.HashMap; import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; +import javax.microedition.khronos.opengles.GL11Ext; public class GraphicsContext3D { private GL10 gl; @@ -348,6 +351,72 @@ } } + /** + * 画像を流し込む + * + * @author s.iwatani + * @param image ImageComponent2D + * @return int textureId + */ + public int loadImage(ImageComponent2D image) { + int[] textureId = new int[1]; + gl.glGenTextures(1, textureId, 0); + //テクスチャIDに対応するテクスチャをバインドする + gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId[0]); + + // 初回のみ画像を流し込む + GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, image.getBitmap(), 0); + return textureId[0]; + } + + /** + * Bitmap描画 + * + * @author s.iwatani + * @param textureId + * @param pos + * @param texPos + * @param texSize + * @param viewSize + */ + public void draw(int textureId, Position3D pos, Position3D texPos, Position3D texSize, Position3D viewSize) { + //テクスチャIDに対応するテクスチャをバインドする + gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); + + // 拡大縮小のアルゴリズム指定 + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); + + int rect[] = { (int)texPos.getX(), (int)texPos.getY(), (int)texSize.getX(), (int)texSize.getY()}; + ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect, 0); + ((GL11Ext) gl).glDrawTexfOES((int)pos.getX(), (int)pos.getY(), (int)pos.getZ(), (int)viewSize.getX(), (int)viewSize.getY()); + } + + public void startDrawImage() { + // なんかやってる + gl.glDisable(GL10.GL_DEPTH_TEST); + gl.glDisable(GL10.GL_DITHER); + gl.glDisable(GL10.GL_LIGHTING); + +// gl.glEnable(GL10.GL_ALPHA_TEST); + // アルファ値を適用するための一連 + gl.glEnable(GL10.GL_ALPHA); // GL_INVALID_ENUMが出るけどちゃんと動いてる.謎 + gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); + gl.glEnable(GL10.GL_BLEND); + + gl.glEnable(GL10.GL_TEXTURE_2D); + + // テクスチャ0番をアクティブにする(よくわからん) + gl.glActiveTexture(GL10.GL_TEXTURE0); + } + + public void endDrawImage() { + gl.glEnable(GL10.GL_DEPTH_TEST); + gl.glEnable(GL10.GL_DITHER); + gl.glEnable(GL10.GL_LIGHTING); + gl.glDisable(GL10.GL_ALPHA); + } + private void setTextureAttributes(TextureAttributes ta) { int textureMode = ta.getTextureMode(); switch (textureMode) { diff --git a/app/src/main/java/org/ntlab/radishforandroidstudio/spriteTest/TestActivity.java b/app/src/main/java/org/ntlab/radishforandroidstudio/spriteTest/TestActivity.java new file mode 100644 index 0000000..5d943a9 --- /dev/null +++ b/app/src/main/java/org/ntlab/radishforandroidstudio/spriteTest/TestActivity.java @@ -0,0 +1,163 @@ +package org.ntlab.radishforandroidstudio.spriteTest; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; + +import org.ntlab.radishforandroidstudio.R; +import org.ntlab.radishforandroidstudio.framework.RWT.RWTSprite; +import org.ntlab.radishforandroidstudio.framework.RWT.RWTSurfaceView; +import org.ntlab.radishforandroidstudio.framework.RWT.RWTUIFragment; +import org.ntlab.radishforandroidstudio.framework.gameMain.RealTimeActivity; +import org.ntlab.radishforandroidstudio.framework.listener.PadListener; +import org.ntlab.radishforandroidstudio.framework.model3D.Object3D; +import org.ntlab.radishforandroidstudio.framework.model3D.Position3D; +import org.ntlab.radishforandroidstudio.framework.model3D.Universe; +import org.ntlab.radishforandroidstudio.framework.physics.AngularVelocity3D; +import org.ntlab.radishforandroidstudio.framework.physics.Force3D; +import org.ntlab.radishforandroidstudio.framework.physics.PhysicalSystem; +import org.ntlab.radishforandroidstudio.framework.physics.Solid3D; +import org.ntlab.radishforandroidstudio.framework.physics.Velocity3D; +import org.ntlab.radishforandroidstudio.framework.subject.PadSubject; +import org.ntlab.radishforandroidstudio.framework.view3D.Camera3D; +import org.ntlab.radishforandroidstudio.java3d.Appearance; +import org.ntlab.radishforandroidstudio.java3d.Box; +import org.ntlab.radishforandroidstudio.java3d.Material; +import org.ntlab.radishforandroidstudio.java3d.TextureCubeMap; +import org.ntlab.radishforandroidstudio.java3d.TextureLoader; +import org.ntlab.radishforandroidstudio.java3d.Transform3D; + +public class TestActivity extends RealTimeActivity { + private PhysicalSystem physicalSystem; + private Object3D groundObj; + private Solid3D ground; + private Transform3D initTrans; + private Solid3D diceObj; + private long time = 0; + private int side = 0; + + private RWTSurfaceView view = null; + + private RWTSprite[] sprite = new RWTSprite[3]; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // 3Dモデルの作成 + Universe universe = new Universe(); + + // サイコロの作成 + Appearance ap1 = new Appearance(); + TextureCubeMap tex1 = new TextureCubeMap(TextureCubeMap.BASE_LEVEL, TextureCubeMap.RGB, 0); + TextureLoader loader = new TextureLoader(getResources(), R.drawable.dice_1, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.POSITIVE_Z, loader.getImage()); + loader = new TextureLoader(getResources(), R.drawable.dice_6, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.NEGATIVE_Z, loader.getImage()); + loader = new TextureLoader(getResources(), R.drawable.dice_4, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.POSITIVE_X, loader.getImage()); + loader = new TextureLoader(getResources(), R.drawable.dice_3, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.NEGATIVE_X, loader.getImage()); + loader = new TextureLoader(getResources(), R.drawable.dice_5, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.POSITIVE_Y, loader.getImage()); + loader = new TextureLoader(getResources(), R.drawable.dice_2, TextureLoader.BY_REFERENCE | TextureLoader.Y_UP); + tex1.setImage(0, TextureCubeMap.NEGATIVE_Y, loader.getImage()); + ap1.setTexture(tex1); + physicalSystem = new PhysicalSystem(); + Box b1 = new Box(1.0f, 1.0f, 1.0f, ap1); + Object3D obj1 = new Object3D("box", b1); + obj1.apply(new Position3D(0.0 , 30.0, 0.0), false); + diceObj = new Solid3D(obj1); + diceObj.scale(2.0, 2.0, 2.0); + diceObj.apply(new AngularVelocity3D(-0.4, 0.0, -0.6), false); + universe.place(diceObj); + physicalSystem.add(diceObj); + initTrans = new Transform3D(); + obj1.rot.getTransform(initTrans); + + // 地面の作成 + 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); + + Box b2 = new Box(1.0f, 1.0f, 1.0f, ap1); + groundObj = new Object3D("ground", b2); + groundObj.apply(new Position3D(0.0, -3.0, 0.0), false); + groundObj.scale(100.0, 3.0, -50.0); + ground = new Solid3D(groundObj); + ground.setMass(100000000); + universe.place(ground); + physicalSystem.add(ground); + + // カメラの作成 + Camera3D camera = new Camera3D(universe); + camera.setViewPoint(new Position3D(0.0, 30, -30.0)); + camera.addTarget(diceObj); + + // 画面との関連付け + FrameLayout l = findViewById(R.id.game_layout); + view = new RWTSurfaceView(this); + view.attachCamera(camera); + l.addView(view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); + + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction transaction = fragmentManager.beginTransaction(); + Fragment f = new RWTUIFragment(); + View uiLayout = (View)findViewById(R.id.ui_layout); + uiLayout.setOnTouchListener((RWTUIFragment)f); + transaction.add(R.id.ui_layout, f); + transaction.commit(); + + start(10); + } + + @Override + protected void update(long interval) { + ground.apply(new Position3D(0.0, -3.0, 0.0), false); + ground.apply(new Velocity3D(), false); + groundObj.rot.setTransform(initTrans); + + long newTime = System.nanoTime(); + physicalSystem.motion(0, 10, Force3D.ZERO, physicalSystem.objects.get(0).getGravityCenter(), null); + // Log.v("moji", "" + ((System.nanoTime()-newTime)/1000.0)); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public boolean onTouchEvent(MotionEvent event){ + physicalSystem.objects.get(0).setPosition(new Position3D(0.0 , 30.0, 0.0)); + return true; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/res/drawable/tss_thumb.png b/app/src/main/res/drawable/tss_thumb.png new file mode 100644 index 0000000..18e0ca2 --- /dev/null +++ b/app/src/main/res/drawable/tss_thumb.png Binary files differ diff --git a/app/src/main/res/drawable/wadahand.png b/app/src/main/res/drawable/wadahand.png new file mode 100644 index 0000000..7294a18 --- /dev/null +++ b/app/src/main/res/drawable/wadahand.png Binary files differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9d26b30..77628c5 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,14 +6,23 @@ android:layout_height="match_parent" tools:context=".cactusClient.MainActivity"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/test_activity.xml b/app/src/main/res/layout/test_activity.xml new file mode 100644 index 0000000..b514099 --- /dev/null +++ b/app/src/main/res/layout/test_activity.xml @@ -0,0 +1,15 @@ + + + +