diff --git a/.prettierignore b/.prettierignore index 20214acb..c615bef7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -158,3 +158,5 @@ dist Caddyfile dockerdata/ packages/api-types/dist + +apps/web/public/static/vendor/ diff --git a/apps/web/locales/en.json b/apps/web/locales/en.json index 175d618d..1488775f 100644 --- a/apps/web/locales/en.json +++ b/apps/web/locales/en.json @@ -112,6 +112,7 @@ "live.player.autoplay-blocked": "Click/tap to play", "live.player.seek-latest": "Seek to the latest", "live.player.reload": "Reload the stream", + "live.player.danmaku": "弾幕の表示/非表示切り替え", "live.player.wide": "Wide in window", "live.player.maximize": "Maximize", "page.account-settings.title": "Account settings", diff --git a/apps/web/locales/ja.json b/apps/web/locales/ja.json index 1ddd57f3..53dee87a 100644 --- a/apps/web/locales/ja.json +++ b/apps/web/locales/ja.json @@ -112,6 +112,7 @@ "live.player.autoplay-blocked": "クリック/タップして再生", "live.player.seek-latest": "最新までシーク", "live.player.reload": "配信を開き直す", + "live.player.danmaku": "弾幕の表示/非表示切り替え", "live.player.wide": "ウインドウ内ワイド", "live.player.maximize": "最大化", "page.account-settings.title": "アカウント設定", diff --git a/apps/web/organisms/live/live-app.tsx b/apps/web/organisms/live/live-app.tsx index f2892a7f..53fd1a68 100644 --- a/apps/web/organisms/live/live-app.tsx +++ b/apps/web/organisms/live/live-app.tsx @@ -102,6 +102,7 @@ export const LiveApp: FC = ({ live, streamer }) => { liveId={live.id} liveTitle={live.title} userId={user?.id} + comments={comments} /> ) : ( | undefined; onChangePlayType: (type: PlayType<'live'>) => void; + onChangeDanmaku: () => void; }; type VideoProps = { @@ -204,6 +206,14 @@ export const Controller: FC = props => { + {isLive && ( + + + + )} + {props.playType && ( diff --git a/apps/web/organisms/live/video/live-player.tsx b/apps/web/organisms/live/video/live-player.tsx index d27173cf..30060f34 100644 --- a/apps/web/organisms/live/video/live-player.tsx +++ b/apps/web/organisms/live/video/live-player.tsx @@ -8,6 +8,8 @@ import { Controller } from './controller'; import { LiveUrls } from 'api-types/api/v1/lives/_liveId@number/url'; import { useVideoStream } from '~/utils/hooks/use-video-stream'; import { useMuxData } from '~/utils/hooks/use-mux-data'; +import { CommentPublic } from 'api-types/common/types'; +import { Gravity } from '~/utils/danmaku/gravity/jgravity-fork'; type Props = { thumbnailUrl: string; @@ -19,6 +21,7 @@ type Props = { liveId?: number; liveTitle?: string; userId?: number; + comments: CommentPublic[]; }; export const LivePlayer: FC = ({ @@ -29,10 +32,14 @@ export const LivePlayer: FC = ({ isStreamer, liveId, liveTitle, - userId + userId, + comments }) => { const videoRef = useRef(null); const containerRef = useRef(null); + const danmakuRef = useRef(null); + const gravityRef = useRef(null); + const commentAddedRef = useRef | null>(null); const lastPlayingRef = useRef(0); const [latency, setLatency] = useState(-1); const [error, setError] = useState(); @@ -40,6 +47,7 @@ export const LivePlayer: FC = ({ const { show, events } = usePlayerTouch(); const [canPlay, setCanPlay] = useState(false); const [maybeBlocked, setMaybeBlocked] = useState(false); + const [danmaku, setDanmaku] = useState(true); const { playType, setPlayType, play } = useVideoStream('live', videoRef, url); useMuxData(videoRef, liveId, liveTitle, userId, playType); @@ -161,6 +169,61 @@ export const LivePlayer: FC = ({ } }, [canPlay, autoSeek]); + useEffect(() => { + const container = danmakuRef.current; + if (!container || !danmaku) { + return; + } + + void (async () => { + const gravity = new Gravity({}, container); + await gravity.init(); + gravityRef.current = gravity; + })(); + + return () => { + const gravity = gravityRef.current; + if (gravity) { + gravity.destroy(); + gravityRef.current = null; + } + }; + }, [danmaku]); + + useEffect(() => { + if (!danmaku) { + commentAddedRef.current = null; + return; + } + if (!commentAddedRef.current) { + const set = new Set(); + commentAddedRef.current = set; + + comments.forEach(comment => { + set.add(comment.id); + }); + return; + } + + const gravity = gravityRef.current; + if (!gravity) { + return; + } + + for (const comment of comments) { + if (commentAddedRef.current?.has(comment.id)) { + break; + } + + commentAddedRef.current.add(comment.id); + const dom = gravity.add(comment.content, false); + + setTimeout(() => { + gravity.remove(dom); + }, 10000); + } + }, [comments, danmaku]); + return ( = ({ ); @@ -216,6 +282,56 @@ const VideoContainer = styled(AspectRatio)` background-repeat: no-repeat; `; +const DanmakuContainer = styled(Box)` + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; + user-select: none; + + span { + /* credit: https://qiita.com/NoxGit/items/eb0904822c0f0fe97650 */ + text-shadow: + black 2px 0, + black -2px 0, + black 0 -2px, + black 0 2px, + black 2px 2px, + black -2px 2px, + black 2px -2px, + black -2px -2px, + black 1px 2px, + black -1px 2px, + black 1px -2px, + black -1px -2px, + black 2px 1px, + black -2px 1px, + black 2px -1px, + black -2px -1px; + + font-size: 1.5rem; + line-height: 1 !important; + color: #fff !important; + opacity: 0.7; + white-space: nowrap; + max-width: 100%; + overflow-x: hidden; + overflow-y: visible; + + ::-webkit-scrollbar { + display: none; + } + + @media (min-width: 768px) { + font-size: 2rem; + } + } +`; + const LoadingContainer = styled(Center)` position: absolute; width: 100%; diff --git a/apps/web/public/static/vendor/box2d.min.js b/apps/web/public/static/vendor/box2d.min.js new file mode 100644 index 00000000..f013038c --- /dev/null +++ b/apps/web/public/static/vendor/box2d.min.js @@ -0,0 +1,3 @@ +/* eslint-disable */ +// Box2Djs (port of Box2DFlash 1.4.3.1) :: http://box2d-js.sourceforge.net/ +var b2Settings=Class.create();b2Settings.prototype={initialize:function(){}};b2Settings.USHRT_MAX=65535;b2Settings.b2_pi=Math.PI;b2Settings.b2_massUnitsPerKilogram=1;b2Settings.b2_timeUnitsPerSecond=1;b2Settings.b2_lengthUnitsPerMeter=30;b2Settings.b2_maxManifoldPoints=2;b2Settings.b2_maxShapesPerBody=64;b2Settings.b2_maxPolyVertices=8;b2Settings.b2_maxProxies=1024;b2Settings.b2_maxPairs=8*b2Settings.b2_maxProxies;b2Settings.b2_linearSlop=.005*b2Settings.b2_lengthUnitsPerMeter;b2Settings.b2_angularSlop=2/180*b2Settings.b2_pi;b2Settings.b2_velocityThreshold=1*b2Settings.b2_lengthUnitsPerMeter/b2Settings.b2_timeUnitsPerSecond;b2Settings.b2_maxLinearCorrection=.2*b2Settings.b2_lengthUnitsPerMeter;b2Settings.b2_maxAngularCorrection=8/180*b2Settings.b2_pi;b2Settings.b2_contactBaumgarte=.2;b2Settings.b2_timeToSleep=.5*b2Settings.b2_timeUnitsPerSecond;b2Settings.b2_linearSleepTolerance=.01*b2Settings.b2_lengthUnitsPerMeter/b2Settings.b2_timeUnitsPerSecond;b2Settings.b2_angularSleepTolerance=2/180/b2Settings.b2_timeUnitsPerSecond;b2Settings.b2Assert=function(a){if(!a){var b;b.x++}};var b2Vec2=Class.create();b2Vec2.prototype={initialize:function(a,b){this.x=a;this.y=b},SetZero:function(){this.x=0;this.y=0},Set:function(a,b){this.x=a;this.y=b},SetV:function(a){this.x=a.x;this.y=a.y},Negative:function(){return new b2Vec2(-this.x,-this.y)},Copy:function(){return new b2Vec2(this.x,this.y)},Add:function(a){this.x+=a.x;this.y+=a.y},Subtract:function(a){this.x-=a.x;this.y-=a.y},Multiply:function(a){this.x*=a;this.y*=a},MulM:function(a){var b=this.x;this.x=a.col1.x*b+a.col2.x*this.y;this.y=a.col1.y*b+a.col2.y*this.y},MulTM:function(a){var b=b2Math.b2Dot(this,a.col1);this.y=b2Math.b2Dot(this,a.col2);this.x=b},CrossVF:function(a){var b=this.x;this.x=a*this.y;this.y=-a*b},CrossFV:function(a){var b=this.x;this.x=-a*this.y;this.y=a*b},MinV:function(a){this.x=this.xa.x?this.x:a.x;this.y=this.y>a.y?this.y:a.y},Abs:function(){this.x=Math.abs(this.x);this.y=Math.abs(this.y)},Length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},Normalize:function(){var a=this.Length();if(a0?a:-a};b2Math.b2AbsV=function(a){var b=new b2Vec2(b2Math.b2Abs(a.x),b2Math.b2Abs(a.y));return b};b2Math.b2AbsM=function(a){var b=new b2Mat22(0,b2Math.b2AbsV(a.col1),b2Math.b2AbsV(a.col2));return b};b2Math.b2Min=function(a,b){return ab?a:b};b2Math.b2MaxV=function(a,b){var c=new b2Vec2(b2Math.b2Max(a.x,b.x),b2Math.b2Max(a.y,b.y));return c};b2Math.b2Clamp=function(a,b,c){return b2Math.b2Max(b,b2Math.b2Min(a,c))};b2Math.b2ClampV=function(a,b,c){return b2Math.b2MaxV(b,b2Math.b2MinV(a,c))};b2Math.b2Swap=function(a,b){var c=a[0];a[0]=b[0];b[0]=c};b2Math.b2Random=function(){return Math.random()*2-1};b2Math.b2NextPowerOfTwo=function(a){a|=a>>1&2147483647;a|=a>>2&1073741823;a|=a>>4&268435455;a|=a>>8&16777215;a|=a>>16&65535;return a+1};b2Math.b2IsPowerOfTwo=function(a){var b=a>0&&(a&a-1)==0;return b};b2Math.tempVec2=new b2Vec2;b2Math.tempVec3=new b2Vec2;b2Math.tempVec4=new b2Vec2;b2Math.tempVec5=new b2Vec2;b2Math.tempMat=new b2Mat22;var b2AABB=Class.create();b2AABB.prototype={IsValid:function(){var a=this.maxVertex.x;var b=this.maxVertex.y;a=this.maxVertex.x;b=this.maxVertex.y;a-=this.minVertex.x;b-=this.minVertex.y;var c=a>=0&&b>=0;c=c&&this.minVertex.IsValid()&&this.maxVertex.IsValid();return c},minVertex:new b2Vec2,maxVertex:new b2Vec2,initialize:function(){this.minVertex=new b2Vec2;this.maxVertex=new b2Vec2}};var b2Bound=Class.create();b2Bound.prototype={IsLower:function(){return(this.value&1)==0},IsUpper:function(){return(this.value&1)==1},Swap:function(a){var b=this.value;var c=this.proxyId;var d=this.stabbingCount;this.value=a.value;this.proxyId=a.proxyId;this.stabbingCount=a.stabbingCount;a.value=b;a.proxyId=c;a.stabbingCount=d},value:0,proxyId:0,stabbingCount:0,initialize:function(){}};var b2BoundValues=Class.create();b2BoundValues.prototype={lowerValues:[0,0],upperValues:[0,0],initialize:function(){this.lowerValues=[0,0];this.upperValues=[0,0]}};var b2Pair=Class.create();b2Pair.prototype={SetBuffered:function(){this.status|=b2Pair.e_pairBuffered},ClearBuffered:function(){this.status&=~b2Pair.e_pairBuffered},IsBuffered:function(){return(this.status&b2Pair.e_pairBuffered)==b2Pair.e_pairBuffered},SetRemoved:function(){this.status|=b2Pair.e_pairRemoved},ClearRemoved:function(){this.status&=~b2Pair.e_pairRemoved},IsRemoved:function(){return(this.status&b2Pair.e_pairRemoved)==b2Pair.e_pairRemoved},SetFinal:function(){this.status|=b2Pair.e_pairFinal},IsFinal:function(){return(this.status&b2Pair.e_pairFinal)==b2Pair.e_pairFinal},userData:null,proxyId1:0,proxyId2:0,next:0,status:0,initialize:function(){}};b2Pair.b2_nullPair=b2Settings.USHRT_MAX;b2Pair.b2_nullProxy=b2Settings.USHRT_MAX;b2Pair.b2_tableCapacity=b2Settings.b2_maxPairs;b2Pair.b2_tableMask=b2Pair.b2_tableCapacity-1;b2Pair.e_pairBuffered=1;b2Pair.e_pairRemoved=2;b2Pair.e_pairFinal=4;var b2PairCallback=Class.create();b2PairCallback.prototype={PairAdded:function(a,b){return null},PairRemoved:function(a,b,c){},initialize:function(){}};var b2BufferedPair=Class.create();b2BufferedPair.prototype={proxyId1:0,proxyId2:0,initialize:function(){}};var b2PairManager=Class.create();b2PairManager.prototype={initialize:function(){var a=0;this.m_hashTable=new Array(b2Pair.b2_tableCapacity);for(a=0;ab){var c=a;a=b;b=c}var d=b2PairManager.Hash(a,b)&b2Pair.b2_tableMask;var e=e=this.FindHash(a,b,d);if(e!=null){return e}var f=this.m_freePair;e=this.m_pairs[f];this.m_freePair=e.next;e.proxyId1=a;e.proxyId2=b;e.status=0;e.userData=null;e.next=this.m_hashTable[d];this.m_hashTable[d]=f;++this.m_pairCount;return e},RemovePair:function(a,b){if(a>b){var c=a;a=b;b=c}var d=b2PairManager.Hash(a,b)&b2Pair.b2_tableMask;var e=this.m_hashTable[d];var f=null;while(e!=b2Pair.b2_nullPair){if(b2PairManager.Equals(this.m_pairs[e],a,b)){var g=e;if(f){f.next=this.m_pairs[e].next}else{this.m_hashTable[d]=this.m_pairs[e].next}var h=this.m_pairs[g];var i=h.userData;h.next=this.m_freePair;h.proxyId1=b2Pair.b2_nullProxy;h.proxyId2=b2Pair.b2_nullProxy;h.userData=null;h.status=0;this.m_freePair=g;--this.m_pairCount;return i}else{f=this.m_pairs[e];e=f.next}}return null},Find:function(a,b){if(a>b){var c=a;a=b;b=c}var d=b2PairManager.Hash(a,b)&b2Pair.b2_tableMask;return this.FindHash(a,b,d)},FindHash:function(a,b,c){var d=this.m_hashTable[c];while(d!=b2Pair.b2_nullPair&&b2PairManager.Equals(this.m_pairs[d],a,b)==false){d=this.m_pairs[d].next}if(d==b2Pair.b2_nullPair){return null}return this.m_pairs[d]},ValidateBuffer:function(){},ValidateTable:function(){},m_broadPhase:null,m_callback:null,m_pairs:null,m_freePair:0,m_pairCount:0,m_pairBuffer:null,m_pairBufferCount:0,m_hashTable:null};b2PairManager.Hash=function(a,b){var c=b<<16&4294901760|a;c=~c+(c<<15&4294934528);c=c^c>>12&1048575;c=c+(c<<2&4294967292);c=c^c>>4&268435455;c=c*2057;c=c^c>>16&65535;return c};b2PairManager.Equals=function(a,b,c){return a.proxyId1==b&&a.proxyId2==c};b2PairManager.EqualsPair=function(a,b){return a.proxyId1==b.proxyId1&&a.proxyId2==b.proxyId2};var b2BroadPhase=Class.create();b2BroadPhase.prototype={initialize:function(a,b){this.m_pairManager=new b2PairManager;this.m_proxyPool=new Array(b2Settings.b2_maxPairs);this.m_bounds=new Array(2*b2Settings.b2_maxProxies);this.m_queryResults=new Array(b2Settings.b2_maxProxies);this.m_quantizationFactor=new b2Vec2;var c=0;this.m_pairManager.Initialize(this,b);this.m_worldAABB=a;this.m_proxyCount=0;for(c=0;c0&&q0){d=p;while(d0){d=o;while(d0&&rd[b.upperBounds[c]].value)return false;if(d[a.upperBounds[c]].valued[b.upperBounds[c]].value)return false;if(a.upperValues[c]0){var k=h-1;var l=e[k].stabbingCount;while(l){if(e[k].IsLower()){var m=this.m_proxyPool[e[k].proxyId];if(h<=m.upperBounds[g]){this.IncrementOverlapCount(e[k].proxyId);--l}}--k}}a[0]=h;b[0]=i},IncrementOverlapCount:function(a){var b=this.m_proxyPool[a];if(b.timeStampc){e=f-1}else if(a[f].value0){a[e].id=b[0].id}else{a[e].id=b[1].id}++e}return e};b2Collision.EdgeSeparation=function(a,b,c){var d=a.m_vertices;var e=c.m_vertexCount;var f=c.m_vertices;var g=a.m_normals[b].x;var h=a.m_normals[b].y;var i=g;var j=a.m_R;g=j.col1.x*i+j.col2.x*h;h=j.col1.y*i+j.col2.y*h;var k=g;var l=h;j=c.m_R;i=k*j.col1.x+l*j.col1.y;l=k*j.col2.x+l*j.col2.y;k=i;var m=0;var n=Number.MAX_VALUE;for(var o=0;ok){k=m;j=l}}var n=b2Collision.EdgeSeparation(b,j,c);if(n>0&&d==false){return n}var o=j-1>=0?j-1:e-1;var p=b2Collision.EdgeSeparation(b,o,c);if(p>0&&d==false){return p}var q=j+10&&d==false){return r}var s=0;var t;var u=0;if(p>n&&p>r){u=-1;s=o;t=p}else if(r>n){u=1;s=q;t=r}else{a[0]=j;return n}while(true){if(u==-1)j=s-1>=0?s-1:e-1;else j=s+10&&d==false){return n}if(n>t){s=j;t=n}else{break}}a[0]=s;return t};b2Collision.FindIncidentEdge=function(a,b,c,d){var e=b.m_vertexCount;var f=b.m_vertices;var g=d.m_vertexCount;var h=d.m_vertices;var i=c;var j=c+1==e?0:c+1;var k=f[j];var l=k.x;var m=k.y;k=f[i];l-=k.x;m-=k.y;var n=l;l=m;m=-n;var o=1/Math.sqrt(l*l+m*m);l*=o;m*=o;var p=l;var q=m;n=p;var r=b.m_R;p=r.col1.x*n+r.col2.x*q;q=r.col1.y*n+r.col2.y*q;var s=p;var t=q;r=d.m_R;n=s*r.col1.x+t*r.col1.y;t=s*r.col2.x+t*r.col2.y;s=n;var u=0;var v=0;var w=Number.MAX_VALUE;for(var x=0;x0&&d==false)return;var h=0;var i=[h];var j=b2Collision.FindMaxSeparation(i,c,b,d);h=i[0];if(j>0&&d==false)return;var k;var l;var m=0;var n=0;var o=.98;var p=.001;if(j>o*g+p){k=c;l=b;m=h;n=1}else{k=b;l=c;m=e;n=0}var q=[new ClipVertex,new ClipVertex];b2Collision.FindIncidentEdge(q,k,m,l);var r=k.m_vertexCount;var s=k.m_vertices;var t=s[m];var u=m+1h*h&&d==false){return}var i;if(go){return}if(q>n){n=q;m=p}}if(no){return}a.pointCount=1;a.normal.Set(j.col1.x*f+j.col2.x*g,j.col1.y*f+j.col2.y*g);e=a.points[0];e.id.features.incidentEdge=b2Collision.b2_nullFeature;e.id.features.incidentVertex=s;e.id.features.referenceFace=b2Collision.b2_nullFeature;e.id.features.flip=0;e.position.x=c.m_position.x-o*a.normal.x;e.position.y=c.m_position.y-o*a.normal.y;e.separation=l-o;return}var x=(h-b.m_vertices[s].x)*u+(i-b.m_vertices[s].y)*v;e=a.points[0];e.id.features.incidentEdge=b2Collision.b2_nullFeature;e.id.features.incidentVertex=b2Collision.b2_nullFeature;e.id.features.referenceFace=b2Collision.b2_nullFeature;e.id.features.flip=0;var y,z;if(x<=0){y=b.m_vertices[s].x;z=b.m_vertices[s].y;e.id.features.incidentVertex=s}else if(x>=w){y=b.m_vertices[t].x;z=b.m_vertices[t].y;e.id.features.incidentVertex=t}else{y=u*x+b.m_vertices[s].x;z=v*x+b.m_vertices[s].y;e.id.features.incidentEdge=s}f=h-y;g=i-z;l=Math.sqrt(f*f+g*g);f/=l;g/=l;if(l>o){return}a.pointCount=1;a.normal.Set(j.col1.x*f+j.col2.x*g,j.col1.y*f+j.col2.y*g);e.position.x=c.m_position.x-o*a.normal.x;e.position.y=c.m_position.y-o*a.normal.y;e.separation=l-o};b2Collision.b2TestOverlap=function(a,b){var c=b.minVertex;var d=a.maxVertex;var e=c.x-d.x;var f=c.y-d.y;c=a.minVertex;d=b.maxVertex;var g=c.x-d.x;var h=c.y-d.y;if(e>0||f>0)return false;if(g>0||h>0)return false;return true};var Features=Class.create();Features.prototype={set_referenceFace:function(a){this._referenceFace=a;this._m_id._key=this._m_id._key&4294967040|this._referenceFace&255},get_referenceFace:function(){return this._referenceFace},_referenceFace:0,set_incidentEdge:function(a){this._incidentEdge=a;this._m_id._key=this._m_id._key&4294902015|this._incidentEdge<<8&65280},get_incidentEdge:function(){return this._incidentEdge},_incidentEdge:0,set_incidentVertex:function(a){this._incidentVertex=a;this._m_id._key=this._m_id._key&4278255615|this._incidentVertex<<16&16711680},get_incidentVertex:function(){return this._incidentVertex},_incidentVertex:0,set_flip:function(a){this._flip=a;this._m_id._key=this._m_id._key&16777215|this._flip<<24&4278190080},get_flip:function(){return this._flip},_flip:0,_m_id:null,initialize:function(){}};var b2ContactID=Class.create();b2ContactID.prototype={initialize:function(){this.features=new Features;this.features._m_id=this},Set:function(a){this.set_key(a._key)},Copy:function(){var a=new b2ContactID;a.set_key(this._key);return a},get_key:function(){return this._key},set_key:function(a){this._key=a;this.features._referenceFace=this._key&255;this.features._incidentEdge=(this._key&65280)>>8&255;this.features._incidentVertex=(this._key&16711680)>>16&255;this.features._flip=(this._key&4278190080)>>24&255},features:new Features,_key:0};var b2ContactPoint=Class.create();b2ContactPoint.prototype={position:new b2Vec2,separation:null,normalImpulse:null,tangentImpulse:null,id:new b2ContactID,initialize:function(){this.position=new b2Vec2;this.id=new b2ContactID}};var b2Distance=Class.create();b2Distance.prototype={initialize:function(){}};b2Distance.ProcessTwo=function(a,b,c,d,e){var f=-e[1].x;var g=-e[1].y;var h=e[0].x-e[1].x;var i=e[0].y-e[1].y;var j=Math.sqrt(h*h+i*i);h/=j;i/=j;var k=f*h+g*i;if(k<=0||j=0&&w>=0){var A=v/(v+w);a.x=c[1].x+A*(c[2].x-c[1].x);a.y=c[1].y+A*(c[2].y-c[1].y);b.x=d[1].x+A*(d[2].x-d[1].x);b.y=d[1].y+A*(d[2].y-d[1].y);c[0].SetV(c[2]);d[0].SetV(d[2]);e[0].SetV(e[2]);return 2}var B=x*(j*g-k*f);if(B<=0&&t>=0&&u>=0){var A=t/(t+u);a.x=c[0].x+A*(c[2].x-c[0].x);a.y=c[0].y+A*(c[2].y-c[0].y);b.x=d[0].x+A*(d[2].x-d[0].x);b.y=d[0].y+A*(d[2].y-d[0].y);c[1].SetV(c[2]);d[1].SetV(d[2]);e[1].SetV(e[2]);return 2}var C=z+B+y;C=1/C;var D=z*C;var E=B*C;var F=1-D-E;a.x=D*c[0].x+E*c[1].x+F*c[2].x;a.y=D*c[0].y+E*c[1].y+F*c[2].y;b.x=D*d[0].x+E*d[1].x+F*d[2].x;b.y=D*d[0].y+E*d[1].y+F*d[2].y;return 3};b2Distance.InPoinsts=function(a,b,c){for(var d=0;d0){return false}}return true},initialize:function(a,b,c){this.m_R=new b2Mat22;this.m_position=new b2Vec2;this.m_userData=a.userData;this.m_friction=a.friction;this.m_restitution=a.restitution;this.m_body=b;this.m_proxyId=b2Pair.b2_nullProxy;this.m_maxRadius=0;this.m_categoryBits=a.categoryBits;this.m_maskBits=a.maskBits;this.m_groupIndex=a.groupIndex;this.syncAABB=new b2AABB;this.syncMat=new b2Mat22;this.m_localCentroid=new b2Vec2;this.m_localOBB=new b2OBB;var d=0;var e;var f;var g;var h=new b2AABB;this.m_vertices=new Array(b2Settings.b2_maxPolyVertices);this.m_coreVertices=new Array(b2Settings.b2_maxPolyVertices);this.m_normals=new Array(b2Settings.b2_maxPolyVertices);this.m_type=b2Shape.e_polyShape;var i=new b2Mat22(a.localRotation);if(a.type==b2Shape.e_boxShape){this.m_localCentroid.x=a.localPosition.x-c.x;this.m_localCentroid.y=a.localPosition.y-c.y;var j=a;this.m_vertexCount=4;e=j.extents.x;f=j.extents.y;var k=Math.max(0,e-2*b2Settings.b2_linearSlop);var l=Math.max(0,f-2*b2Settings.b2_linearSlop);g=this.m_vertices[0]=new b2Vec2;g.x=i.col1.x*e+i.col2.x*f;g.y=i.col1.y*e+i.col2.y*f;g=this.m_vertices[1]=new b2Vec2;g.x=i.col1.x*-e+i.col2.x*f;g.y=i.col1.y*-e+i.col2.y*f;g=this.m_vertices[2]=new b2Vec2;g.x=i.col1.x*-e+i.col2.x*-f;g.y=i.col1.y*-e+i.col2.y*-f;g=this.m_vertices[3]=new b2Vec2;g.x=i.col1.x*e+i.col2.x*-f;g.y=i.col1.y*e+i.col2.y*-f;g=this.m_coreVertices[0]=new b2Vec2;g.x=i.col1.x*k+i.col2.x*l;g.y=i.col1.y*k+i.col2.y*l;g=this.m_coreVertices[1]=new b2Vec2;g.x=i.col1.x*-k+i.col2.x*l;g.y=i.col1.y*-k+i.col2.y*l;g=this.m_coreVertices[2]=new b2Vec2;g.x=i.col1.x*-k+i.col2.x*-l;g.y=i.col1.y*-k+i.col2.y*-l;g=this.m_coreVertices[3]=new b2Vec2;g.x=i.col1.x*k+i.col2.x*-l;g.y=i.col1.y*k+i.col2.y*-l}else{var m=a;this.m_vertexCount=m.vertexCount;b2Shape.PolyCentroid(m.vertices,m.vertexCount,b2PolyShape.tempVec);var n=b2PolyShape.tempVec.x;var o=b2PolyShape.tempVec.y;this.m_localCentroid.x=a.localPosition.x+(i.col1.x*n+i.col2.x*o)-c.x;this.m_localCentroid.y=a.localPosition.y+(i.col1.y*n+i.col2.y*o)-c.y;for(d=0;dNumber.MIN_VALUE){p*=1/r;q*=1/r}this.m_coreVertices[d].x=this.m_vertices[d].x-2*b2Settings.b2_linearSlop*p;this.m_coreVertices[d].y=this.m_vertices[d].y-2*b2Settings.b2_linearSlop*q}}var s=Number.MAX_VALUE;var t=Number.MAX_VALUE;var u=-Number.MAX_VALUE;var v=-Number.MAX_VALUE;this.m_maxRadius=0;for(d=0;dg){f=h;g=i}}c.Set(this.m_position.x+(this.m_R.col1.x*this.m_coreVertices[f].x+this.m_R.col2.x*this.m_coreVertices[f].y),this.m_position.y+(this.m_R.col1.y*this.m_coreVertices[f].x+this.m_R.col2.y*this.m_coreVertices[f].y))},m_localCentroid:new b2Vec2,m_localOBB:new b2OBB,m_vertices:null,m_coreVertices:null,m_vertexCount:0,m_normals:null});b2PolyShape.tempVec=new b2Vec2;b2PolyShape.tAbsR=new b2Mat22;var b2Body=Class.create();b2Body.prototype={SetOriginPosition:function(a,b){if(this.IsFrozen()){return}this.m_rotation=b;this.m_R.Set(this.m_rotation);this.m_position=b2Math.AddVV(a,b2Math.b2MulMV(this.m_R,this.m_center));this.m_position0.SetV(this.m_position);this.m_rotation0=this.m_rotation;for(var c=this.m_shapeList;c!=null;c=c.m_next){c.Synchronize(this.m_position,this.m_R,this.m_position,this.m_R)}this.m_world.m_broadPhase.Commit()},GetOriginPosition:function(){return b2Math.SubtractVV(this.m_position,b2Math.b2MulMV(this.m_R,this.m_center))},SetCenterPosition:function(a,b){if(this.IsFrozen()){return}this.m_rotation=b;this.m_R.Set(this.m_rotation);this.m_position.SetV(a);this.m_position0.SetV(this.m_position);this.m_rotation0=this.m_rotation;for(var c=this.m_shapeList;c!=null;c=c.m_next){c.Synchronize(this.m_position,this.m_R,this.m_position,this.m_R)}this.m_world.m_broadPhase.Commit()},GetCenterPosition:function(){return this.m_position},GetRotation:function(){return this.m_rotation},GetRotationMatrix:function(){return this.m_R},SetLinearVelocity:function(a){this.m_linearVelocity.SetV(a)},GetLinearVelocity:function(){return this.m_linearVelocity},SetAngularVelocity:function(a){this.m_angularVelocity=a},GetAngularVelocity:function(){return this.m_angularVelocity},ApplyForce:function(a,b){if(this.IsSleeping()==false){this.m_force.Add(a);this.m_torque+=b2Math.b2CrossVV(b2Math.SubtractVV(b,this.m_position),a)}},ApplyTorque:function(a){if(this.IsSleeping()==false){this.m_torque+=a}},ApplyImpulse:function(a,b){if(this.IsSleeping()==false){this.m_linearVelocity.Add(b2Math.MulFV(this.m_invMass,a));this.m_angularVelocity+=this.m_invI*b2Math.b2CrossVV(b2Math.SubtractVV(b,this.m_position),a)}},GetMass:function(){return this.m_mass},GetInertia:function(){return this.m_I},GetWorldPoint:function(a){return b2Math.AddVV(this.m_position,b2Math.b2MulMV(this.m_R,a))},GetWorldVector:function(a){return b2Math.b2MulMV(this.m_R,a)},GetLocalPoint:function(a){return b2Math.b2MulTMV(this.m_R,b2Math.SubtractVV(a,this.m_position))},GetLocalVector:function(a){return b2Math.b2MulTMV(this.m_R,a)},IsStatic:function(){return(this.m_flags&b2Body.e_staticFlag)==b2Body.e_staticFlag},IsFrozen:function(){return(this.m_flags&b2Body.e_frozenFlag)==b2Body.e_frozenFlag},IsSleeping:function(){return(this.m_flags&b2Body.e_sleepFlag)==b2Body.e_sleepFlag},AllowSleeping:function(a){if(a){this.m_flags|=b2Body.e_allowSleepFlag}else{this.m_flags&=~b2Body.e_allowSleepFlag;this.WakeUp()}},WakeUp:function(){this.m_flags&=~b2Body.e_sleepFlag;this.m_sleepTime=0},GetShapeList:function(){return this.m_shapeList},GetContactList:function(){return this.m_contactList},GetJointList:function(){return this.m_jointList},GetNext:function(){return this.m_next},GetUserData:function(){return this.m_userData},initialize:function(a,b){this.sMat0=new b2Mat22;this.m_position=new b2Vec2;this.m_R=new b2Mat22(0);this.m_position0=new b2Vec2;var c=0;var d;var e;this.m_flags=0;this.m_position.SetV(a.position);this.m_rotation=a.rotation;this.m_R.Set(this.m_rotation);this.m_position0.SetV(this.m_position);this.m_rotation0=this.m_rotation;this.m_world=b;this.m_linearDamping=b2Math.b2Clamp(1-a.linearDamping,0,1);this.m_angularDamping=b2Math.b2Clamp(1-a.angularDamping,0,1);this.m_force=new b2Vec2(0,0);this.m_torque=0;this.m_mass=0;var f=new Array(b2Settings.b2_maxShapesPerBody);for(c=0;c0){this.m_center.Multiply(1/this.m_mass);this.m_position.Add(b2Math.b2MulMV(this.m_R,this.m_center))}else{this.m_flags|=b2Body.e_staticFlag}this.m_I=0;for(c=0;c0){this.m_invMass=1/this.m_mass}else{this.m_invMass=0}if(this.m_I>0&&a.preventRotation==false){this.m_invI=1/this.m_I}else{this.m_I=0;this.m_invI=0}this.m_linearVelocity=b2Math.AddVV(a.linearVelocity,b2Math.b2CrossFV(a.angularVelocity,this.m_center));this.m_angularVelocity=a.angularVelocity;this.m_jointList=null;this.m_contactList=null;this.m_prev=null;this.m_next=null;this.m_shapeList=null;for(c=0;c0}var c=(a.m_maskBits&b.m_categoryBits)!=0&&(a.m_categoryBits&b.m_maskBits)!=0;return c},initialize:function(){}};b2CollisionFilter.b2_defaultFilter=new b2CollisionFilter;var b2Island=Class.create();b2Island.prototype={initialize:function(a,b,c,d){var e=0;this.m_bodyCapacity=a;this.m_contactCapacity=b;this.m_jointCapacity=c;this.m_bodyCount=0;this.m_contactCount=0;this.m_jointCount=0;this.m_bodies=new Array(a);for(e=0;ef||b2Math.b2Dot(c.m_linearVelocity,c.m_linearVelocity)>e){c.m_sleepTime=0;d=0}else{c.m_sleepTime+=a;d=b2Math.b2Min(d,c.m_sleepTime)}}if(d>=b2Settings.b2_timeToSleep){for(b=0;b0){a.m_shape1.m_body.WakeUp();a.m_shape2.m_body.WakeUp()}var c=a.m_shape1.m_type;var d=a.m_shape2.m_type;var e=b2Contact.s_registers[c][d].destroyFcn;e(a,b)};b2Contact.s_registers=null;b2Contact.s_initialized=false;var b2ContactConstraint=Class.create();b2ContactConstraint.prototype={initialize:function(){this.normal=new b2Vec2;this.points=new Array(b2Settings.b2_maxManifoldPoints);for(var a=0;a0){B.velocityBias=-60*B.separation}var Q=q+ -t*F-o- -s*D;var R=r+t*E-p-s*C;var S=y.normal.x*Q+y.normal.y*R;if(S<-b2Settings.b2_velocityThreshold){B.velocityBias+=-y.restitution*S}}++g}}},PreSolve:function(){var a;var b;var c;for(var d=0;d=-b2Settings.b2_linearSlop},PostSolve:function(){for(var a=0;a0){this.m_manifoldCount=1}else{this.m_manifoldCount=0}},GetManifolds:function(){return this.m_manifold},m_manifold:[new b2Manifold]});b2CircleContact.Create=function(a,b,c){return new b2CircleContact(a,b)};b2CircleContact.Destroy=function(a,b){};var b2Conservative=Class.create();b2Conservative.prototype={initialize:function(){}};b2Conservative.R1=new b2Mat22;b2Conservative.R2=new b2Mat22;b2Conservative.x1=new b2Vec2;b2Conservative.x2=new b2Vec2;b2Conservative.Conservative=function(a,b){var c=a.GetBody();var e=b.GetBody();var f=c.m_position.x-c.m_position0.x;var g=c.m_position.y-c.m_position0.y;var h=c.m_rotation-c.m_rotation0;var i=e.m_position.x-e.m_position0.x;var j=e.m_position.y-e.m_position0.y;var k=e.m_rotation-e.m_rotation0;var l=a.GetMaxRadius();var m=b.GetMaxRadius();var n=c.m_position0.x;var o=c.m_position0.y;var p=c.m_rotation0;var q=e.m_position0.x;var r=e.m_position0.y;var s=e.m_rotation0;var t=n;var u=o;var v=p;var w=q;var x=r;var y=s;b2Conservative.R1.Set(v);b2Conservative.R2.Set(y);a.QuickSync(p1,b2Conservative.R1);b.QuickSync(p2,b2Conservative.R2);var z=0;var A=10;var B;var C;var D=0;var E=true;for(var F=0;FFLT_EPSILON){d*=b2_linearSlop/L}if(c.IsStatic()){c.m_position.x=t;c.m_position.y=u}else{c.m_position.x=t-B;c.m_position.y=u-C}c.m_rotation=v;c.m_R.Set(v);c.QuickSyncShapes();if(e.IsStatic()){e.m_position.x=w;e.m_position.y=x}else{e.m_position.x=w+B;e.m_position.y=x+C}e.m_position.x=w+B;e.m_position.y=x+C;e.m_rotation=y;e.m_R.Set(y);e.QuickSyncShapes();return true}a.QuickSync(c.m_position,c.m_R);b.QuickSync(e.m_position,e.m_R);return false};var b2NullContact=Class.create();Object.extend(b2NullContact.prototype,b2Contact.prototype);Object.extend(b2NullContact.prototype,{initialize:function(a,b){this.m_node1=new b2ContactNode;this.m_node2=new b2ContactNode;this.m_flags=0;if(!a||!b){this.m_shape1=null;this.m_shape2=null;return}this.m_shape1=a;this.m_shape2=b;this.m_manifoldCount=0;this.m_friction=Math.sqrt(this.m_shape1.m_friction*this.m_shape2.m_friction);this.m_restitution=b2Math.b2Max(this.m_shape1.m_restitution,this.m_shape2.m_restitution);this.m_prev=null;this.m_next=null;this.m_node1.contact=null;this.m_node1.prev=null;this.m_node1.next=null;this.m_node1.other=null;this.m_node2.contact=null;this.m_node2.prev=null;this.m_node2.next=null;this.m_node2.other=null},Evaluate:function(){},GetManifolds:function(){return null}});var b2PolyAndCircleContact=Class.create();Object.extend(b2PolyAndCircleContact.prototype,b2Contact.prototype);Object.extend(b2PolyAndCircleContact.prototype,{initialize:function(a,b){this.m_node1=new b2ContactNode;this.m_node2=new b2ContactNode;this.m_flags=0;if(!a||!b){this.m_shape1=null;this.m_shape2=null;return}this.m_shape1=a;this.m_shape2=b;this.m_manifoldCount=0;this.m_friction=Math.sqrt(this.m_shape1.m_friction*this.m_shape2.m_friction);this.m_restitution=b2Math.b2Max(this.m_shape1.m_restitution,this.m_shape2.m_restitution);this.m_prev=null;this.m_next=null;this.m_node1.contact=null;this.m_node1.prev=null;this.m_node1.next=null;this.m_node1.other=null;this.m_node2.contact=null;this.m_node2.prev=null;this.m_node2.next=null;this.m_node2.other=null;this.m_manifold=[new b2Manifold];b2Settings.b2Assert(this.m_shape1.m_type==b2Shape.e_polyShape);b2Settings.b2Assert(this.m_shape2.m_type==b2Shape.e_circleShape);this.m_manifold[0].pointCount=0;this.m_manifold[0].points[0].normalImpulse=0;this.m_manifold[0].points[0].tangentImpulse=0},Evaluate:function(){b2Collision.b2CollidePolyAndCircle(this.m_manifold[0],this.m_shape1,this.m_shape2,false);if(this.m_manifold[0].pointCount>0){this.m_manifoldCount=1}else{this.m_manifoldCount=0}},GetManifolds:function(){return this.m_manifold},m_manifold:[new b2Manifold]});b2PolyAndCircleContact.Create=function(a,b,c){return new b2PolyAndCircleContact(a,b)};b2PolyAndCircleContact.Destroy=function(a,b){};var b2PolyContact=Class.create();Object.extend(b2PolyContact.prototype,b2Contact.prototype);Object.extend(b2PolyContact.prototype,{initialize:function(a,b){this.m_node1=new b2ContactNode;this.m_node2=new b2ContactNode;this.m_flags=0;if(!a||!b){this.m_shape1=null;this.m_shape2=null;return}this.m_shape1=a;this.m_shape2=b;this.m_manifoldCount=0;this.m_friction=Math.sqrt(this.m_shape1.m_friction*this.m_shape2.m_friction);this.m_restitution=b2Math.b2Max(this.m_shape1.m_restitution,this.m_shape2.m_restitution);this.m_prev=null;this.m_next=null;this.m_node1.contact=null;this.m_node1.prev=null;this.m_node1.next=null;this.m_node1.other=null;this.m_node2.contact=null;this.m_node2.prev=null;this.m_node2.next=null;this.m_node2.other=null;this.m0=new b2Manifold;this.m_manifold=[new b2Manifold];this.m_manifold[0].pointCount=0},m0:new b2Manifold,Evaluate:function(){var a=this.m_manifold[0];var b=this.m0.points;for(var c=0;c0){var f=[false,false];for(var g=0;g0){var b=a.m_shape1.m_body;var c=a.m_shape2.m_body;var d=a.m_node1;var e=a.m_node2;b.WakeUp();c.WakeUp();if(d.prev){d.prev.next=d.next}if(d.next){d.next.prev=d.prev}if(d==b.m_contactList){b.m_contactList=d.next}d.prev=null;d.next=null;if(e.prev){e.prev.next=e.next}if(e.next){e.next.prev=e.prev}if(e==c.m_contactList){c.m_contactList=e.next}e.prev=null;e.next=null}b2Contact.Destroy(a,this.m_world.m_blockAllocator);--this.m_world.m_contactCount},CleanContactList:function(){var a=this.m_world.m_contactList;while(a!=null){var b=a;a=a.m_next;if(b.m_flags&b2Contact.e_destroyFlag){this.DestroyContact(b);b=null}}},Collide:function(){var a;var b;var c;var d;for(var e=this.m_world.m_contactList;e!=null;e=e.m_next){if(e.m_shape1.m_body.IsSleeping()&&e.m_shape2.m_body.IsSleeping()){continue}var f=e.GetManifoldCount();e.Evaluate();var g=e.GetManifoldCount();if(f==0&&g>0){a=e.m_shape1.m_body;b=e.m_shape2.m_body;c=e.m_node1;d=e.m_node2;c.contact=e;c.other=b;c.prev=null;c.next=a.m_contactList;if(c.next!=null){c.next.prev=e.m_node1}a.m_contactList=e.m_node1;d.contact=e;d.other=a;d.prev=null;d.next=b.m_contactList;if(d.next!=null){d.next.prev=d}b.m_contactList=d}else if(f>0&&g==0){a=e.m_shape1.m_body;b=e.m_shape2.m_body;c=e.m_node1;d=e.m_node2;if(c.prev){c.prev.next=c.next}if(c.next){c.next.prev=c.prev}if(c==a.m_contactList){a.m_contactList=c.next}c.prev=null;c.next=null;if(d.prev){d.prev.next=d.next}if(d.next){d.next.prev=d.prev}if(d==b.m_contactList){b.m_contactList=d.next}d.prev=null;d.next=null}}},m_world:null,m_nullContact:new b2NullContact,m_destroyImmediate:null});var b2World=Class.create();b2World.prototype={initialize:function(a,b,c){this.step=new b2TimeStep;this.m_contactManager=new b2ContactManager;this.m_listener=null;this.m_filter=b2CollisionFilter.b2_defaultFilter;this.m_bodyList=null;this.m_contactList=null;this.m_jointList=null;this.m_bodyCount=0;this.m_contactCount=0;this.m_jointCount=0;this.m_bodyDestroyList=null;this.m_allowSleep=c;this.m_gravity=b;this.m_contactManager.m_world=this;this.m_broadPhase=new b2BroadPhase(a,this.m_contactManager);var d=new b2BodyDef;this.m_groundBody=this.CreateBody(d)},SetListener:function(a){this.m_listener=a},SetFilter:function(a){this.m_filter=a},CreateBody:function(a){var b=new b2Body(a,this);b.m_prev=null;b.m_next=this.m_bodyList;if(this.m_bodyList){this.m_bodyList.m_prev=b}this.m_bodyList=b;++this.m_bodyCount;return b},DestroyBody:function(a){if(a.m_flags&b2Body.e_destroyFlag){return}if(a.m_prev){a.m_prev.m_next=a.m_next}if(a.m_next){a.m_next.m_prev=a.m_prev}if(a==this.m_bodyList){this.m_bodyList=a.m_next}a.m_flags|=b2Body.e_destroyFlag;--this.m_bodyCount;a.m_prev=null;a.m_next=this.m_bodyDestroyList;this.m_bodyDestroyList=a},CleanBodyList:function(){this.m_contactManager.m_destroyImmediate=true;var a=this.m_bodyDestroyList;while(a){var b=a;a=a.m_next;var c=b.m_jointList;while(c){var d=c;c=c.next;if(this.m_listener){this.m_listener.NotifyJointDestroyed(d.joint)}this.DestroyJoint(d.joint)}b.Destroy()}this.m_bodyDestroyList=null;this.m_contactManager.m_destroyImmediate=false},CreateJoint:function(a){var b=b2Joint.Create(a,this.m_blockAllocator);b.m_prev=null;b.m_next=this.m_jointList;if(this.m_jointList){this.m_jointList.m_prev=b}this.m_jointList=b;++this.m_jointCount;b.m_node1.joint=b;b.m_node1.other=b.m_body2;b.m_node1.prev=null;b.m_node1.next=b.m_body1.m_jointList;if(b.m_body1.m_jointList)b.m_body1.m_jointList.prev=b.m_node1;b.m_body1.m_jointList=b.m_node1;b.m_node2.joint=b;b.m_node2.other=b.m_body1;b.m_node2.prev=null;b.m_node2.next=b.m_body2.m_jointList;if(b.m_body2.m_jointList)b.m_body2.m_jointList.prev=b.m_node2;b.m_body2.m_jointList=b.m_node2;if(a.collideConnected==false){var c=a.body1.m_shapeCount0){this.step.inv_dt=1/a}else{this.step.inv_dt=0}this.m_positionIterationCount=0;this.m_contactManager.CleanContactList();this.CleanBodyList();this.m_contactManager.Collide();var e=new b2Island(this.m_bodyCount,this.m_contactCount,this.m_jointCount,this.m_stackAllocator);for(c=this.m_bodyList;c!=null;c=c.m_next){c.m_flags&=~b2Body.e_islandFlag}for(var f=this.m_contactList;f!=null;f=f.m_next){f.m_flags&=~b2Contact.e_islandFlag}for(var g=this.m_jointList;g!=null;g=g.m_next){g.m_islandFlag=false}var h=this.m_bodyCount;var i=new Array(this.m_bodyCount);for(var j=0;j0){c=i[--l];e.AddBody(c);c.m_flags&=~b2Body.e_sleepFlag;if(c.m_flags&b2Body.e_staticFlag){continue}for(var m=c.m_contactList;m!=null;m=m.next){if(m.contact.m_flags&b2Contact.e_islandFlag){continue}e.AddContact(m.contact);m.contact.m_flags|=b2Contact.e_islandFlag;d=m.other;if(d.m_flags&b2Body.e_islandFlag){continue}i[l++]=d;d.m_flags|=b2Body.e_islandFlag}for(var n=c.m_jointList;n!=null;n=n.next){if(n.joint.m_islandFlag==true){continue}e.AddJoint(n.joint);n.joint.m_islandFlag=true;d=n.other;if(d.m_flags&b2Body.e_islandFlag){continue}i[l++]=d;d.m_flags|=b2Body.e_islandFlag}}e.Solve(this.step,this.m_gravity);this.m_positionIterationCount=b2Math.b2Max(this.m_positionIterationCount,b2Island.m_positionIterationCount);if(this.m_allowSleep){e.UpdateSleep(a)}for(var o=0;ob2Settings.b2_linearSlop){this.m_u.Multiply(1/f)}else{this.m_u.SetZero()}var g=b*this.m_u.y-c*this.m_u.x;var h=d*this.m_u.y-e*this.m_u.x;this.m_mass=this.m_body1.m_invMass+this.m_body1.m_invI*g*g+this.m_body2.m_invMass+this.m_body2.m_invI*h*h;this.m_mass=1/this.m_mass;if(b2World.s_enableWarmStarting){var i=this.m_impulse*this.m_u.x;var j=this.m_impulse*this.m_u.y;this.m_body1.m_linearVelocity.x-=this.m_body1.m_invMass*i;this.m_body1.m_linearVelocity.y-=this.m_body1.m_invMass*j;this.m_body1.m_angularVelocity-=this.m_body1.m_invI*(b*j-c*i);this.m_body2.m_linearVelocity.x+=this.m_body2.m_invMass*i;this.m_body2.m_linearVelocity.y+=this.m_body2.m_invMass*j;this.m_body2.m_angularVelocity+=this.m_body2.m_invI*(d*j-e*i)}else{this.m_impulse=0}},SolveVelocityConstraints:function(a){var b;b=this.m_body1.m_R;var c=b.col1.x*this.m_localAnchor1.x+b.col2.x*this.m_localAnchor1.y;var d=b.col1.y*this.m_localAnchor1.x+b.col2.y*this.m_localAnchor1.y;b=this.m_body2.m_R;var e=b.col1.x*this.m_localAnchor2.x+b.col2.x*this.m_localAnchor2.y;var f=b.col1.y*this.m_localAnchor2.x+b.col2.y*this.m_localAnchor2.y;var g=this.m_body1.m_linearVelocity.x+ -this.m_body1.m_angularVelocity*d;var h=this.m_body1.m_linearVelocity.y+this.m_body1.m_angularVelocity*c;var i=this.m_body2.m_linearVelocity.x+ -this.m_body2.m_angularVelocity*f;var j=this.m_body2.m_linearVelocity.y+this.m_body2.m_angularVelocity*e;var k=this.m_u.x*(i-g)+this.m_u.y*(j-h);var l=-this.m_mass*k;this.m_impulse+=l;var m=l*this.m_u.x;var n=l*this.m_u.y;this.m_body1.m_linearVelocity.x-=this.m_body1.m_invMass*m;this.m_body1.m_linearVelocity.y-=this.m_body1.m_invMass*n;this.m_body1.m_angularVelocity-=this.m_body1.m_invI*(c*n-d*m);this.m_body2.m_linearVelocity.x+=this.m_body2.m_invMass*m;this.m_body2.m_linearVelocity.y+=this.m_body2.m_invMass*n;this.m_body2.m_angularVelocity+=this.m_body2.m_invI*(e*n-f*m)},SolvePositionConstraints:function(){var a;a=this.m_body1.m_R;var b=a.col1.x*this.m_localAnchor1.x+a.col2.x*this.m_localAnchor1.y;var c=a.col1.y*this.m_localAnchor1.x+a.col2.y*this.m_localAnchor1.y;a=this.m_body2.m_R;var d=a.col1.x*this.m_localAnchor2.x+a.col2.x*this.m_localAnchor2.y;var e=a.col1.y*this.m_localAnchor2.x+a.col2.y*this.m_localAnchor2.y;var f=this.m_body2.m_position.x+d-this.m_body1.m_position.x-b;var g=this.m_body2.m_position.y+e-this.m_body1.m_position.y-c;var h=Math.sqrt(f*f+g*g);f/=h;g/=h;var i=h-this.m_length;i=b2Math.b2Clamp(i,-b2Settings.b2_maxLinearCorrection,b2Settings.b2_maxLinearCorrection);var j=-this.m_mass*i;this.m_u.Set(f,g);var k=j*this.m_u.x;var l=j*this.m_u.y;this.m_body1.m_position.x-=this.m_body1.m_invMass*k;this.m_body1.m_position.y-=this.m_body1.m_invMass*l;this.m_body1.m_rotation-=this.m_body1.m_invI*(b*l-c*k);this.m_body2.m_position.x+=this.m_body2.m_invMass*k;this.m_body2.m_position.y+=this.m_body2.m_invMass*l;this.m_body2.m_rotation+=this.m_body2.m_invI*(d*l-e*k);this.m_body1.m_R.Set(this.m_body1.m_rotation);this.m_body2.m_R.Set(this.m_body2.m_rotation);return b2Math.b2Abs(i)a.dt*this.m_maxForce){this.m_impulse.Multiply(a.dt*this.m_maxForce/n)}j=this.m_impulse.x-l;k=this.m_impulse.y-m;b.m_linearVelocity.x+=b.m_invMass*j;b.m_linearVelocity.y+=b.m_invMass*k;b.m_angularVelocity+=b.m_invI*(d*k-e*j)},SolvePositionConstraints:function(){return true},m_localAnchor:new b2Vec2,m_target:new b2Vec2,m_impulse:new b2Vec2,m_ptpMass:new b2Mat22,m_C:new b2Vec2,m_maxForce:null,m_beta:null,m_gamma:null});var b2MouseJointDef=Class.create();Object.extend(b2MouseJointDef.prototype,b2JointDef.prototype);Object.extend(b2MouseJointDef.prototype,{initialize:function(){this.type=b2Joint.e_unknownJoint;this.userData=null;this.body1=null;this.body2=null;this.collideConnected=false;this.target=new b2Vec2;this.type=b2Joint.e_mouseJoint;this.maxForce=0;this.frequencyHz=5;this.dampingRatio=.7;this.timeStep=1/60},target:new b2Vec2,maxForce:null,frequencyHz:null,dampingRatio:null,timeStep:null});var b2PrismaticJoint=Class.create();Object.extend(b2PrismaticJoint.prototype,b2Joint.prototype);Object.extend(b2PrismaticJoint.prototype,{GetAnchor1:function(){var a=this.m_body1;var b=new b2Vec2;b.SetV(this.m_localAnchor1);b.MulM(a.m_R);b.Add(a.m_position);return b},GetAnchor2:function(){var a=this.m_body2;var b=new b2Vec2;b.SetV(this.m_localAnchor2);b.MulM(a.m_R);b.Add(a.m_position);return b},GetJointTranslation:function(){var a=this.m_body1;var b=this.m_body2;var c;c=a.m_R;var d=c.col1.x*this.m_localAnchor1.x+c.col2.x*this.m_localAnchor1.y;var e=c.col1.y*this.m_localAnchor1.x+c.col2.y*this.m_localAnchor1.y;c=b.m_R;var f=c.col1.x*this.m_localAnchor2.x+c.col2.x*this.m_localAnchor2.y;var g=c.col1.y*this.m_localAnchor2.x+c.col2.y*this.m_localAnchor2.y;var h=a.m_position.x+d;var i=a.m_position.y+e;var j=b.m_position.x+f;var k=b.m_position.y+g;var l=j-h;var m=k-i;c=a.m_R;var n=c.col1.x*this.m_localXAxis1.x+c.col2.x*this.m_localXAxis1.y;var o=c.col1.y*this.m_localXAxis1.x+c.col2.y*this.m_localXAxis1.y;var p=n*l+o*m;return p},GetJointSpeed:function(){var a=this.m_body1;var b=this.m_body2;var c;c=a.m_R;var d=c.col1.x*this.m_localAnchor1.x+c.col2.x*this.m_localAnchor1.y;var e=c.col1.y*this.m_localAnchor1.x+c.col2.y*this.m_localAnchor1.y;c=b.m_R;var f=c.col1.x*this.m_localAnchor2.x+c.col2.x*this.m_localAnchor2.y;var g=c.col1.y*this.m_localAnchor2.x+c.col2.y*this.m_localAnchor2.y;var h=a.m_position.x+d;var i=a.m_position.y+e;var j=b.m_position.x+f;var k=b.m_position.y+g;var l=j-h;var m=k-i;c=a.m_R;var n=c.col1.x*this.m_localXAxis1.x+c.col2.x*this.m_localXAxis1.y;var o=c.col1.y*this.m_localXAxis1.x+c.col2.y*this.m_localXAxis1.y;var p=a.m_linearVelocity;var q=b.m_linearVelocity;var r=a.m_angularVelocity;var s=b.m_angularVelocity;var t=l*-r*o+m*r*n+(n*(q.x+ -s*g-p.x- -r*e)+o*(q.y+s*f-p.y-r*d));return t},GetMotorForce:function(a){return a*this.m_motorImpulse},SetMotorSpeed:function(a){this.m_motorSpeed=a},SetMotorForce:function(a){this.m_maxMotorForce=a},GetReactionForce:function(a){var b=a*this.m_limitImpulse;var c;c=this.m_body1.m_R;var d=b*(c.col1.x*this.m_localXAxis1.x+c.col2.x*this.m_localXAxis1.y);var e=b*(c.col1.y*this.m_localXAxis1.x+c.col2.y*this.m_localXAxis1.y);var f=b*(c.col1.x*this.m_localYAxis1.x+c.col2.x*this.m_localYAxis1.y);var g=b*(c.col1.y*this.m_localYAxis1.x+c.col2.y*this.m_localYAxis1.y);return new b2Vec2(d+f,e+g)},GetReactionTorque:function(a){return a*this.m_angularImpulse},initialize:function(a){this.m_node1=new b2JointNode;this.m_node2=new b2JointNode;this.m_type=a.type;this.m_prev=null;this.m_next=null;this.m_body1=a.body1;this.m_body2=a.body2;this.m_collideConnected=a.collideConnected;this.m_islandFlag=false;this.m_userData=a.userData;this.m_localAnchor1=new b2Vec2;this.m_localAnchor2=new b2Vec2;this.m_localXAxis1=new b2Vec2;this.m_localYAxis1=new b2Vec2;this.m_linearJacobian=new b2Jacobian;this.m_motorJacobian=new b2Jacobian;var b;var c;var d;b=this.m_body1.m_R;c=a.anchorPoint.x-this.m_body1.m_position.x;d=a.anchorPoint.y-this.m_body1.m_position.y;this.m_localAnchor1.Set(c*b.col1.x+d*b.col1.y,c*b.col2.x+d*b.col2.y);b=this.m_body2.m_R;c=a.anchorPoint.x-this.m_body2.m_position.x;d=a.anchorPoint.y-this.m_body2.m_position.y;this.m_localAnchor2.Set(c*b.col1.x+d*b.col1.y,c*b.col2.x+d*b.col2.y);b=this.m_body1.m_R;c=a.axis.x;d=a.axis.y;this.m_localXAxis1.Set(c*b.col1.x+d*b.col1.y,c*b.col2.x+d*b.col2.y);this.m_localYAxis1.x=-this.m_localXAxis1.y;this.m_localYAxis1.y=this.m_localXAxis1.x;this.m_initialAngle=this.m_body2.m_rotation-this.m_body1.m_rotation;this.m_linearJacobian.SetZero();this.m_linearMass=0;this.m_linearImpulse=0;this.m_angularMass=0;this.m_angularImpulse=0;this.m_motorJacobian.SetZero();this.m_motorMass=0;this.m_motorImpulse=0;this.m_limitImpulse=0;this.m_limitPositionImpulse=0;this.m_lowerTranslation=a.lowerTranslation;this.m_upperTranslation=a.upperTranslation;this.m_maxMotorForce=a.motorForce;this.m_motorSpeed=a.motorSpeed;this.m_enableLimit=a.enableLimit;this.m_enableMotor=a.enableMotor},PrepareVelocitySolver:function(){var a=this.m_body1;var b=this.m_body2;var c;c=a.m_R;var d=c.col1.x*this.m_localAnchor1.x+c.col2.x*this.m_localAnchor1.y;var e=c.col1.y*this.m_localAnchor1.x+c.col2.y*this.m_localAnchor1.y;c=b.m_R;var f=c.col1.x*this.m_localAnchor2.x+c.col2.x*this.m_localAnchor2.y;var g=c.col1.y*this.m_localAnchor2.x+c.col2.y*this.m_localAnchor2.y;var h=a.m_invMass;var i=b.m_invMass;var j=a.m_invI;var k=b.m_invI;c=a.m_R;var l=c.col1.x*this.m_localYAxis1.x+c.col2.x*this.m_localYAxis1.y;var m=c.col1.y*this.m_localYAxis1.x+c.col2.y*this.m_localYAxis1.y;var n=b.m_position.x+f-a.m_position.x;var o=b.m_position.y+g-a.m_position.y;this.m_linearJacobian.linear1.x=-l;this.m_linearJacobian.linear1.y=-m;this.m_linearJacobian.linear2.x=l;this.m_linearJacobian.linear2.y=m;this.m_linearJacobian.angular1=-(n*m-o*l);this.m_linearJacobian.angular2=f*m-g*l;this.m_linearMass=h+j*this.m_linearJacobian.angular1*this.m_linearJacobian.angular1+i+k*this.m_linearJacobian.angular2*this.m_linearJacobian.angular2;this.m_linearMass=1/this.m_linearMass;this.m_angularMass=1/(j+k);if(this.m_enableLimit||this.m_enableMotor){c=a.m_R;var p=c.col1.x*this.m_localXAxis1.x+c.col2.x*this.m_localXAxis1.y;var q=c.col1.y*this.m_localXAxis1.x+c.col2.y*this.m_localXAxis1.y;this.m_motorJacobian.linear1.x=-p;this.m_motorJacobian.linear1.y=-q;this.m_motorJacobian.linear2.x=p;this.m_motorJacobian.linear2.y=q;this.m_motorJacobian.angular1=-(n*q-o*p);this.m_motorJacobian.angular2=f*q-g*p;this.m_motorMass=h+j*this.m_motorJacobian.angular1*this.m_motorJacobian.angular1+i+k*this.m_motorJacobian.angular2*this.m_motorJacobian.angular2;this.m_motorMass=1/this.m_motorMass;if(this.m_enableLimit){var r=n-d;var s=o-e;var t=p*r+q*s;if(b2Math.b2Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*b2Settings.b2_linearSlop){this.m_limitState=b2Joint.e_equalLimits}else if(t<=this.m_lowerTranslation){if(this.m_limitState!=b2Joint.e_atLowerLimit){this.m_limitImpulse=0}this.m_limitState=b2Joint.e_atLowerLimit}else if(t>=this.m_upperTranslation){if(this.m_limitState!=b2Joint.e_atUpperLimit){this.m_limitImpulse=0}this.m_limitState=b2Joint.e_atUpperLimit}else{this.m_limitState=b2Joint.e_inactiveLimit;this.m_limitImpulse=0}}}if(this.m_enableMotor==false){this.m_motorImpulse=0}if(this.m_enableLimit==false){this.m_limitImpulse=0}if(b2World.s_enableWarmStarting){var u=this.m_linearImpulse*this.m_linearJacobian.linear1.x+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.linear1.x;var v=this.m_linearImpulse*this.m_linearJacobian.linear1.y+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.linear1.y;var w=this.m_linearImpulse*this.m_linearJacobian.linear2.x+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.linear2.x;var x=this.m_linearImpulse*this.m_linearJacobian.linear2.y+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.linear2.y;var y=this.m_linearImpulse*this.m_linearJacobian.angular1-this.m_angularImpulse+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.angular1;var z=this.m_linearImpulse*this.m_linearJacobian.angular2+this.m_angularImpulse+(this.m_motorImpulse+this.m_limitImpulse)*this.m_motorJacobian.angular2;a.m_linearVelocity.x+=h*u;a.m_linearVelocity.y+=h*v;a.m_angularVelocity+=j*y;b.m_linearVelocity.x+=i*w;b.m_linearVelocity.y+=i*x;b.m_angularVelocity+=k*z}else{this.m_linearImpulse=0;this.m_angularImpulse=0;this.m_limitImpulse=0;this.m_motorImpulse=0}this.m_limitPositionImpulse=0},SolveVelocityConstraints:function(a){var b=this.m_body1;var c=this.m_body2;var d=b.m_invMass;var e=c.m_invMass;var f=b.m_invI;var g=c.m_invI;var h;var i=this.m_linearJacobian.Compute(b.m_linearVelocity,b.m_angularVelocity,c.m_linearVelocity,c.m_angularVelocity);var j=-this.m_linearMass*i;this.m_linearImpulse+=j;b.m_linearVelocity.x+=d*j*this.m_linearJacobian.linear1.x;b.m_linearVelocity.y+=d*j*this.m_linearJacobian.linear1.y;b.m_angularVelocity+=f*j*this.m_linearJacobian.angular1;c.m_linearVelocity.x+=e*j*this.m_linearJacobian.linear2.x;c.m_linearVelocity.y+=e*j*this.m_linearJacobian.linear2.y;c.m_angularVelocity+=g*j*this.m_linearJacobian.angular2;var k=c.m_angularVelocity-b.m_angularVelocity;var l=-this.m_angularMass*k;this.m_angularImpulse+=l;b.m_angularVelocity-=f*l;c.m_angularVelocity+=g*l;if(this.m_enableMotor&&this.m_limitState!=b2Joint.e_equalLimits){var m=this.m_motorJacobian.Compute(b.m_linearVelocity,b.m_angularVelocity,c.m_linearVelocity,c.m_angularVelocity)-this.m_motorSpeed;var n=-this.m_motorMass*m;var o=this.m_motorImpulse;this.m_motorImpulse=b2Math.b2Clamp(this.m_motorImpulse+n,-a.dt*this.m_maxMotorForce,a.dt*this.m_maxMotorForce);n=this.m_motorImpulse-o;b.m_linearVelocity.x+=d*n*this.m_motorJacobian.linear1.x;b.m_linearVelocity.y+=d*n*this.m_motorJacobian.linear1.y;b.m_angularVelocity+=f*n*this.m_motorJacobian.angular1;c.m_linearVelocity.x+=e*n*this.m_motorJacobian.linear2.x;c.m_linearVelocity.y+=e*n*this.m_motorJacobian.linear2.y;c.m_angularVelocity+=g*n*this.m_motorJacobian.angular2}if(this.m_enableLimit&&this.m_limitState!=b2Joint.e_inactiveLimit){var p=this.m_motorJacobian.Compute(b.m_linearVelocity,b.m_angularVelocity,c.m_linearVelocity,c.m_angularVelocity);var q=-this.m_motorMass*p;if(this.m_limitState==b2Joint.e_equalLimits){this.m_limitImpulse+=q}else if(this.m_limitState==b2Joint.e_atLowerLimit){h=this.m_limitImpulse;this.m_limitImpulse=b2Math.b2Max(this.m_limitImpulse+q,0);q=this.m_limitImpulse-h}else if(this.m_limitState==b2Joint.e_atUpperLimit){h=this.m_limitImpulse;this.m_limitImpulse=b2Math.b2Min(this.m_limitImpulse+q,0);q=this.m_limitImpulse-h}b.m_linearVelocity.x+=d*q*this.m_motorJacobian.linear1.x;b.m_linearVelocity.y+=d*q*this.m_motorJacobian.linear1.y;b.m_angularVelocity+=f*q*this.m_motorJacobian.angular1;c.m_linearVelocity.x+=e*q*this.m_motorJacobian.linear2.x;c.m_linearVelocity.y+=e*q*this.m_motorJacobian.linear2.y;c.m_angularVelocity+=g*q*this.m_motorJacobian.angular2}},SolvePositionConstraints:function(){var a;var b;var c=this.m_body1;var d=this.m_body2;var e=c.m_invMass;var f=d.m_invMass;var g=c.m_invI;var h=d.m_invI;var i;i=c.m_R;var j=i.col1.x*this.m_localAnchor1.x+i.col2.x*this.m_localAnchor1.y;var k=i.col1.y*this.m_localAnchor1.x+i.col2.y*this.m_localAnchor1.y;i=d.m_R;var l=i.col1.x*this.m_localAnchor2.x+i.col2.x*this.m_localAnchor2.y;var m=i.col1.y*this.m_localAnchor2.x+i.col2.y*this.m_localAnchor2.y;var n=c.m_position.x+j;var o=c.m_position.y+k;var p=d.m_position.x+l;var q=d.m_position.y+m;var r=p-n;var s=q-o;i=c.m_R;var t=i.col1.x*this.m_localYAxis1.x+i.col2.x*this.m_localYAxis1.y;var u=i.col1.y*this.m_localYAxis1.x+i.col2.y*this.m_localYAxis1.y;var v=t*r+u*s;v=b2Math.b2Clamp(v,-b2Settings.b2_maxLinearCorrection,b2Settings.b2_maxLinearCorrection);var w=-this.m_linearMass*v;c.m_position.x+=e*w*this.m_linearJacobian.linear1.x;c.m_position.y+=e*w*this.m_linearJacobian.linear1.y;c.m_rotation+=g*w*this.m_linearJacobian.angular1;d.m_position.x+=f*w*this.m_linearJacobian.linear2.x;d.m_position.y+=f*w*this.m_linearJacobian.linear2.y;d.m_rotation+=h*w*this.m_linearJacobian.angular2;var x=b2Math.b2Abs(v);var y=d.m_rotation-c.m_rotation-this.m_initialAngle;y=b2Math.b2Clamp(y,-b2Settings.b2_maxAngularCorrection,b2Settings.b2_maxAngularCorrection);var z=-this.m_angularMass*y;c.m_rotation-=c.m_invI*z;c.m_R.Set(c.m_rotation);d.m_rotation+=d.m_invI*z;d.m_R.Set(d.m_rotation);var A=b2Math.b2Abs(y);if(this.m_enableLimit&&this.m_limitState!=b2Joint.e_inactiveLimit){i=c.m_R;j=i.col1.x*this.m_localAnchor1.x+i.col2.x*this.m_localAnchor1.y;k=i.col1.y*this.m_localAnchor1.x+i.col2.y*this.m_localAnchor1.y;i=d.m_R;l=i.col1.x*this.m_localAnchor2.x+i.col2.x*this.m_localAnchor2.y;m=i.col1.y*this.m_localAnchor2.x+i.col2.y*this.m_localAnchor2.y;n=c.m_position.x+j;o=c.m_position.y+k;p=d.m_position.x+l;q=d.m_position.y+m;r=p-n;s=q-o;i=c.m_R;var B=i.col1.x*this.m_localXAxis1.x+i.col2.x*this.m_localXAxis1.y;var C=i.col1.y*this.m_localXAxis1.x+i.col2.y*this.m_localXAxis1.y;var D=B*r+C*s;var E=0;if(this.m_limitState==b2Joint.e_equalLimits){a=b2Math.b2Clamp(D,-b2Settings.b2_maxLinearCorrection,b2Settings.b2_maxLinearCorrection);E=-this.m_motorMass*a;x=b2Math.b2Max(x,b2Math.b2Abs(y))}else if(this.m_limitState==b2Joint.e_atLowerLimit){a=D-this.m_lowerTranslation;x=b2Math.b2Max(x,-a);a=b2Math.b2Clamp(a+b2Settings.b2_linearSlop,-b2Settings.b2_maxLinearCorrection,0);E=-this.m_motorMass*a;b=this.m_limitPositionImpulse;this.m_limitPositionImpulse=b2Math.b2Max(this.m_limitPositionImpulse+E,0);E=this.m_limitPositionImpulse-b}else if(this.m_limitState==b2Joint.e_atUpperLimit){a=D-this.m_upperTranslation;x=b2Math.b2Max(x,a);a=b2Math.b2Clamp(a-b2Settings.b2_linearSlop,0,b2Settings.b2_maxLinearCorrection);E=-this.m_motorMass*a;b=this.m_limitPositionImpulse;this.m_limitPositionImpulse=b2Math.b2Min(this.m_limitPositionImpulse+E,0);E=this.m_limitPositionImpulse-b}c.m_position.x+=e*E*this.m_motorJacobian.linear1.x;c.m_position.y+=e*E*this.m_motorJacobian.linear1.y;c.m_rotation+=g*E*this.m_motorJacobian.angular1;c.m_R.Set(c.m_rotation);d.m_position.x+=f*E*this.m_motorJacobian.linear2.x;d.m_position.y+=f*E*this.m_motorJacobian.linear2.y;d.m_rotation+=h*E*this.m_motorJacobian.angular2;d.m_R.Set(d.m_rotation)}return x<=b2Settings.b2_linearSlop&&A<=b2Settings.b2_angularSlop},m_localAnchor1:new b2Vec2,m_localAnchor2:new b2Vec2,m_localXAxis1:new b2Vec2,m_localYAxis1:new b2Vec2,m_initialAngle:null,m_linearJacobian:new b2Jacobian,m_linearMass:null,m_linearImpulse:null,m_angularMass:null,m_angularImpulse:null,m_motorJacobian:new b2Jacobian,m_motorMass:null,m_motorImpulse:null,m_limitImpulse:null,m_limitPositionImpulse:null,m_lowerTranslation:null,m_upperTranslation:null,m_maxMotorForce:null,m_motorSpeed:null,m_enableLimit:null,m_enableMotor:null,m_limitState:0});var b2PrismaticJointDef=Class.create();Object.extend(b2PrismaticJointDef.prototype,b2JointDef.prototype);Object.extend(b2PrismaticJointDef.prototype,{initialize:function(){this.type=b2Joint.e_unknownJoint;this.userData=null;this.body1=null;this.body2=null;this.collideConnected=false;this.type=b2Joint.e_prismaticJoint;this.anchorPoint=new b2Vec2(0,0);this.axis=new b2Vec2(0,0);this.lowerTranslation=0;this.upperTranslation=0;this.motorForce=0;this.motorSpeed=0;this.enableLimit=false;this.enableMotor=false},anchorPoint:null,axis:null,lowerTranslation:null,upperTranslation:null,motorForce:null,motorSpeed:null,enableLimit:null,enableMotor:null});var b2PulleyJoint=Class.create();Object.extend(b2PulleyJoint.prototype,b2Joint.prototype);Object.extend(b2PulleyJoint.prototype,{GetAnchor1:function(){var a=this.m_body1.m_R;return new b2Vec2(this.m_body1.m_position.x+(a.col1.x*this.m_localAnchor1.x+a.col2.x*this.m_localAnchor1.y),this.m_body1.m_position.y+(a.col1.y*this.m_localAnchor1.x+a.col2.y*this.m_localAnchor1.y))},GetAnchor2:function(){var a=this.m_body2.m_R;return new b2Vec2(this.m_body2.m_position.x+(a.col1.x*this.m_localAnchor2.x+a.col2.x*this.m_localAnchor2.y),this.m_body2.m_position.y+(a.col1.y*this.m_localAnchor2.x+a.col2.y*this.m_localAnchor2.y))},GetGroundPoint1:function(){return new b2Vec2(this.m_ground.m_position.x+this.m_groundAnchor1.x,this.m_ground.m_position.y+this.m_groundAnchor1.y)},GetGroundPoint2:function(){return new b2Vec2(this.m_ground.m_position.x+this.m_groundAnchor2.x,this.m_ground.m_position.y+this.m_groundAnchor2.y)},GetReactionForce:function(a){return new b2Vec2},GetReactionTorque:function(a){return 0},GetLength1:function(){var a;a=this.m_body1.m_R;var b=this.m_body1.m_position.x+(a.col1.x*this.m_localAnchor1.x+a.col2.x*this.m_localAnchor1.y);var c=this.m_body1.m_position.y+(a.col1.y*this.m_localAnchor1.x+a.col2.y*this.m_localAnchor1.y);var d=b-(this.m_ground.m_position.x+this.m_groundAnchor1.x);var e=c-(this.m_ground.m_position.y+this.m_groundAnchor1.y);return Math.sqrt(d*d+e*e)},GetLength2:function(){var a;a=this.m_body2.m_R;var b=this.m_body2.m_position.x+(a.col1.x*this.m_localAnchor2.x+a.col2.x*this.m_localAnchor2.y);var c=this.m_body2.m_position.y+(a.col1.y*this.m_localAnchor2.x+a.col2.y*this.m_localAnchor2.y);var d=b-(this.m_ground.m_position.x+this.m_groundAnchor2.x);var e=c-(this.m_ground.m_position.y+this.m_groundAnchor2.y);return Math.sqrt(d*d+e*e)},GetRatio:function(){return this.m_ratio},initialize:function(a){this.m_node1=new b2JointNode;this.m_node2=new b2JointNode;this.m_type=a.type;this.m_prev=null;this.m_next=null;this.m_body1=a.body1;this.m_body2=a.body2;this.m_collideConnected=a.collideConnected;this.m_islandFlag=false;this.m_userData=a.userData;this.m_groundAnchor1=new b2Vec2;this.m_groundAnchor2=new b2Vec2;this.m_localAnchor1=new b2Vec2;this.m_localAnchor2=new b2Vec2;this.m_u1=new b2Vec2;this.m_u2=new b2Vec2;var b;var c;var d;this.m_ground=this.m_body1.m_world.m_groundBody;this.m_groundAnchor1.x=a.groundPoint1.x-this.m_ground.m_position.x;this.m_groundAnchor1.y=a.groundPoint1.y-this.m_ground.m_position.y;this.m_groundAnchor2.x=a.groundPoint2.x-this.m_ground.m_position.x;this.m_groundAnchor2.y=a.groundPoint2.y-this.m_ground.m_position.y;b=this.m_body1.m_R;c=a.anchorPoint1.x-this.m_body1.m_position.x;d=a.anchorPoint1.y-this.m_body1.m_position.y;this.m_localAnchor1.x=c*b.col1.x+d*b.col1.y;this.m_localAnchor1.y=c*b.col2.x+d*b.col2.y;b=this.m_body2.m_R;c=a.anchorPoint2.x-this.m_body2.m_position.x;d=a.anchorPoint2.y-this.m_body2.m_position.y;this.m_localAnchor2.x=c*b.col1.x+d*b.col1.y;this.m_localAnchor2.y=c*b.col2.x+d*b.col2.y;this.m_ratio=a.ratio;c=a.groundPoint1.x-a.anchorPoint1.x;d=a.groundPoint1.y-a.anchorPoint1.y;var e=Math.sqrt(c*c+d*d);c=a.groundPoint2.x-a.anchorPoint2.x;d=a.groundPoint2.y-a.anchorPoint2.y;var f=Math.sqrt(c*c+d*d);var g=b2Math.b2Max(.5*b2PulleyJoint.b2_minPulleyLength,e);var h=b2Math.b2Max(.5*b2PulleyJoint.b2_minPulleyLength,f);this.m_constant=g+this.m_ratio*h;this.m_maxLength1=b2Math.b2Clamp(a.maxLength1,g,this.m_constant-this.m_ratio*b2PulleyJoint.b2_minPulleyLength);this.m_maxLength2=b2Math.b2Clamp(a.maxLength2,h,(this.m_constant-b2PulleyJoint.b2_minPulleyLength)/this.m_ratio);this.m_pulleyImpulse=0;this.m_limitImpulse1=0;this.m_limitImpulse2=0},PrepareVelocitySolver:function(){var a=this.m_body1;var b=this.m_body2;var c;c=a.m_R;var d=c.col1.x*this.m_localAnchor1.x+c.col2.x*this.m_localAnchor1.y;var e=c.col1.y*this.m_localAnchor1.x+c.col2.y*this.m_localAnchor1.y;c=b.m_R;var f=c.col1.x*this.m_localAnchor2.x+c.col2.x*this.m_localAnchor2.y;var g=c.col1.y*this.m_localAnchor2.x+c.col2.y*this.m_localAnchor2.y;var h=a.m_position.x+d;var i=a.m_position.y+e;var j=b.m_position.x+f;var k=b.m_position.y+g;var l=this.m_ground.m_position.x+this.m_groundAnchor1.x;var m=this.m_ground.m_position.y+this.m_groundAnchor1.y;var n=this.m_ground.m_position.x+this.m_groundAnchor2.x;var o=this.m_ground.m_position.y+this.m_groundAnchor2.y;this.m_u1.Set(h-l,i-m);this.m_u2.Set(j-n,k-o);var p=this.m_u1.Length();var q=this.m_u2.Length();if(p>b2Settings.b2_linearSlop){this.m_u1.Multiply(1/p)}else{this.m_u1.SetZero()}if(q>b2Settings.b2_linearSlop){this.m_u2.Multiply(1/q)}else{this.m_u2.SetZero()}if(pb2Settings.b2_linearSlop){this.m_u1.Multiply(1/p)}else{this.m_u1.SetZero()}if(q>b2Settings.b2_linearSlop){this.m_u2.Multiply(1/q)}else{this.m_u2.SetZero()}r=this.m_constant-p-this.m_ratio*q;u=b2Math.b2Max(u,Math.abs(r));r=b2Math.b2Clamp(r,-b2Settings.b2_maxLinearCorrection,b2Settings.b2_maxLinearCorrection);s=-this.m_pulleyMass*r;l=-s*this.m_u1.x;m=-s*this.m_u1.y;n=-this.m_ratio*s*this.m_u2.x;o=-this.m_ratio*s*this.m_u2.y;a.m_position.x+=a.m_invMass*l;a.m_position.y+=a.m_invMass*m;a.m_rotation+=a.m_invI*(h*m-i*l);b.m_position.x+=b.m_invMass*n;b.m_position.y+=b.m_invMass*o;b.m_rotation+=b.m_invI*(j*o-k*n);a.m_R.Set(a.m_rotation);b.m_R.Set(b.m_rotation)}if(this.m_limitState1==b2Joint.e_atUpperLimit){c=a.m_R;h=c.col1.x*this.m_localAnchor1.x+c.col2.x*this.m_localAnchor1.y;i=c.col1.y*this.m_localAnchor1.x+c.col2.y*this.m_localAnchor1.y;l=a.m_position.x+h;m=a.m_position.y+i;this.m_u1.Set(l-d,m-e);p=this.m_u1.Length();if(p>b2Settings.b2_linearSlop){this.m_u1.x*=1/p;this.m_u1.y*=1/p}else{this.m_u1.SetZero()}r=this.m_maxLength1-p;u=b2Math.b2Max(u,-r);r=b2Math.b2Clamp(r+b2Settings.b2_linearSlop,-b2Settings.b2_maxLinearCorrection,0);s=-this.m_limitMass1*r;t=this.m_limitPositionImpulse1;this.m_limitPositionImpulse1=b2Math.b2Max(0,this.m_limitPositionImpulse1+s);s=this.m_limitPositionImpulse1-t;l=-s*this.m_u1.x;m=-s*this.m_u1.y;a.m_position.x+=a.m_invMass*l;a.m_position.y+=a.m_invMass*m;a.m_rotation+=a.m_invI*(h*m-i*l);a.m_R.Set(a.m_rotation)}if(this.m_limitState2==b2Joint.e_atUpperLimit){c=b.m_R;j=c.col1.x*this.m_localAnchor2.x+c.col2.x*this.m_localAnchor2.y;k=c.col1.y*this.m_localAnchor2.x+c.col2.y*this.m_localAnchor2.y;n=b.m_position.x+j;o=b.m_position.y+k;this.m_u2.Set(n-f,o-g);q=this.m_u2.Length();if(q>b2Settings.b2_linearSlop){this.m_u2.x*=1/q;this.m_u2.y*=1/q}else{this.m_u2.SetZero()}r=this.m_maxLength2-q;u=b2Math.b2Max(u,-r);r=b2Math.b2Clamp(r+b2Settings.b2_linearSlop,-b2Settings.b2_maxLinearCorrection,0);s=-this.m_limitMass2*r;t=this.m_limitPositionImpulse2;this.m_limitPositionImpulse2=b2Math.b2Max(0,this.m_limitPositionImpulse2+s);s=this.m_limitPositionImpulse2-t;n=-s*this.m_u2.x;o=-s*this.m_u2.y;b.m_position.x+=b.m_invMass*n;b.m_position.y+=b.m_invMass*o;b.m_rotation+=b.m_invI*(j*o-k*n);b.m_R.Set(b.m_rotation)}return u=this.m_upperAngle){if(this.m_limitState!=b2Joint.e_atUpperLimit){this.m_limitImpulse=0}this.m_limitState=b2Joint.e_atUpperLimit}else{this.m_limitState=b2Joint.e_inactiveLimit;this.m_limitImpulse=0}}else{this.m_limitImpulse=0}if(b2World.s_enableWarmStarting){a.m_linearVelocity.x-=h*this.m_ptpImpulse.x;a.m_linearVelocity.y-=h*this.m_ptpImpulse.y;a.m_angularVelocity-=j*(d*this.m_ptpImpulse.y-e*this.m_ptpImpulse.x+this.m_motorImpulse+this.m_limitImpulse);b.m_linearVelocity.x+=i*this.m_ptpImpulse.x;b.m_linearVelocity.y+=i*this.m_ptpImpulse.y;b.m_angularVelocity+=k*(f*this.m_ptpImpulse.y-g*this.m_ptpImpulse.x+this.m_motorImpulse+this.m_limitImpulse)}else{this.m_ptpImpulse.SetZero();this.m_motorImpulse=0;this.m_limitImpulse=0}this.m_limitPositionImpulse=0},SolveVelocityConstraints:function(a){var b=this.m_body1;var c=this.m_body2;var d;d=b.m_R;var e=d.col1.x*this.m_localAnchor1.x+d.col2.x*this.m_localAnchor1.y;var f=d.col1.y*this.m_localAnchor1.x+d.col2.y*this.m_localAnchor1.y;d=c.m_R;var g=d.col1.x*this.m_localAnchor2.x+d.col2.x*this.m_localAnchor2.y;var h=d.col1.y*this.m_localAnchor2.x+d.col2.y*this.m_localAnchor2.y;var i;var j=c.m_linearVelocity.x+ -c.m_angularVelocity*h-b.m_linearVelocity.x- -b.m_angularVelocity*f;var k=c.m_linearVelocity.y+c.m_angularVelocity*g-b.m_linearVelocity.y-b.m_angularVelocity*e;var l=-(this.m_ptpMass.col1.x*j+this.m_ptpMass.col2.x*k);var m=-(this.m_ptpMass.col1.y*j+this.m_ptpMass.col2.y*k);this.m_ptpImpulse.x+=l;this.m_ptpImpulse.y+=m;b.m_linearVelocity.x-=b.m_invMass*l;b.m_linearVelocity.y-=b.m_invMass*m;b.m_angularVelocity-=b.m_invI*(e*m-f*l);c.m_linearVelocity.x+=c.m_invMass*l;c.m_linearVelocity.y+=c.m_invMass*m;c.m_angularVelocity+=c.m_invI*(g*m-h*l);if(this.m_enableMotor&&this.m_limitState!=b2Joint.e_equalLimits){var n=c.m_angularVelocity-b.m_angularVelocity-this.m_motorSpeed;var o=-this.m_motorMass*n;var p=this.m_motorImpulse;this.m_motorImpulse=b2Math.b2Clamp(this.m_motorImpulse+o,-a.dt*this.m_maxMotorTorque,a.dt*this.m_maxMotorTorque);o=this.m_motorImpulse-p;b.m_angularVelocity-=b.m_invI*o;c.m_angularVelocity+=c.m_invI*o}if(this.m_enableLimit&&this.m_limitState!=b2Joint.e_inactiveLimit){var q=c.m_angularVelocity-b.m_angularVelocity;var r=-this.m_motorMass*q;if(this.m_limitState==b2Joint.e_equalLimits){this.m_limitImpulse+=r}else if(this.m_limitState==b2Joint.e_atLowerLimit){i=this.m_limitImpulse;this.m_limitImpulse=b2Math.b2Max(this.m_limitImpulse+r,0);r=this.m_limitImpulse-i}else if(this.m_limitState==b2Joint.e_atUpperLimit){i=this.m_limitImpulse;this.m_limitImpulse=b2Math.b2Min(this.m_limitImpulse+r,0);r=this.m_limitImpulse-i}b.m_angularVelocity-=b.m_invI*r;c.m_angularVelocity+=c.m_invI*r}},SolvePositionConstraints:function(){var a;var b;var c=this.m_body1;var d=this.m_body2;var e=0;var f;f=c.m_R;var g=f.col1.x*this.m_localAnchor1.x+f.col2.x*this.m_localAnchor1.y;var h=f.col1.y*this.m_localAnchor1.x+f.col2.y*this.m_localAnchor1.y;f=d.m_R;var i=f.col1.x*this.m_localAnchor2.x+f.col2.x*this.m_localAnchor2.y;var j=f.col1.y*this.m_localAnchor2.x+f.col2.y*this.m_localAnchor2.y;var k=c.m_position.x+g;var l=c.m_position.y+h;var m=d.m_position.x+i;var n=d.m_position.y+j;var o=m-k;var p=n-l;e=Math.sqrt(o*o+p*p);var q=c.m_invMass;var r=d.m_invMass;var s=c.m_invI;var t=d.m_invI;this.K1.col1.x=q+r;this.K1.col2.x=0;this.K1.col1.y=0;this.K1.col2.y=q+r;this.K2.col1.x=s*h*h;this.K2.col2.x=-s*g*h;this.K2.col1.y=-s*g*h;this.K2.col2.y=s*g*g;this.K3.col1.x=t*j*j;this.K3.col2.x=-t*i*j;this.K3.col1.y=-t*i*j;this.K3.col2.y=t*i*i;this.K.SetM(this.K1);this.K.AddM(this.K2);this.K.AddM(this.K3);this.K.Solve(b2RevoluteJoint.tImpulse,-o,-p);var u=b2RevoluteJoint.tImpulse.x;var v=b2RevoluteJoint.tImpulse.y;c.m_position.x-=c.m_invMass*u;c.m_position.y-=c.m_invMass*v;c.m_rotation-=c.m_invI*(g*v-h*u);c.m_R.Set(c.m_rotation);d.m_position.x+=d.m_invMass*u;d.m_position.y+=d.m_invMass*v;d.m_rotation+=d.m_invI*(i*v-j*u);d.m_R.Set(d.m_rotation);var w=0;if(this.m_enableLimit&&this.m_limitState!=b2Joint.e_inactiveLimit){var x=d.m_rotation-c.m_rotation-this.m_intialAngle;var y=0;if(this.m_limitState==b2Joint.e_equalLimits){b=b2Math.b2Clamp(x,-b2Settings.b2_maxAngularCorrection,b2Settings.b2_maxAngularCorrection);y=-this.m_motorMass*b;w=b2Math.b2Abs(b)}else if(this.m_limitState==b2Joint.e_atLowerLimit){b=x-this.m_lowerAngle;w=b2Math.b2Max(0,-b);b=b2Math.b2Clamp(b+b2Settings.b2_angularSlop,-b2Settings.b2_maxAngularCorrection,0);y=-this.m_motorMass*b;a=this.m_limitPositionImpulse;this.m_limitPositionImpulse=b2Math.b2Max(this.m_limitPositionImpulse+y,0);y=this.m_limitPositionImpulse-a}else if(this.m_limitState==b2Joint.e_atUpperLimit){b=x-this.m_upperAngle;w=b2Math.b2Max(0,b);b=b2Math.b2Clamp(b-b2Settings.b2_angularSlop,0,b2Settings.b2_maxAngularCorrection);y=-this.m_motorMass*b;a=this.m_limitPositionImpulse;this.m_limitPositionImpulse=b2Math.b2Min(this.m_limitPositionImpulse+y,0);y=this.m_limitPositionImpulse-a}c.m_rotation-=c.m_invI*y;c.m_R.Set(c.m_rotation);d.m_rotation+=d.m_invI*y;d.m_R.Set(d.m_rotation)}return e<=b2Settings.b2_linearSlop&&w<=b2Settings.b2_angularSlop},m_localAnchor1:new b2Vec2,m_localAnchor2:new b2Vec2,m_ptpImpulse:new b2Vec2,m_motorImpulse:null,m_limitImpulse:null,m_limitPositionImpulse:null,m_ptpMass:new b2Mat22,m_motorMass:null,m_intialAngle:null,m_lowerAngle:null,m_upperAngle:null,m_maxMotorTorque:null,m_motorSpeed:null,m_enableLimit:null,m_enableMotor:null,m_limitState:0});b2RevoluteJoint.tImpulse=new b2Vec2;var b2RevoluteJointDef=Class.create();Object.extend(b2RevoluteJointDef.prototype,b2JointDef.prototype);Object.extend(b2RevoluteJointDef.prototype,{initialize:function(){this.type=b2Joint.e_unknownJoint;this.userData=null;this.body1=null;this.body2=null;this.collideConnected=false;this.type=b2Joint.e_revoluteJoint;this.anchorPoint=new b2Vec2(0,0);this.lowerAngle=0;this.upperAngle=0;this.motorTorque=0;this.motorSpeed=0;this.enableLimit=false;this.enableMotor=false},anchorPoint:null,lowerAngle:null,upperAngle:null,motorTorque:null,motorSpeed:null,enableLimit:null,enableMotor:null}) diff --git a/apps/web/public/static/vendor/inheritance.min.js b/apps/web/public/static/vendor/inheritance.min.js new file mode 100644 index 00000000..96ede808 --- /dev/null +++ b/apps/web/public/static/vendor/inheritance.min.js @@ -0,0 +1,4 @@ +/* eslint-disable */ +// Alex Arnell's inheritance.js :: http://code.google.com/p/inheritance/ + +function $A(a){if(!a)return[];if(a.toArray)return a.toArray();var b=a.length||0,c=new Array(b);while(b--)c[b]=a[b];return c}var Class={create:function(){function c(){this.initialize.apply(this,arguments)}var a=null,b=$A(arguments);if(Object.isFunction(b[0]))a=b.shift();Object.extend(c,Class.Methods);c.superclass=a;c.subclasses=[];if(a){var d=function(){};d.prototype=a.prototype;c.prototype=new d;a.subclasses.push(c)}for(var e=0;e-1){$A=function(a){if(!a)return[];if(!(Object.isFunction(a)&&a=="[object NodeList]")&&a.toArray)return a.toArray();var b=a.length||0,c=new Array(b);while(b--)c[b]=a[b];return c}} diff --git a/apps/web/utils/danmaku/gravity/jgravity-fork.ts b/apps/web/utils/danmaku/gravity/jgravity-fork.ts new file mode 100644 index 00000000..a0e8a926 --- /dev/null +++ b/apps/web/utils/danmaku/gravity/jgravity-fork.ts @@ -0,0 +1,514 @@ +// This file is a fork of jGravity library by @nzws. +// Original Source: /~https://github.com/tinybigideas/jGravity + +/* eslint-disable */ +// @ts-nocheck + +/* + * @project: jGravity + * @version: 0.8 - 29/04/2012 + * @author: Craig Thomas - www.tinybigideas.com + * @project: http://tinybigideas.com/plugins/jquery-gravity/ + * @license: jGravity is licensed under a Open Source Initiative OSI MIT License: http://opensource.org/licenses/mit-license.php + * @changlog: http://tinybigideas.com/plugins/jquery-gravity/ + + */ + +/*------------------------------------*\ + CREDITS +\*------------------------------------*/ +/* + - Mr. Doobs :: http://mrdoob.com/92/Google_Gravity + - GravityScript :: http://gravityscript.googlecode.com/ + - Alex Arnell's inheritance.js :: http://code.google.com/p/inheritance/ + - Box2Djs :: http://box2d-js.sourceforge.net/ +*/ + +/*------------------------------------*\ + CONTENTS +\*------------------------------------*/ +/* + +LIBRARIES + - Alex Arnell's inheritance.js + - Box2Djs (port of Box2DFlash 1.4.3.1) :: http://box2d-js.sourceforge.net/ + +WORKERS + - variables + - get browser dimensions + - initialise + +FUNCTIONS + - init() + - run() + - onDocumentMouseDown() + - onDocumentMouseUp() + - onDocumentMouseMove() + - onElementMouseDown() + - onnElementMouseUp() + - loop() + - createBox() + - mouseDrag() + - getBodyAtMouse() + - setWalls() + - getBrowserDimensions() + +*/ + +export interface GravityConfig { + target: string; + ignoreClass: string; + weight: number | 'light' | 'heavy'; + depth: number; + drag: boolean; +} + +interface GravityConfigInternal extends GravityConfig { + target: string; + ignoreClass: string; + weight: number; + depth: number; + drag: boolean; +} + +export class Gravity { + config: GravityConfigInternal; + worldAABB: any; + mouseJoint: any; + canvas: any; + world: any; + delta: number[] = [0, 0]; + stage: number[] = []; + isMouseDown = false; + iterations = 1; + timeStep = 1 / 25; + walls: any[] = []; + wall_thickness = 200; + wallsSetted = false; + mouseX = 0; + mouseY = 0; + mouseOnClick: number[] = []; + timer = 0; + bodies: any = {}; + properties: any = {}; + orientation = { x: 0, y: 1 }; + items: any[] = []; + joints: any = {}; + isRunning = false; + + constructor( + config: Partial, + private container: HTMLElement + ) { + this.config = { + target: + config.target === 'everything' + ? 'body *' + : config.target ?? + 'div, span, img, ol, ul, li, a, blockquote, button, input, embed, h1, h2, h3, h4, h5, h6, label, object, option, p, pre, span, table', + ignoreClass: '', + weight: + config.weight === 'light' + ? 50 + : config.weight === 'heavy' + ? 1 + : config.weight ?? 50, + depth: config.depth ?? 1, + drag: config.drag ?? false + }; + } + + async init() { + if (this.isRunning) { + return; + } + + if (!document.getElementById('inheritance')) { + await new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.id = 'inheritance'; + script.src = '/static/vendor/inheritance.min.js'; + document.body.appendChild(script); + + script.onload = resolve; + script.onerror = reject; + }); + } + + // load box2d.js + if (!document.getElementById('box2d')) { + await new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.id = 'box2d'; + script.src = '/static/vendor/box2d.min.js'; + document.body.appendChild(script); + + script.onload = resolve; + script.onerror = reject; + }); + } + + await new Promise(resolve => setTimeout(resolve, 1000)); + + // init box2d + this.worldAABB = new window.b2AABB(); + this.worldAABB.minVertex.Set(-200, -200); + const box = this.container.getBoundingClientRect(); + this.worldAABB.maxVertex.Set(box.width + 200, box.height + 200); + + this.world = new window.b2World(this.worldAABB, new b2Vec2(0, 0), true); + + // walls + this.setWalls(); + + this.isRunning = true; + this.loop(); + } + + private getBrowserDimensions() { + let changed = false; + + const box = this.container.getBoundingClientRect(); + + const left = window.screenX + box.left; + if (this.stage[0] !== left) { + this.delta[0] = + this.stage[0] === undefined ? 0 : (left - this.stage[0]) * 50; + this.stage[0] = left; + changed = true; + } + + const top = window.screenY + box.top; + if (this.stage[1] !== top) { + this.delta[1] = + this.stage[1] === undefined ? 0 : (top - (this.stage[1] ?? 0)) * 50; + this.stage[1] = top; + changed = true; + } + + const width = box.width; + if (this.stage[2] !== width) { + this.stage[2] = width; + changed = true; + } + + const height = box.height; + if (this.stage[3] !== height) { + this.stage[3] = height; + changed = true; + } + + return changed; + } + + private setWalls() { + if (this.wallsSetted) { + this.world.DestroyBody(this.walls[0]); + this.world.DestroyBody(this.walls[1]); + this.world.DestroyBody(this.walls[2]); + this.world.DestroyBody(this.walls[3]); + + this.walls[0] = null; + this.walls[1] = null; + this.walls[2] = null; + this.walls[3] = null; + } + + this.walls[0] = this.createBox( + this.world, + this.stage[2] / 2, + -this.wall_thickness, + this.stage[2], + this.wall_thickness + ); + this.walls[1] = this.createBox( + this.world, + this.stage[2] / 2, + this.stage[3] + this.wall_thickness, + this.stage[2], + this.wall_thickness + ); + this.walls[2] = this.createBox( + this.world, + -this.wall_thickness, + this.stage[3] / 2, + this.wall_thickness, + this.stage[3] + ); + this.walls[3] = this.createBox( + this.world, + this.stage[2] + this.wall_thickness, + this.stage[3] / 2, + this.wall_thickness, + this.stage[3] + ); + + this.wallsSetted = true; + } + + private findPos(obj: HTMLElement, index: number) { + let curleft = 0; + let curtop = 0; + + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + } while ((obj = obj.offsetParent as HTMLElement)); + } + + return [curleft + index * -20, curtop]; + } + + private getBodyAtMouse() { + // Make a small box. + const mousePVec = new window.b2Vec2(); + mousePVec.Set(this.mouseX, this.mouseY); + + const aabb = new window.b2AABB(); + aabb.minVertex.Set(this.mouseX - 1, this.mouseY - 1); + aabb.maxVertex.Set(this.mouseX + 1, this.mouseY + 1); + + // Query the world for overlapping shapes. + const k_maxCount = 10; + const shapes = []; + const count = this.world.Query(aabb, shapes, k_maxCount); + let body = null; + + for (let i = 0; i < count; ++i) { + if (!shapes[i].m_body.IsStatic()) { + if (shapes[i].TestPoint(mousePVec)) { + body = shapes[i].m_body; + break; + } + } + } + + return body; + } + + private createBox( + world: any, + x: number, + y: number, + width: number, + height: number, + fixed: boolean, + element: HTMLElement + ) { + if (typeof fixed === 'undefined') fixed = true; + + const boxSd = new window.b2BoxDef(); + + if (!fixed) boxSd.density = 1.0; + + boxSd.extents.Set(width, height); + + const boxBd = new window.b2BodyDef(); + boxBd.AddShape(boxSd); + boxBd.position.Set(x, y); + boxBd.userData = { element: element }; + + return world.CreateBody(boxBd); + } + + private mouseDrag() { + if (this.config.drag) { + // mouse press + if (this.isMouseDown && !this.mouseJoint) { + const body = this.getBodyAtMouse(); + + if (body) { + const md = new window.b2MouseJointDef(); + md.body1 = this.world.m_groundBody; + md.body2 = body; + md.target.Set(this.mouseX, this.mouseY); + md.maxForce = 30000.0 * body.m_mass; + md.timeStep = this.timeStep; + this.mouseJoint = this.world.CreateJoint(md); + body.WakeUp(); + } + } + + // mouse release + if (!this.isMouseDown) { + if (this.mouseJoint) { + this.world.DestroyJoint(this.mouseJoint); + this.mouseJoint = null; + } + } + + // mouse move + if (this.mouseJoint) { + const p2 = new window.b2Vec2(this.mouseX, this.mouseY); + this.mouseJoint.SetTarget(p2); + } + } + } + + private loop() { + if (!this.isRunning) { + return; + } + + if (this.getBrowserDimensions()) this.setWalls(); + + this.delta[0] += (0 - this.delta[0]) * 0.5; + this.delta[1] += (0 - this.delta[1]) * 0.5; + + this.world.m_gravity.x = this.orientation.x * 350 + this.delta[0]; + this.world.m_gravity.y = this.orientation.y * 350 + this.delta[1]; + + this.mouseDrag(); + this.world.Step(this.timeStep, this.iterations); + + this.items.forEach(element => { + if (!element || !element.dataset || !element.dataset.id) { + return false; + } + const id = element.dataset.id; + + const body = this.bodies[id]; + + element.style.left = + body.m_position0.x - (this.properties[id][2] >> 1) + 'px'; + element.style.top = + body.m_position0.y - (this.properties[id][3] >> 1) + 'px'; + + if (!element.isGunya) { + const rotationStyle = + 'rotate(' + body.m_rotation0 * 57.2957795 + 'deg)'; + + element.style.WebkitTransform = rotationStyle; + element.style.MozTransform = rotationStyle; + element.style.OTransform = rotationStyle; + } + }); + + window.requestAnimationFrame(this.loop.bind(this)); + } + + public add(text: string, isGunya: boolean): HTMLElement | HTMLElement[] { + const jointItem = []; + + const run = (text: string, index = 0) => { + const element = document.createElement('span'); + element.innerText = text; + element.className = 'box2d'; + // const min = 5; + // const max = 80; + + // const leftPer = Math.floor(Math.random() * (max + 1 - min)) + min; + //element.style.left = `${leftPer}%`; + // element.style.top = '0'; + // console.log(leftPer); + this.container.appendChild(element); + + const id = Math.random().toString(32).substring(2); + const elementBox = element.getBoundingClientRect(); + + element.dataset.id = id; + const boxWidth = this.stage[2]; + this.properties[id] = [ + Math.max(Math.floor(Math.random() * (boxWidth - elementBox.width)), 0), + 0, + Math.min(elementBox.width, boxWidth) - 5, + elementBox.height - 5 + ]; + + element.style.position = 'absolute'; + element.style.left = this.properties[id][0] + 'px'; + element.style.top = this.properties[id][1] + 'px'; + + element.onmousedown = () => { + this.mouseOnClick[0] = window.event.clientX; + this.mouseOnClick[1] = window.event.clientY; + return false; + }; + element.onmouseup = () => false; + + this.bodies[id] = this.createBox( + this.world, + this.properties[id][0] + (this.properties[id][2] >> 1), + this.properties[id][1] + (this.properties[id][3] >> 1), + this.properties[id][2] / 2, + this.properties[id][3] / 2, + false, + element + ); + element.isGunya = isGunya; + this.items.push(element); + + if (isGunya) { + jointItem[index] = this.bodies[id]; + + if (isGunya && index > 0) { + const jointDef = new window.b2DistanceJointDef(); + jointDef.body1 = jointItem[index]; + jointDef.body2 = jointItem[index - 1]; + + jointDef.anchorPoint1 = new window.b2Vec2( + jointDef.body1.m_center.x, + jointDef.body1.m_center.y + ); + jointDef.anchorPoint2 = new window.b2Vec2( + jointDef.body2.m_center.x, + jointDef.body2.m_center.y + ); + + this.joints[id] = this.world.CreateJoint(jointDef); + } + } + + return element; + }; + + if (isGunya) { + return text.split('').reverse().map(run); + } else { + return run(text); + } + } + + public remove(elem: HTMLElement | HTMLElement[]) { + const run = (element: HTMLElement) => { + try { + if (this.isMouseDown) { + return setTimeout(() => run(element), 500); + } + + const id = element.dataset.id; + element.parentNode && element.parentNode.removeChild(element); + + this.joints[id] && this.world.DestroyJoint(this.joints[id]); + this.joints[id] = null; + + this.bodies[id] && this.world.DestroyBody(this.bodies[id]); + this.bodies[id] = null; + + const index = this.items.indexOf(element); + index !== -1 && delete this.items[index]; + } catch (e) { + console.warn(e); + } + }; + + if (Array.isArray(elem)) { + elem.forEach(run); + } else { + run(elem); + } + } + + public destroy() { + this.remove(this.items); + + this.items = []; + this.bodies = {}; + this.properties = {}; + this.world = null; + this.worldAABB = null; + + this.isRunning = false; + } +}