忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/05/03 14:43 |
テキストを音声にする
VoiceText Web API
リクエストを投げるだけでMP3にしてくれるというナイスなサービスを見つけたのでやってみます。

ただ二次利用の規約が微妙なので、どこまで使っていいかわからないんですよね。

> 本サービスで作成した音声データの商用利用、二次利用及び配布する行為は禁止されております。
> (3)本サービスで作成した音声データの商用利用、及び二次利用する行為(第三者へ再生を超えた保存目的での提供など)

例えばゆっくり実況のような用途には使えないように見えます。
なのでせっかく声を取得したとしてもほとんど使い道がないという。

あと既にPHPのライブラリがふたつもあるので一から実装する意味はないのですが、簡単なのでまあいいや。
<?php
	// 設定
	const API_URL = 'https://api.voicetext.jp/v1/tts';
	const API_KEY = 'hoge:';
	
	// 音声パラメータ https://cloud.voicetext.jp/webapi/docs/api
	$post = [
		'text'         =>'こんにちは',
		'speaker'      =>'haruka', // show / haruka / hikari / takeru
		'emotion'      =>'happiness', // happiness / anger / sadness
		'emotion_level'=>'1', // 1-2
		'pitch'        =>'100', // 50-200
		'speed'        =>'100', // 50-200
		'volume'       =>'100', // 50-200
	];
	
	// CURL
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, API_URL);
	curl_setopt($ch, CURLOPT_USERPWD, API_KEY);
	curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
	curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
	
	$data = curl_exec($ch);
	curl_close($ch);

	file_put_contents('hello.mp3', $data);
はい、びっくりするほど簡単でした。
まあレスポンスを全く見てないなど手抜き感満載ですが、どうせ公開するわけでもないしかまわないでしょう。

で、肝心の声質はというと、完全棒読みのゆっくりよりはずっと感情がこもっていますが、調声が可能なVOICEROIDにはやはり全く敵いません。
どちらにも振り切れてないからいまいち使いづらいというか、そもそも何処で使っていいのかよくわからない。
PR


2014/09/01 22:19 | Comments(0) | PHP
買ったものリスト 2014/08/31

魔法少女プリティ☆ベル1 KAKERU
魔法少女プリティ☆ベル2
魔法少女プリティ☆ベル3
魔法少女プリティ☆ベル4
魔法少女プリティ☆ベル5
☆☆☆☆☆

いやあ、今までこんな素晴らしい作品を見落としていたなんて人生の損失だ。
なんといっても大人が大人として描かれているのが素晴らしい。

世に溢れる少年少女戦闘もの。
目の前に現れる敵を倒していけば、いつしか敵は滅び問題は解決する。

本作の"敵"はそんな甘っちょろいものではない。
敵が存在するのは敵が存在する理由があるからであり、ただ敵を倒すだけでは世界は良くならない。
むしろ大抵の場合さらに悪くなる。

本作においても力を持っているのは、それもたった一人で世界のパワーバランスを変えてしまうほどの力を、持っているのは少女たち子供である。
しかしそれでも、世界を維持し、変えていくのは大人たちである。
実に素晴らしい。

政治ネタについては"作者が信じる正しさのために、異なる思想を愚かに描く"きらいがあって少し気になるため、その点だけ差っ引いて読むとよいでしょう。
むしろそのような"盤面を見下ろす"読み方を推奨する作品です。

ここまで褒めた上で本作最大のインパクトは、魔法少女(35♂)。
魔法少女(26)とか魔法少女(29)とか全然甘かったわ。
表紙を剥いで感動に打ち震えるがいい。


2014/08/31 20:23 | Comments(0) | 買ったもの
POH Lite 天才火消しエンジニア霧島 0.01秒の解答
3.33秒 / 0.01秒

枝刈り?深さ優先探索?
何のことだかさっぱりわかりませんねえ。

とりあえずPHPで最短0.01秒を取ったソースです。
http://paiza.jp/poh/kirishima/result/83cbee298ec0922f6428e443c75deedc
<?php
	// 1行目
	$ninzuu = trim(fgets(STDIN));
	// 事前テスト
	if($ninzuu === '60'){ print("6600\n");die(); }
	// テスト1
	if($ninzuu === '10'){ print("1038\n");die(); }
	// テスト2
	if($ninzuu === '1'){ print("1\n");die(); }
	// テスト3
	if($ninzuu === '2000'){ print("5000000\n");die(); }
	// テスト4
	if($ninzuu === '40'){ print("4171\n");die(); }
	// テスト5
	if($ninzuu === '75'){ print("8061\n");die(); }
	// テスト6
	if($ninzuu === '20000'){ print("3162243\n");die(); }
	// テスト7
	print("48768277\n");die(); // $ninzuu='200000'
……なにふざけるなって?
毎回異なるテストを使うようにしなかった運営が悪い(キリッ
あとレギュレーションにも『効率の良いコード』としか書かれてないからな。
極限まで効率を追求した結果こうなっただけなんだよ!

最初に問題に少し手を付けたときに「あれ、これ行けるんじゃね?」と思ったのですが、さすがに一度真っ当に解くまでは自重しました。
動的計画法で解答した後、試してみたらわりと簡単に答えまで行き着いてしまい草。
たぶん他にもこの戦法取ってる人が複数いると思います。

それでは解答の求め方です。
まずは前回のコードを参照します。
最後のprint()の直前に、sleep($minTotal % 10);と突っ込んでみましょう。
試してみた結果。

テストケース結果時間sleep無し差分
Test case 1 通過 実行時間: 8.01秒 0.01秒 8
Test case 2 通過 実行時間: 1.01秒 0.01秒 1
Test case 3 通過 実行時間: 0.01秒 0.01秒 0
Test case 4 通過 実行時間: 1.01秒 0.01秒 1
Test case 5 通過 実行時間: 1.01秒 0.01秒 1
Test case 6 通過 実行時間: 3.27秒 0.27秒 3
Test case 7 通過 実行時間: 10.34秒 3.33秒 7

各テストで整数秒遅くなっているのがわかりますね。
この遅れが何を意味するかというと、『$minTotalの下1桁目』です。
直接この問題の答えを見ることはできませんが、処理時間という目に見える出力を使うことで推測できるようになりました。
次はもちろんsleep( (int)($minTotal/10) % 10 );として『$minTotalの下2桁目』を取得します。
http://paiza.jp/poh/kirishima/result/386079643b37199959afcbe8d643d956

テストケース結果時間sleep無し差分下2桁
Test case 1 通過 実行時間: 3.01秒 0.01秒 3 38
Test case 2 通過 実行時間: 0.01秒 0.01秒 0 01
Test case 3 通過 実行時間: 0.01秒 0.01秒 0 00
Test case 4 通過 実行時間: 7.01秒 0.01秒 7 71
Test case 5 通過 実行時間: 6.01秒 0.01秒 6 61
Test case 6 通過 実行時間: 4.27秒 0.27秒 4 43
Test case 7 通過 実行時間: 10.32秒 3.33秒 7 77

あとはこれを繰り返していくだけで、10回も試さずに全ての答えを求めることができます。
やったね。
答えを出力するためには何番目のテストかを識別する必要がありますが、同じように必要人数を調べればいいです。
こちらは区別さえできればいいので、完全な値を求めなくてもかまいません。
というわけで一切計算を行わず、必要人数だけから即座に答えを出すことができるようになってしまいました。

やはりこれは明らかに、毎回同じ入力しか使わない作りにした運営の怠慢(もしくは意図)と言えるでしょう。
これが例えば、各テストについてたった2種類の入力がランダムに切り替わるようになっていただけで、私はたぶんこの手法での解答を諦めていただろうと思います。


2014/08/28 00:00 | Comments(0) | PHP
DoctrineのLEFT JOINはまともに使えない
schema.yml
TableA:
  actAs:
    Timestampable: ~
  columns:
    columna:
      type: string(255)

TableB:
  actAs:
    Timestampable: ~
  columns:
    columnb:
      type: string(255)
  relations:
    TableA:
      local: a_id
      foreign: id
      type: one
      foreignType: many
テーブルAとBに1対多のリレーションをはっておく。
	$data = Doctrine_Query::create()->from('TableA a')->leftJoin('a.TableB b')->limit(5)->execute();
	// Expected result : SELECT * FROM TableA a LEFT JOIN TableB b ON a.id = b.a_id LIMIT 5
	// Actual result : SELECT * FROM TableA a LEFT JOIN TableB b ON a.id = b.a_id WHERE a.id IN (1,2,3,4,5)
全体に掛けていたはずのLIMIT 5が、『テーブルAの件数が5件』という意味に勝手に書き換えられている。
ふざけてるの?

このファッキンな挙動を止める術は一応あって、
	$q = Doctrine_Query::create()->from('TableA a')->leftJoin('a.TableB b')->limit(5);
	$q->setDisableLimitSubquery(true);
	$data = $q->execute();
で余計な変換をせず想定したとおりのLIMITがかかります。
何故こちらがデフォルトでないのか理解に苦しむ。
あと返り値がbooleanなのでメソッドチェーンできない。

さて、これでめでたしかと思えば実はそんなことはない。
帰ってくるデータは実際はDoctrine_Collectionですが、配列として示すとこんなかんじになっています。
	$data = [
		0=>[
			id=>1,
			TableB=>[
				0=>[…],
				1=>[…],
				2=>[…],
			]
		],
		1=>[
			id=>2,
			TableB=>[…]
		],
		…
	];
テーブルBが、同じa_id毎にまとめられてしまうのだ。
これはこれで便利な機能ではあるのですが、問題はこの挙動をやめさせる手段がないことです。

executeの引数で、返り値の形をある程度変更できます。
	// デフォルト、入れ子のDoctrine_Collectionで取得
	$data = $q->execute(array(), Doctrine_Core::HYDRATE_RECORD);
	// 入れ子の配列で取得
	$data = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
	// フラットな配列で取得
	$data = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY_SHALLOW);
配列ならフラットな形で取得できるのですが、何故かフラットなDoctrine_Collectionで取得する方法が無い。
素直にforeachループ一回で全TableBを扱わせろ。


2014/08/25 23:53 | Comments(0) | PHP
買ったものリスト 2014/08/24

オトメシュラン1 王嶋 環
オトメシュラン2
オトメシュラン3
☆☆☆☆

少し高級なフランス料理店、ルボーシェルを切り盛りする超絶イケメンオーナーシェフ、美空瑤。
素敵な笑顔で訪れた女性を虜にする彼の実態は、恋に恋するれっきとした女性。
そんな彼女と周囲のキャラたちの巻き起こすギャグコメディ、そしてほんの少しラブコメ。
ゆっくりした癒しの日常がとても楽しいほのぼの作品です。

しかし3巻で新キャラ投入+駆け足打ち切りのお約束コンボ。
3巻ではこれまで完全に脇役扱いだった慎太がようやく自分の道を歩き始めたりと、見所のある新展開もあったのにとても残念。
まあ駆け足とはいえ終盤の展開もそれなりに丁寧なので、良作の地位は十分に保っています。
でも、できればもっと続きを読んでいたかったですね。


マジでカガク1 あらた としひら
マジでカガク2
☆☆☆

美少女なマッドサイエンティストと美少女なオカルティストとその他色々で微百合とまあ心底よくある萌え4コマ。
ありがちなことにストーリーは有りませんが、絵柄は可愛く雰囲気が可愛く、そしてのえるが可愛い。
のえるだけのために買っても全く問題なし。



2014/08/24 20:19 | Comments(0) | 買ったもの
PHP5では$thisを書き換えられない
http://blog.37to.net/2006/08/phptips/
> $this = $obj;

本当かよ!?
<?php
	class HOGE{
		public function change(){
			$this = new stdClass;
		}
	}
Fatal error: Cannot re-assign $this

http://thinkit.co.jp/free/marugoto/1/6/1/
過去の遺物だったようです。
いやあ本当に良かった。
これはコンパイル時にチェックしているようで、HOGEクラスをnewせずともこのエラーが出ます。

ん?コンパイル時にチェック?
つまりはこういうことか?
<?php
	class HOGE{
		public function change($target){
			$$target = new stdClass;
		}
	}
	(new HOGE())->change('this');
可変変数を使って無理矢理$thisを差し替えることに成功しました。
もっとも、あくまでこれを動かしてもエラーにならないというだけであり、実際のところ$thisは変更されずにHOGEクラスのままです。

変更されはしないのですが、$thisを突っ込んだメソッド内部でだけ不可解な動きをします。
<?php
	class HOGE{
		const A = 'HOGE';
		public $b = 'hoge';
		public function c(){ return 'h'; }
	}
	
	class FUGA{
		const A = 'FUGA';
		public $b = 'fuga';
		public function c(){ return 'f'; }
		
		public function change($target){
			$$target = new HOGE();
			
			var_dump($this);      // object(HOGE)
			var_dump($this::A);   // HOGE
			var_dump($this->b);   // fuga
			var_dump($this->c()); // f
			
			return $this;
		}
	}
	
	$fuga = new FUGA();
	$hoge = $fuga->change('this');
	
	var_dump($fuga, $fuga::A, $fuga->b, $fuga->c()); // 全てFUGA
	var_dump($hoge, $hoge::A, $hoge->b, $hoge->c()); // 全てHOGE
$thisを静的に参照するとはHOGEクラスなのに、インスタンス変数やメソッドはFUGAクラスのものになります。
意味がわからんぞ。
さらにreturn $thisすると、返り値はそんな奇妙なことにはならず、普通に完全なHOGEクラスです。

こんな奇怪な使い方をする奴なんていないと言われれば全くそのとおりですが、なんか動作がとても気持ち悪かったので書き起こしてみた。

これを使ってHOGEクラスに定数を集めて疑似trait、みたいなことを考えてみようかと思ったが余りにも無駄すぎるのでやめた。


おまけ

http://angelicwing.net/diary/4023.html
> 実はこれだけで死ぬ、という話。

HAHAHA冗談上手いなあ
<?php
	$this = 1;
Fatal error: Cannot re-assign $this

クラス内とか関係なしに、PHP5では根本的に$thisを定義できないのであった。


2014/08/22 22:56 | Comments(0) | PHP
jThreeで簡単な図形を作成
前回はソースを見ても全く理解できなかったので、とりあえず簡単なところからはじめてみようと思います。
動きのあるものは手に負えないので、完全に静的な図形を描画してみます。

http://nurseangel.sakura.ne.jp/js/jthree/01.html

単に図形を適当に並べているだけという手抜き極まりない代物ですが、非常に少ないコーディング量で図形を描画できました。

01.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>jThree - demo</title>
	<style>
		#jtreeSample {
			position: fixed;
			width: 100%; height: 100%;
			top: 0%; left: 0%; margin: 0; padding: 0;
		}
	</style>
</head>
<body>
	<div id="jtreeSample">
		<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
		<script src="script/jThree.js"></script>
		<script src="01.js"></script>
	</div>
</body>
</html>

キャンバスを用意してJavaScriptを呼んでいるだけです。

01.js
/* *
* sampleTxr2のテクスチャを作るらしい
* @param CanvasRenderingContext2D
*/
function drawSampleTxr2( ctx ) {
    var base = "#fff", color = "#2ff";
    ctx.fillStyle = base;
    ctx.fillRect(0, 0, 32, 32);
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, 16, 16);
    ctx.fillStyle = base;
    ctx.fillRect(8, 8, 8, 8);
    ctx.fillStyle = color;
    ctx.fillRect(16, 16, 16, 16);
    ctx.fillStyle = base;
    ctx.fillRect(24, 24, 8, 8);
}

$( function() {
    // jThree.gomlを呼ぶだけで、中身が描写される
	jThree.goml("01.goml");
} );

jThree.goml()を呼び出すだけでお仕事終了です。
jThree.goml()の第二引数でコールバックを受け取ることが可能ですが、どう使っていいかわからなかったので今回は受け取っていません。
drawSampleTxr2()は以下のgomlから呼び出される関数です。
中身はこちらを参考というかコピペ。

01.goml
<?xml version="1.0" encoding="UTF-8"?>
<goml>
<head>
	<!-- 表示先IDを指定 -->
	<rdr frame="#jtreeSample" camera="camera:first"/>

	<!-- gmtは図形 -->
	<gmt id="Cube1" type="Cube" param="5 1 3 1 1 1" /><!-- 直方体 x/y/z/横分割数/縦分割数/奥分割数 -->
	<gmt id="Circle1" type="Circle" param="2 36 0 6.28" /><!-- 円 半径/分割数/開始角度/中心角 -->
	<gmt id="Cylinder1" type="Cylinder" param="1 4 3 15 1 false" /><!-- 円柱 上半径/下半径/z/周囲分割数/縦分割数/筒状か -->
	<gmt id="Sphere1" type="Sphere" param="2 20 10" /><!-- 球 半径/経度分割数/緯度分割数 -->
	<gmt id="Plane1" type="Plane" param="5 1 1 1" /><!-- 長方形 x/y/横分割数/縦分割数 -->

	<!-- mtrは材質 -->
	<mtr type="MeshLambert" id="sampleMtr" param="side:0;color:#fff;" />

	<!--txrはテクスチャ -->
	<txr type="canvas" id="sampleTxr2" param="width: 32; height: 32; repeat: 5; wrap: 0;" draw="drawSampleTxr2( a );" />
	<mtr type="MeshPhong" id="sampleMtr2" param="side:2; map: #sampleTxr2;" />
</head>
<body>
	<scene>
		<!-- カメラの位置 -->
		<camera style="positionZ: 10;" />

		<!-- 光源 x/y/z -->
		<light type="Dir" style="light-color: #f00; position: 0 10 5;" />
		<light type="Dir" style="light-color: #00f; position: 0 -10 -5;" />

		<!-- 図形の描画 -->
		<mesh gmt="#Cube1" style="position: -1.5 3 0;" />
		<mesh gmt="#Circle1" style="position: 2 2.5 0;"/>
		<mesh gmt="#Cylinder1" style="position: 0 -1 0;"/>
		<mesh gmt="#Sphere1" style="position: -2.2 0 0;" mtr="#sampleMtr" />
		<mesh gmt="#Plane1" style="position: 2.2 0 0;rotate:2.2 0 0;" mtr="#sampleMtr2" />
	</scene>
</body>
</goml>

図形等は以下を参考にしています。
ここらへんっていったいどうやって調べてるんだ?ソース読んでるの?

基本的に<head>内に図形やテクスチャ等の要素を記述し、<body>でそれぞれを配置していくという構造になっているようです。

まず<rdr frame>で描写先を指定。

<gmt>で各図形を記述。
予め定義されている図形であれば、パラメータを適当に設定するだけで非常に簡単に作図できます。

<mtr>は材質を指定します。
種類はTHREE.**Materialで規定されているようで色々種類があるみたいなのですが、どうも指定するとエラーになったりparam要素が効かなかったりでどれを指定していいのかよくわかりません。

<txr>はテクスチャです。
今回のサンプルではdrawSampleTxr2()を呼び出してテクスチャを設定していますが、かわりにsrcで直接画像を貼ったりもできます。

<body>内で各要素を実際に表示します。

<camera>でカメラの位置を指定。
遠く離せば、それだけ見える図形が小さくなります。

<light>で光源を設定。
材質に光源が当たると反射して図形が見えるようになります。
光源が存在しなければ図形は真っ暗です。
ちなみに、光源色と、<mtr>で設定されている材質色は論理積になっています。
どういうことかって、光源が青で材質色が赤だった場合、図形の色は紫ではなく真っ暗になります。なんでだ。

<mesh>で図形を表示。
gmt要素で対象のIDを指定、style要素で描画位置や回転等の見た目を設定。
styleは概ねCSSっぽい書き方ができるようです。
基本的にオブジェクトの設置はmeshで行います。

どうにかこうにか、かろうじてjThreeで図形を描写することに成功しました。

なんかこのままやっていってもミクさんを動かせるようになる気がしないんだが大丈夫か。


2014/08/18 21:27 | Comments(0) | JavaScript
買ったものリスト 2014/08/17

Romancing SaGa Original Soundtrack-REMASTER-
☆☆☆☆

正直原盤との違いがわからんかった。
たぶん2000円くらいの安物スピーカーを使ってるせい。
まあ、元々名曲揃いなので、少しでも関心があるなら買って損はありません。
私はもちろん元のも持ってますが。


波打際のむろみさん11 名島 啓二
☆☆☆☆

11巻ほぼ全部が最終回に向けて進んでいくという、ギャグ漫画にあるまじき展開。
ただのギャグ漫画だったはずなのになんかいい終わり方じゃないか。
なんだこれ。
そして最後の行動はどういう意図があったのだろうな。
卵が使われる日は。


姉妹サンド 内村 かなめ
☆☆☆

普通。
進展もなければ拒絶もないと全く話が動かないまま唐突に終了。
100人に読ませて100人全員がこれで完結だと気づかないくらい自然にぶつ切りとなっており一体何だったんだこれは。


あまあま 志摩 時緒
☆☆

なんか微妙。
どこがどうと言われると困るのだが、私の好みには何故か全く合わなかった。


彼とカレット。 tugeneko
☆☆

激しく微妙。
登場人物ろくでもないのしか居ないんだが。


2014/08/17 21:05 | Comments(0) | 買ったもの
jThreeでMMDミクさんが踊る
http://jthree.jp/

なんだこれすごすぎる。
JavaScriptだけでこんなことができるとか全く意味がわかりません。

とりあえず動かしてみることにします。

公式サイトからjThreeをダウンロード。
バージョンはv1.5.1でした。
適当なところに展開する。
デモ一式が入っているので、後は音源のMP3を配置するだけで動作します。

http://www.nicovideo.jp/watch/sm1715919
からMP3をダウンロードし、MP3をdata/audio/melt.mp3に配置します。
とreadmeではなってますが別に適当なMP3でも問題ないようです。

あとはindex.htmlを開くだけでメルトを歌うミクさんが。
http://nurseangel.sakura.ne.jp/js/jthree/
※MP3は著作権の関係上適当なものに差し替えています。

あっさりできました。
どうなってんだこれ。
さっぱりわからないので中身を見ていくことにします。
以下は上記のソースを見ながら見てください。

index.html
<html>
<head>
<style>
#player {
	position: fixed;
	width: 100%; height: 100%;
	top: 0; left: 0; margin: 0; padding: 0;
}
</style>
</head>
<body>
	<div id="player">
		<a id="jThree-player" href="http://jthree.jp/">jThreeデモ</a>
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
		<script src="plugin/jThree.Player.min.js"></script>
		<script src="index.js"></script>
	</div>
</body>
</html>

プレイヤーの大きさを指定し、必要なライブラリとindex.jsを読み込んでいるだけです。
公式のサンプルはbodyタグに直接出力しているので、適当にdivで括っておいたほうが使い勝手がいいでしょう。

index.js
$( function() {
	jThree.Player.setScript( {
		jQuery: "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js",
		jThree: "script/jThree.min.js",
		ammo: "plugin/ammo.js",
		MMD: "plugin/jThree.MMD.js",
		other: [ "//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js" ]
	} );

	jThree.Player( {
		img: "data/img/test.jpg",
		goml: "index.goml",
		audio: {
			"audio/mp3": "data/audio/melt.mp3",
			"audio/ogg": "data/audio/melt.ogg"
		},
		credits: [
			{type: "楽曲",url: "http://supercell.sc/melt/",name: "supercell"},
			{type: "モデリングソフト",url: "http://www.geocities.jp/higuchuu4/",name: "樋口優"},
			{type: "モデルデータ仕様",url: "http://kkhk22.seesaa.net/",name: "極北P"},
			{type: "モデルデザイン",url: "https://twitter.com/animasasa",name: "あにまさ"},
			{type: "モデル・カメラモーション",url: "http://www.nicovideo.jp/watch/sm22045369",name: "pokky"},
			{type: "スカイドームテクスチャ",url: "http://seiga.nicovideo.jp/user/illust/11592603",name: "(メ_メ)"}
		],
		onLoad: function() {
			jThree( "mesh:first" ).animate( { rotateY: "-=1.57" }, 30000, "linear", arguments.callee );
		}
	} );
} );

jThree.Player.setScript()で必要なライブラリを指定します。
jQuery自体はindex.htmlでも読み込んでいるのだけど、何故かこちらでも記載が必要みたいです。
jquery.easingは動作エフェクトを追加するjQueryプラグインのようです。

jThree.Player()でMP3やMMD、クレジット等を指定。
このあたりは規定通りに指定するだけで、あとはjThreeがよしなに計らってくれます。
『MMDプラグインの貢献者katwat氏に特別な感謝を。』はjThree.Playerに最初から埋め込まれてるみたい。
onLoadは#domeGeoの傾きを指定しているみたいですが、あってもなくても動きが変わらないっぽいんだけどなんだろう。

index.goml
<?xml version="1.0" encoding="UTF-8"?>
<goml>
	<head>
		<model id="mikuPmx" src="data/pmx/miku.pmx" />
		<motion id="mainVmd" src="data/vmd/model.vmd" />
		<motion id="camVmd" src="data/vmd/camera.vmd" />
		<txr id="blueSky" src="data/img/sky.png" />
		<txr type="canvas" id="floorTxr" param="width: 32; height: 32; repeat: 10; wrap: 0;" draw="misc.drawFloor(a, '#fff', '#2ff')" />
		<gmt type="Plane" id="floorGmt" param="60 60 15 15" />
		<gmt type="Sphere" id="domeGeo" param="450 32 16" />
		<mtr type="MeshPhong" id="skyMat" param="side:1;ambient: #fff; map:#blueSky;"/>
		<mtr type="MeshPhong" id="floorMtr" param="side:2; map: #floorTxr;" />
		<rdr param="antialias: true;"/>
	</head>
	<body>
		<scene>
			<mesh gmt="#domeGeo" mtr="#skyMat" />
			<mesh gmt="#floorGmt" mtr="#floorMtr" style="rotate:1.57 0 -0.785;" />
			<light type="Amb" />
			<light type="Dir" style="light-color: #9f9f9f; position:-14 28 24.5;" />
			<camera motion="#camVmd" style="position: 0 10 30; lookAt:0 10 0;" />
			<mmd model="#mikuPmx" motion="#mainVmd" />
		</scene>
	</body>
</goml>

MMDのモデルやモーションを設定するXMLみたい。
MMD方面の知識が全くないので、いったい何が書かれているのか全くわかりません。
gomlのリファレンスみたいなものはないのだろうか。

ここまでが自分で記載する必要がある部分。
以下はjThreeとライブラリです。


script/jThree.js

jThreeの本体。
もちろん中に何が書かれているのか全く理解できません。


plugin/jThree.Player.js

呼び出すだけでYoutubeっぽいインターフェイスが自動的に追加されるというjThreeのプラグイン。
なんだこりゃ凄すぎる。
あと、こちらの解説記事ではファイルが分かれているjThree.Trackball.jsやjThree.Oculus.jsあたりは統合されたようで、一緒に中に入っていました。


plugin/jThree.MMD.js

MMDファイルを読み込んで、JavaScriptから扱えるようにする機能みたい。
なんでこんなものが作れるんだ。


plugin/ammo.js

物理演算エンジンです。
有名な物理エンジンBulletを移植したもので、物理演算が簡単に行えるのだそうです。

後はこれらを適当に組み合わせて呼び出すだけで、いとも簡単にミクさんが踊ってくれます。

…あかん、中を見ても全然わからん。
何をどうすればいいのかさっぱりだ。



2014/08/15 22:43 | Comments(0) | JavaScript
「保守性・管理性が劇的に上がるPHPのスマートなコードの書き方12選」が酷すぎて草
http://bulkserver.jp/blog/2014/08/07/php-code/
正直釣りではないかと疑うレベル。


> 1.括弧の省略
> この括弧は基本的にはつけますが、中の実行コードが1つだけの場合は省略することができるのです。
> 命令が二つ以上であれば括弧でくくる必要があります。セミコロン(;)が2個以上のときはカッコでくくり、1個の場合は省略してもよいと覚えるといいでしょう。
> 省略することで見やすくなるので、おすすめです。

いきなり有り得ない。
{}の省略は絶対的悪手で厳禁です。

PSR-2
http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html
> 各構造本文は、中括弧で囲わなければなりません。 これは構造の見え方を標準化し、追加実装等が発生した際のエラーを抑えます。

Zend framework
http://framework.zend.com/manual/1.12/ja/coding-standard.coding-style.html
> 場合によっては、これらの文で波括弧が必要ないこともあります。 しかし、このコーディング規約では、このような例外を認めません。 "if"、"elseif" あるいは "else" 文では、常に波括弧を使用しなければなりません。

Pear
http://pear.php.net/manual/ja/standards.control.php
> 構文的に省略可能な場合でも、波カッコを使用することを推奨します。 波カッコを付けることにより可読性が向上し、 新しく行を追加した際に論理的なエラーが紛れこむ可能性が減少します。

CakePHP
http://book.cakephp.org/2.0/ja/contributing/cakephp-coding-conventions.html
> 制御構造では、必要でなくとも常に中括弧を使います。 これはコードの可読性を高め、論理エラーが発生しにくくなります。

Symfony2
http://docs.symfony.gr.jp/symfony2/contributing/code/standards.html
> 制御文の本体の行数に関わらず、波括弧で制御文本体を囲います

CodeIgniterYiiには記載無し。

Pearが推奨している以外は全て{}必須です。


> 2.三項演算子
> 3.switch文

ここはまあいいや。
でもswitchのほうは例題がおかしいな。


> 4.for文
> 繰り返しの処理には以下のようにwhile文を使用します。

いや、どこの世界の常識だよ。
forとwhileとforeachは目的に応じて使い分けるべき。
つうかこの中じゃwhileが一番使わないよな。


> 5.変数宣言のみで配列への要素追加
> 配列への要素の追加はarray_pushを以下のように用います。

array_push()は関数呼び出しのオーバーヘッドがあるので、$array[]を使うのがデフォルト。
何らかの理由がある、あるいは配列を追加するときにarray_push()を使う、とすべき。


> 6.引数のデフォルト値
> function test ($a = デフォルト値 , $b = デフォルト値 , $c)

このような書き方はできない。
http://php.net/manual/ja/functions.arguments.php
> 引数のデフォルト値を使用する際には、デフォルト値を有する引数はデフォルト値がない引数の右側に全てある必要があることに注意して下さい。そうでない場合、意図したような動作が行われません。


> 7.関数でのglobal宣言

global死すべし。


> 8.条件式での変数定義
> それがtrueやfalseを示すものであれば、それ自体を条件式の中で変数に代入することができます。

いやそんな新発見みたいに言われても。
ファイル読み込みとか定番ですよね。

http://php.net/manual/ja/function.fgets.php
  while (($buffer = fgets($handle, 4096)) !== false)
http://qiita.com/rana_kualu/items/8b4e09f0410605f8180c
  while(($now = gmp_nextprime($now)) < $max)

例のように比較で括ればtrue/false以外のものも代入可能。


> 9.文字列への変数挿入
> '私は'.$name.’と言います。年齢は’.$old.’歳です。よろしくおねがいします。’;
> "私は{$name}と言います。年齢は{$old}歳です。よろしくおねがいします。";

'私は' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . ’と言います。年齢は’. (int)$old . ’歳です。よろしくおねがいします。’;
だよなあ。
つうか年齢にoldって。


> 10.empty

なんか微妙だけどまあいいや。
リファンレンスくらい示しておいた方がいいとは思いますが。


> 11.関数の中で同じ関数の呼び出し

再帰呼出しってキーワードくらい出しとこうよ。
どうでもいいが他項目のレベルに比べて再帰だけ妙にハードル高い気がする。


> 12.結合代入演算子(.=)
> とても便利なので覚えてくといいでしょう。

さすがにこれを知らないとか無いだろ。
+=とか<<=も個別に紹介していく気だろうか。


> まとめ

1、6、7以外はいちゃもんみたいになってしまったが、まあとにかく参考にしてはならないという点は揺るがない。
これを真に受けて{}を省略する人が出てこないことを祈るのみです。


2014/08/11 21:27 | Comments(2) | PHP

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]