質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • DXライブラリ

    56questions

    DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

マウスのホイールによるモデルの拡大縮小

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 167

north

score 2

いつもお世話になっております。
現在DXライブラリのC#版とwindowsフォームを利用してデスクトップマスコットを作成しているのですが
マウスのホイールによるモデルの拡大縮小を実装しているのですが
ホイール拡大縮小をした後にすぐに最初の大きさに戻ってしまうというバグに悩まされていて原因がわかりません。
下記がコードとなります

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DxLibDLL;//DxLibを使用
using CoreTweet; //CoreTweetを使用
using System.IO;//FileInfoを使用

namespace DesctopMascot
{
    public partial class Form1 : Form
    {
        private int modelHandle;
        private int attachIndex;
        private float totalTime;
        private float playTime;
        private float playSpeed;
        private int motionNum;
        private const int maxNum = 2;
        private Tokens token;
        private DX.VECTOR StartPos, EndPos;
        private DX.VECTOR ScreenPos;
        private DX.VECTOR modelPos;
        private DX.VECTOR oldScreenPos;
        private int MouseX;
        private int MouseY;
        private DX.MV1_COLL_RESULT_POLY HitPoly;
        private bool firstFlg;
        private DX.VECTOR scale;
        private int rot;

        public Form1()
        {
            InitializeComponent();
            MouseWheel += new MouseEventHandler(Form1_MouseWheel);

            ClientSize = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);//画面サイズの設定
            Text = "DesktopMascot";//ウインドウの名前を設定
            AllowDrop = true;//ドラッグ&ドロップを許可

            token = Tokens.Create("", "",
                "", ""); //twitterアカウントの認証
            firstFlg = false;

            DX.SetOutApplicationLogValidFlag(DX.FALSE);    //Log.txtを生成しないように設定
            DX.SetUserWindow(Handle);                      //DxLibの親ウインドウをこのフォームに設定
            DX.SetZBufferBitDepth(24);                     //Zバッファの精度を変更
            DX.DxLib_Init();                               //DxLibの初期化処理
            DX.SetDrawScreen(DX.DX_SCREEN_BACK);           //描画先を裏画面に設定

            System.Random rand = new System.Random();
            motionNum = rand.Next(maxNum);

            modelHandle = DX.MV1LoadModel("Data/kaede/kaede.mv1");//3Dモデルの読み込み
            attachIndex = DX.MV1AttachAnim(modelHandle, motionNum, -1, DX.FALSE);
            totalTime = DX.MV1GetAttachAnimTotalTime(modelHandle, attachIndex);
            playTime = 0.0f;
            playSpeed = 0.2f;
            scale = DX.MV1GetScale(modelHandle);


            DX.SetCameraNearFar(0.1f, 1000.0f);//奥行0.1~1000をカメラの描画範囲とする
            DX.SetCameraPositionAndTarget_UpVecY(DX.VGet(12.0f, 25.0f, -35.0f), DX.VGet(0.0f, 15.0f, 0.0f));//第1引数の位置から第2引数の位置を見る角度にカメラを設置

            DX.MV1SetupCollInfo(modelHandle, -1, 8, 8, 8);
        }

        public void MainLoop()
        {
            DX.ClearDrawScreen();//裏画面を消す

            DX.DrawBox(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, DX.GetColor(1, 1, 1), DX.TRUE);//背景を設定(透過させる)

            playTime += playSpeed;

            //モーションの再生位置が終端まで来たら最初に戻す
            if (playTime >= totalTime)
            {
                playTime = 0.0f;
            }

            DX.MV1SetAttachAnimTime(modelHandle, attachIndex, playTime);//モーションの再生位置を設定

            DX.MV1RefreshCollInfo(modelHandle, -1);

            DX.MV1DrawModel(modelHandle);//3Dモデルの描画

            ModelMove();

            //ESCキーを押したら終了
            if (DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) != 0)
            {
                Close();
            }

            DX.ScreenFlip();//裏画面を表画面にコピー
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            DX.DxLib_End();//DxLibの終了処理
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FormBorderStyle = FormBorderStyle.None;//フォームの枠を非表示にする
            Bitmap bmp = new Bitmap(@"form.bmp"); //画像を読み込み
            Color transColor = bmp.GetPixel(0, 0);
            bmp.MakeTransparent(transColor); //画像を透明にする
            BackgroundImage = bmp; //背景画像を指定する
            //背景色を指定する
            BackColor = transColor;
            //透明を指定する
            TransparencyKey = transColor;
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            //ファイルがドラッグされた場合のみ受け付け
            if(e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            string[] path = (string[])e.Data.GetData(DataFormats.FileDrop, false); //ドロップされたファイルのパスを取得する
            var ids = new List<long>();

            //各画像をアップロードしIDを取得
            foreach(var p in path)
            {
                MediaUploadResult image = token.Media.Upload(media: new FileInfo(p));
                ids.Add(image.MediaId);
            }

            //画像をツイートする
            Status s = token.Statuses.Update(status: "Upload Image", media_ids: ids);
        }

        private void ModelMove()
        {
            //マウスのクリックが左クリックの時に実行
            if ((DX.GetMouseInput() & DX.MOUSE_INPUT_LEFT) != 0)
            {

                DX.GetMousePoint(out MouseX, out MouseY);
                ScreenPos.x = (float)MouseX;
                ScreenPos.y = (float)MouseY;

                if(!firstFlg)
                {
                    oldScreenPos.x = (float)MouseX;
                    oldScreenPos.y = (float)MouseY;
                    firstFlg = true;
                }

                //ローカル座標を画面の指定の座標のワールド座標での一番手前(画面に近い側)の座標に変換
                ScreenPos.z = 0.0f;
                StartPos = DX.ConvScreenPosToWorldPos(ScreenPos);

                //ローカル座標を画面の指定の座標のワールド座標での画面の奥側の座標に変換
                ScreenPos.z = 1.0f;
                EndPos = DX.ConvScreenPosToWorldPos(ScreenPos);

                //マウスポインタがモデル上にあるかチェック
                HitPoly = DX.MV1CollCheck_Line(modelHandle, -1, StartPos, EndPos);
                if (HitPoly.HitFlag == DX.TRUE)
                {
                    modelPos = DX.MV1GetPosition(modelHandle);
                    DX.DrawStringF(100, 500, ">>クリックされてるよ~", 0xffffff);
                    if (oldScreenPos.x != ScreenPos.x || oldScreenPos.y != ScreenPos.y)
                    {
                        DX.VECTOR modelPos2D = DX.ConvWorldPosToScreenPos(modelPos);
                        modelPos2D.x += ScreenPos.x - oldScreenPos.x;
                        modelPos2D.y += ScreenPos.y - oldScreenPos.y;
                        if(modelPos2D.x > Screen.PrimaryScreen.Bounds.Width)
                        {
                            modelPos2D.x = Screen.PrimaryScreen.Bounds.Width;
                        }
                        if(modelPos2D.y > Screen.PrimaryScreen.Bounds.Height)
                        {
                            modelPos2D.y = Screen.PrimaryScreen.Bounds.Height;
                        }
                        DX.MV1SetPosition(modelHandle, DX.ConvScreenPosToWorldPos(modelPos2D));
                        //DX.VECTOR oldScreenPos3D = DX.ConvScreenPosToWorldPos(oldScreenPos);
                        //DX.VECTOR ScreenPos3D = DX.ConvScreenPosToWorldPos(ScreenPos);
                        //DX.MV1SetPosition(modelHandle, DX.VGet(modelPos.x + (ScreenPos3D.x - oldScreenPos3D.x), modelPos.y + (ScreenPos3D.y - oldScreenPos3D.y), modelPos.z));
                    }
                    oldScreenPos = ScreenPos;
                }
                else
                {
                    firstFlg = false;
                }

            }
        }

        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            //if(e.Delta != 0)
            //{
                DX.MV1SetScale(modelHandle, DX.VGet(scale.x + (float)e.Delta * SystemInformation.MouseWheelScrollLines / 12000, scale.y + (float)e.Delta * SystemInformation.MouseWheelScrollLines / 12000, scale.z + e.Delta * SystemInformation.MouseWheelScrollLines / 12000));
            //}
        }
    }
}

Form1_MouseWheel関数内で処理を行っております。
また、この機能をDXライブラリの関数    GetMouseWheelRotVol()でやろうとしたらどのようにしたらいいでしょうか?
一度実装してみたのですがマイフレーム関数が呼ばれてしまうため回転数がとれなかったので・・・

どうかよろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

MouseEventArgsのDeltaはホイールの回転量を表します
ズームさせるなら、ホイール回転量を積算してズーム量としなければいけません

回転量そのままズーム量としたら元に戻るのは当たり前ですね

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/13 23:20

    ありがとうございます。
    原因は仰るとおりでした。
    お陰様で無事修正できました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • DXライブラリ

    56questions

    DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。