min3d引擎使用指南(Android stdio)<一>

来源:互联网 发布:当量直径算法 编辑:程序博客网 时间:2024/05/01 10:58

尝试着把min3d引擎移植到android stdio上开发,开始的时候遇到不少问题,所以在CSDN上开个帖。同时感谢美丽同事XY的帮忙。


第一个问题:一开始把min3d包导入Android stdio后,在MainActivity中提示“improt unused imports statement”,然后声明了对象,也同样没用。

后来上谷歌查了不少资料,在另一篇CSDN博客上找到了一项设置:

然后点 ok,这样 Android stdio就懂得自动导入响应的包。import就不会报错了。


第二个问题:在Android stdio上新建的空工程,public class MainActivity extends AppCompatActivity。而min3d要显示跑起来,需要继承的是RendererActivity。所以修改的代码如下:


package com.example.zk.min3d_demo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.Window;import android.view.WindowManager;import android.widget.FrameLayout;import min3d.animation.AnimationObject3d;import min3d.core.Object3dContainer;import min3d.core.RendererActivity;import min3d.objectPrimitives.Box;import min3d.parser.IParser;import min3d.parser.Parser;import min3d.vos.Light;public class MainActivity extends RendererActivity {//public class MainActivity extends AppCompatActivity {    Object3dContainer faceObject3D;     //3D对象    private AnimationObject3d ogre;    private RockerView rockerView1;    float modelx = 0;    float modely = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //frame3dView        FrameLayout ll = (FrameLayout) this.findViewById(R.id.frame3dView);        //在xml中,指定显示的控件,这里是一个FrameLayout。        ll.addView(_glSurfaceView);//加入到_glSurfaceView中显示。        rockerView1 = (RockerView) findViewById(R.id.rockerView1);        rockerView1.setRockerChangeListener(new RockerView.RockerChangeListener() {            @Override            public void report(float x, float y) {                // TODO Auto-generated method stub                modelx = x/1000;                modely = y/1000;            }        });    }    public void initScene() {        scene.lights().add(new Light());        IParser parser = Parser.createParser(Parser.Type.MD2,                getResources(), "com.example.zk.min3d_demo:raw/ogro", false);        parser.parse();        ogre = parser.getParsedAnimationObject();        ogre.scale().x = ogre.scale().y = ogre.scale().z = .07f;        ogre.rotation().z = -90;        ogre.rotation().x = -90;        scene.addChild(ogre);        ogre.setFps(70);        ogre.play();    }    public void updateScene() {        //     faceObject3D.rotation().x++;//围绕着X轴旋转,正数为顺时针,速度由X的数值变化决定        ogre.rotation().x +=modelx;//设置初始位置,平截头体中xyz的坐标位置        ogre.position().y +=modely;    }}
下面的xml文件,就是美丽的同事帮我弄好的。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.zk.min3d_demo.MainActivity">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"        android:id="@+id/textView" />    <FrameLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@+id/textView"        android:id="@+id/frame3dView"        android:layout_alignParentStart="true">    </FrameLayout>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_gravity="center_horizontal|top">        <com.example.zk.min3d_demo.RockerView            android:id="@+id/rockerView1"            android:layout_width="120dp"            android:layout_height="120dp"            android:layout_marginLeft="20dp"            android:layout_alignParentTop="true"            android:layout_alignParentEnd="true" />    </RelativeLayout></RelativeLayout>

里面的摇杆控件,要用到下面这个Java类

package com.example.zk.min3d_demo;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.PointF;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewTreeObserver;/** * Created by zk on 2016/11/24. */public class RockerView extends View {    //固定摇杆背景圆形的X,Y坐标以及半径    private float mRockerBg_X;    private float mRockerBg_Y;    private float mRockerBg_R;    //摇杆的X,Y坐标以及摇杆的半径    private float mRockerBtn_X;    private float mRockerBtn_Y;    private float mRockerBtn_R;    private Bitmap mBmpRockerBg;    private Bitmap mBmpRockerBtn;    private PointF mCenterPoint;    public RockerView(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        // 获取bitmap        mBmpRockerBg = BitmapFactory.decodeResource(context.getResources(), R.drawable.rocker_bg);        mBmpRockerBtn = BitmapFactory.decodeResource(context.getResources(), R.drawable.rocker_btn);        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {            // 调用该方法时可以获取view实际的宽getWidth()和高getHeight()            @Override            public boolean onPreDraw() {                // TODO Auto-generated method stub                getViewTreeObserver().removeOnPreDrawListener(this);                Log.e("RockerView", getWidth() + "/" +  getHeight());                mCenterPoint = new PointF(getWidth() / 2, getHeight() / 2);                mRockerBg_X = mCenterPoint.x;                mRockerBg_Y = mCenterPoint.y;                mRockerBtn_X = mCenterPoint.x;                mRockerBtn_Y = mCenterPoint.y;                float tmp_f = mBmpRockerBg.getWidth() / (float)(mBmpRockerBg.getWidth() + mBmpRockerBtn.getWidth());                mRockerBg_R = tmp_f * getWidth() / 2;                mRockerBtn_R = (1.0f - tmp_f)* getWidth() / 2;                return true;            }        });        new Thread(new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                while(true){                    //系统调用onDraw方法刷新画面                    RockerView.this.postInvalidate();                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        }).start();    }    @Override    protected void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        super.onDraw(canvas);        canvas.drawBitmap(mBmpRockerBg, null,                new Rect((int)(mRockerBg_X - mRockerBg_R),                        (int)(mRockerBg_Y - mRockerBg_R),                        (int)(mRockerBg_X + mRockerBg_R),                        (int)(mRockerBg_Y + mRockerBg_R)),                null);        canvas.drawBitmap(mBmpRockerBtn, null,                new Rect((int)(mRockerBtn_X - mRockerBtn_R),                        (int)(mRockerBtn_Y - mRockerBtn_R),                        (int)(mRockerBtn_X + mRockerBtn_R),                        (int)(mRockerBtn_Y + mRockerBtn_R)),                null);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        // TODO Auto-generated method stub        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {            // 当触屏区域不在活动范围内            if (Math.sqrt(Math.pow((mRockerBg_X - (int) event.getX()), 2) + Math.pow((mRockerBg_Y - (int) event.getY()), 2)) >= mRockerBg_R) {                //得到摇杆与触屏点所形成的角度                double tempRad = getRad(mRockerBg_X, mRockerBg_Y, event.getX(), event.getY());                //保证内部小圆运动的长度限制                getXY(mRockerBg_X, mRockerBg_Y, mRockerBg_R, tempRad);            } else {//如果小球中心点小于活动区域则随着用户触屏点移动即可                mRockerBtn_X = (int) event.getX();                mRockerBtn_Y = (int) event.getY();            }            if(mRockerChangeListener != null) {                mRockerChangeListener.report(mRockerBtn_X - mCenterPoint.x, mRockerBtn_Y - mCenterPoint.y);            }        } else if (event.getAction() == MotionEvent.ACTION_UP) {            //当释放按键时摇杆要恢复摇杆的位置为初始位置            mRockerBtn_X = mCenterPoint.x;            mRockerBtn_Y = mCenterPoint.y;            if(mRockerChangeListener != null) {                mRockerChangeListener.report(0, 0);            }        }        return true;    }    /***     * 得到两点之间的弧度     */    public double getRad(float px1, float py1, float px2, float py2) {        //得到两点X的距离        float x = px2 - px1;        //得到两点Y的距离        float y = py1 - py2;        //算出斜边长        float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));        //得到这个角度的余弦值(通过三角函数中的定理 :邻边/斜边=角度余弦值)        float cosAngle = x / xie;        //通过反余弦定理获取到其角度的弧度        float rad = (float) Math.acos(cosAngle);        //注意:当触屏的位置Y坐标<摇杆的Y坐标我们要取反值-0~-180        if (py2 < py1) {            rad = -rad;        }        return rad;    }    /**     *     * @param R  圆周运动的旋转点     * @param centerX 旋转点X     * @param centerY 旋转点Y     * @param rad 旋转的弧度     */    public void getXY(float centerX, float centerY, float R, double rad) {        //获取圆周运动的X坐标        mRockerBtn_X = (float) (R * Math.cos(rad)) + centerX;        //获取圆周运动的Y坐标        mRockerBtn_Y = (float) (R * Math.sin(rad)) + centerY;    }    RockerChangeListener mRockerChangeListener = null;    public void setRockerChangeListener(RockerChangeListener rockerChangeListener) {        mRockerChangeListener = rockerChangeListener;    }    public interface RockerChangeListener {        public void report(float x, float y);    }}


还有一些资源文件,我已经把整个工程上传到CSDN,无积分。但还在审核,通过后会把链接贴到这里:

http://download.csdn.net/detail/zhangkun35268/9692440


效果动态图:



1 0