[LookingGlass]holoplay.jsで焦点をオブジェクトの表面に合わせる

回転するとオブジェクトの裏に焦点がいきぼやけてしまうので
視線からオブジェクト表面の距離を求めてフォーカスをそこに合わせるようにしてみた

var vlocal = new THREE.Vector3(0, 0, -1);
var dir = vlocal.applyQuaternion(camera.quaternion);
//カメラと中心部の距離
var length = camera.position.clone().sub(objcenter).length();
//大体の表面位置を算出し焦点を移動
var pos = dir.multiplyScalar(length - objradius).add(camera.position);
holoPlay.lookAt(pos, camera);

レンダリングの直前に行うとよさそう

TypeScriptでclassをテンプレートとして活用

TypeScriptでクラスのテンプレートみたいなものがあって基本はそれを参照するけどメンバーに値を設定すればそちらを参照し
テンプレートは影響受けないみたいなの作ろうとして試行錯誤した結果
メンバー増えるごとに処理するのめんどいのでインスタンス生成時に

class PlayerTemplate {
    constructor(public Name:string="Template", public Level:number=0) {
    }
}
var player = new class extends PlayerTemplate {
    Name="Hoge";//設定しなければTemplateのまま
    Level = 99;
};

が一番楽という結論に。
テンプレート変更は困難だけどメソッドも簡単に置き換えられるし
テンプレートを使って別のテンプレート生成みたいなのも簡単だからいいね。

なんとなく動的にclassを宣言生成するのに別言語から来てると違和感があるけど便利すぎる。

乱数の偏り

スプラトゥーン2で勝ち負けがどうも偏るよなぁという
個人的に感じたので勝ち負けを乱数としてみなした場合
偏りとは何ぞやということを考えた。
公式でもあるのかなぁとか探したけどよくわからなかったので
同じ値が続いた数:値が変化した数で偏りを表現してみようと試みる
例えば
〇●〇〇●● 2:3
〇〇〇●●● 4:1
〇●〇●〇● 0:5
みたいな感じでどうだろうか。当然合計すると全体-1の数になるね。
でも値の比率が偏ってると求めたいものは多分求められないので
〇〇〇〇〇〇 5:0
みたいなのはなし。
ちょうどイカリング2を見たら
勝率が25:25だったので(大体そう不思議)
6連勝して6連敗して4連勝したところで終わってる試合だったけど結果は
27:22
んー誤差なのかなぁ。
●〇のような2値じゃないケースだとどうやって計算すればいいのかは思いつかなかった

edge.jsではまり中

Visual Studio 2017でNode.jsのプロジェクトを作成
npmでedge.jsを入れたら
var edge = require(‘edge’);
の瞬間に落ちる。
追いかけてみたら例外メッセージでgitのURLが出てきた。
そこから落としたらものでやり直してみると今度はedge-csがないと怒られるのでnpmで入れてみたら謎なエラーになる。
試行錯誤してedge-csもgitから落としてきてやり直す。
今度は.NETの処理はコメントで書けとエラーが出るがgitに書かれてるes5のサンプルのままなんだよね。
tsconfig.jsonはes5になってるけどes6のサンプルで動かしてみたら動いた!

4時間ほどかけてまだ入り口・・

pixi.jsの動画再生を調べてみた

動画再生対応してるならよいなということで
https://pixijs.io/examples/#/basics/video.js
見てみると動かない。
コードを落としてIISで動かしてみると動く。
よくよく調べてみると
testvideo.mp4を読み込みに行って見つからないでエラーになってる。
でも読み込み処理は
var texture = PIXI.Texture.fromVideo(‘required/assets/testVideo.mp4’);
となってる。
上記処理がiframeにべた書きされたスクリプトでchromeで追いかけるのが困難だったので
Textureクラスにブレイクして逆にたどることで何とか発見。
おそらく問題は
pixi.jsファイルでパスを全部小文字変換してるとこ

function createSource(path, type) {
    if (!type) {
        path = path.split('?').shift().toLowerCase();

three.jsでのviewport領域のclearについて

ビューポートを変更しながら描画しても一度に全体を描画しないと消えるのを回避するには
preserveDrawingBufferをtrueにする
部分描画のときに全体クリアがはしるのを防ぐにはautoClearをfalseにする

var renderer = new THREE.WebGLRenderer({
                    preserveDrawingBuffer: true
                });
renderer.autoClear = false;

ビューポートを設定したあとその領域だけクリアして描画するには以下のようにする。

renderer.setViewport(rect.x, rect.y, rect.w, rect.h);
renderer.setScissorTest(true);
renderer.setScissor(rect.x, rect.y, rect.w, rect.h);
renderer.clear();
renderer.setScissorTest(false);
renderer.render(scene, camera);

今のところ正常に動いてるっぽい。

TypeScriptと戯れる、constructorでのthisの変更

使ってない機能についてネット上のサンプルをもとにちょっと勉強

class Base {
    x: number = 0;
    constructor() {
        // `this`ではなく、新しいオブジェクトを返す
        return {
            x: 1,
        };
    }
}
class Derived extends Base {
    constructor() {
        super();
        this.x += 1;
    }
}

var derved = new Derived();
derved.x;// 2
derved instanceof Base; //false
derved instanceof Derived; //false

これ使うのは最終手段的な感じだなぁ。

TypeScriptと戯れる、クラス拡張と匿名継承

似たような処理をするクラス群で微妙に違うものを定義したい。
クラスとしても使えるし、コード補完で定義済みも用意されてる処理を実現したい。
のでちょっと実験してみた。

クラス中のクラス宣言はできなかったのだが
同名namespaceを利用してclassを拡張する事ができる
のを知った。

普通に行うとコンストラクタを利用して定義済みインスタンスを用意すればいいのだが
匿名クラスを直接実体化することで必要によりメソッドのオーバーライドも可能な実装が実現できた。
プロパティーが多い時にも対応できる。

TypeScriptでは定義さえも処理されることで実現されるため
定義と処理を混在させる事ができるため座標を少しづつずらした定義なのも簡単に実現できる。

以下テストコード※実用するにはImageが読み終わるまで待つなどの処理が必要

    export class ImageResource{
        public Image: HTMLImageElement;
        public Location: { x: number, y: number };
        public Size: { w: number, h: number };
    }
    export namespace ImageResource {
        let ImageA = new Image();
        ImageA.src = "resource.png";
        class DefaultResource extends ImageResource { Image = ImageA; Location = { x: 0, y: 0 }; Size = { w: 64, h: 64 }; }
        let x = 0, w = 64;
        export let Image1: ImageResource = new class extends DefaultResource { Location = { x: x, y: 0 } }; x += w;
        export let Image2: ImageResource = new class extends DefaultResource { Location = { x: x, y: 0 } }; x += w;
        export let Image3: ImageResource = new class extends DefaultResource { Location = { x: x, y: 0 } }; x += w;
    }
//定義済み
    ImageResource.Image2;//VSでのコード補完での選択確認
//生成
    let img=new ImageResource();
//img.でクラスメンバの候補のみ出てくるのを確認

ブラウザのデバッガを使ってのデータ検索

ブラウザのJavaScriptはwindowオブジェクトをルートとして変数が定義されるので
windowオブジェクトから再帰的に指定した値を検索し
見つけたオブジェクト階層を出力することができるのではないかと思い
簡単なスクリプトを書いてみた。
※感覚的にはバイナリエディタでデータ値を検索しアドレスを見つける感じで。


(function(root,data,lvl){let logmax=99,cntmax=10000000;let cnt=0,a=[],r=[],b=[];function f(o){ if(b.indexOf(o)>=0)return;b.push(o);for(let k in o){if(!logmax || cntmax<=cnt)return;a.push(k);cnt++;if(o[k]===data){r.push(a.concat());logmax--;}if(lvl>a.length){if(o[k]) try{f(o[k]);}catch(e){}}a.pop();}};f(root);r.push("search "+cnt+" objects");return r;})(window,"find data",4);

最後の引数はそれぞれ
ルートオブジェクト,検索値,検索最大階層
となっている。

アクセスしたらだめなオブジェクトがあったりして使用時はwindowオブジェクト以外のオブジェクト指定か
ちょっとした改造が必要かもしれない。

動作確認はChromeでDeveloperツールを起動し停止後
Consoleに張り付けて行った。
そのさいconsole.logをつぶされているサイトがあったため使用しないようにした。

Activiz.NETを使ったDicomからのボリュームレンダリング

Activiz.NETを使うとC#でVTKを使用した開発ができる。
VisualStudioからNuGetを使用してさくっとC#でのVTKの開発環境が作れるが欠点もある
Activiz.NETは2012年1月30日に更新されたっきりでVTKのバージョンが古くネット上に多くあるサンプルが使えないことが多い。
その上でどこまでできるかやってみた。
ここまでのものが試行錯誤で2日ほどでできたので案外実用的かもしれない。
フォルダからDicomファイル一式を読み込むのも以下の処理で済むのは驚異的。

            vtkImageData data = new vtkImageData();
            using (vtkDICOMImageReader reader = new vtkDICOMImageReader())
            {
                reader.SetDirectoryName(dir);
                reader.Update();
                data.ShallowCopy(reader.GetOutput());
            }
            data.Update();


ボリュームレンダリングの領域に画像を割り込ませる事ができるので結構よさげ。
左パネルにボリュームレンダリングを
右4分割パネルにそれぞれAxial Sagittal Coronal Oblique断面を表示
分割パネルのほうをクリックで左パネルに断面を表示。
分割パネルのホイール操作で断面の移動。
ボリュームレンダリング側では表示された断面をつかんで動かせる。
TestDataフォルダの中を入れ替えればほかの画像も開けるはず。

MipMprDemo.zip