亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? cpcollision.c

?? Compressed file has password
?? C
字號:
/* Copyright (c) 2007 Scott Lembcke *  * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: *  * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <stdlib.h>#include <math.h>#include <stdio.h>#include <assert.h>#include "chipmunk.h"typedef int (*collisionFunc)(cpShape*, cpShape*, cpContact**);static collisionFunc *colfuncs = NULL;// Add contact points for circle to circle collisions.// Used by several collision tests.static intcircle2circleQuery(cpVect p1, cpVect p2, cpFloat r1, cpFloat r2, cpContact **con){	cpFloat mindist = r1 + r2;	cpVect delta = cpvsub(p2, p1);	cpFloat distsq = cpvlengthsq(delta);	if(distsq >= mindist*mindist) return 0;		cpFloat dist = sqrtf(distsq);	// To avoid singularities, do nothing in the case of dist = 0.	cpFloat non_zero_dist = (dist ? dist : INFINITY);	// Allocate and initialize the contact.	(*con) = (cpContact *)malloc(sizeof(cpContact));	cpContactInit(		(*con),		cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/non_zero_dist)),		cpvmult(delta, 1.0f/non_zero_dist),		dist - mindist,		0	);		return 1;}// Collide circle shapes.static intcircle2circle(cpShape *shape1, cpShape *shape2, cpContact **arr){	cpCircleShape *circ1 = (cpCircleShape *)shape1;	cpCircleShape *circ2 = (cpCircleShape *)shape2;		return circle2circleQuery(circ1->tc, circ2->tc, circ1->r, circ2->r, arr);}// Collide circles to segment shapes.static intcircle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con){	cpCircleShape *circ = (cpCircleShape *)circleShape;	cpSegmentShape *seg = (cpSegmentShape *)segmentShape;		// Radius sum	cpFloat rsum = circ->r + seg->r;		// Calculate normal distance from segment.	cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);	cpFloat dist = fabsf(dn) - rsum;	if(dist > 0.0f) return 0;		// Calculate tangential distance along segment.	cpFloat dt = -cpvcross(seg->tn, circ->tc);	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);		// Decision tree to decide which feature of the segment to collide with.	if(dt < dtMin){		if(dt < (dtMin - rsum)){			return 0;		} else {			return circle2circleQuery(circ->tc, seg->ta, circ->r, seg->r, con);		}	} else {		if(dt < dtMax){			cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);			(*con) = (cpContact *)malloc(sizeof(cpContact));			cpContactInit(				(*con),				cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),				n,				dist,				0				 			);			return 1;		} else {			if(dt < (dtMax + rsum)) {				return circle2circleQuery(circ->tc, seg->tb, circ->r, seg->r, con);			} else {				return 0;			}		}	}		return 1;}// Helper function for allocating contact point lists.static cpContact *addContactPoint(cpContact **arr, int *max, int *num){	if(*arr == NULL){		// Allocate the array if it hasn't been done.		(*max) = 2;		(*num) = 0;		(*arr) = (cpContact *)malloc((*max)*sizeof(cpContact));	} else if(*num == *max){		// Extend it if necessary.		(*max) *= 2;		(*arr) = (cpContact *)realloc(*arr, (*max)*sizeof(cpContact));	}		cpContact *con = &(*arr)[*num];	(*num)++;		return con;}// Find the minimum separating axis for the give poly and axis list.static inline intfindMSA(cpPolyShape *poly, cpPolyShapeAxis *axes, int num, cpFloat *min_out){	int min_index = 0;	cpFloat min = cpPolyShapeValueOnAxis(poly, axes->n, axes->d);	if(min > 0.0) return -1;		for(int i=1; i<num; i++){		cpFloat dist = cpPolyShapeValueOnAxis(poly, axes[i].n, axes[i].d);		if(dist > 0.0) {			return -1;		} else if(dist > min){			min = dist;			min_index = i;		}	}		(*min_out) = min;	return min_index;}// Add contacts for penetrating vertexes.static inline intfindVerts(cpContact **arr, cpPolyShape *poly1, cpPolyShape *poly2, cpVect n, cpFloat dist){	int max = 0;	int num = 0;		for(int i=0; i<poly1->numVerts; i++){		cpVect v = poly1->tVerts[i];		if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))			cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly1, i));	}		for(int i=0; i<poly2->numVerts; i++){		cpVect v = poly2->tVerts[i];		if(cpPolyShapeContainsVertPartial(poly1, v, n))			cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly2, i));	}		//	if(!num)	//		addContactPoint(arr, &size, &num, cpContactNew(shape1->body->p, n, dist, 0));	return num;}// Collide poly shapes together.static intpoly2poly(cpShape *shape1, cpShape *shape2, cpContact **arr){	cpPolyShape *poly1 = (cpPolyShape *)shape1;	cpPolyShape *poly2 = (cpPolyShape *)shape2;		cpFloat min1;	int mini1 = findMSA(poly2, poly1->tAxes, poly1->numVerts, &min1);	if(mini1 == -1) return 0;		cpFloat min2;	int mini2 = findMSA(poly1, poly2->tAxes, poly2->numVerts, &min2);	if(mini2 == -1) return 0;		// There is overlap, find the penetrating verts	if(min1 > min2)		return findVerts(arr, poly1, poly2, poly1->tAxes[mini1].n, min1);	else		return findVerts(arr, poly1, poly2, cpvneg(poly2->tAxes[mini2].n), min2);}// Like cpPolyValueOnAxis(), but for segments.static inline floatsegValueOnAxis(cpSegmentShape *seg, cpVect n, cpFloat d){	cpFloat a = cpvdot(n, seg->ta) - seg->r;	cpFloat b = cpvdot(n, seg->tb) - seg->r;	return cpfmin(a, b) - d;}// Identify vertexes that have penetrated the segment.static inline voidfindPointsBehindSeg(cpContact **arr, int *max, int *num, cpSegmentShape *seg, cpPolyShape *poly, cpFloat pDist, cpFloat coef) {	cpFloat dta = cpvcross(seg->tn, seg->ta);	cpFloat dtb = cpvcross(seg->tn, seg->tb);	cpVect n = cpvmult(seg->tn, coef);		for(int i=0; i<poly->numVerts; i++){		cpVect v = poly->tVerts[i];		if(cpvdot(v, n) < cpvdot(seg->tn, seg->ta)*coef + seg->r){			cpFloat dt = cpvcross(seg->tn, v);			if(dta >= dt && dt >= dtb){				cpContactInit(addContactPoint(arr, max, num), v, n, pDist, CP_HASH_PAIR(poly, i));			}		}	}}// This one is complicated and gross. Just don't go there...// TODO: Comment me!static intseg2poly(cpShape *shape1, cpShape *shape2, cpContact **arr){	cpSegmentShape *seg = (cpSegmentShape *)shape1;	cpPolyShape *poly = (cpPolyShape *)shape2;	cpPolyShapeAxis *axes = poly->tAxes;		cpFloat segD = cpvdot(seg->tn, seg->ta);	cpFloat minNorm = cpPolyShapeValueOnAxis(poly, seg->tn, segD) - seg->r;	cpFloat minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg->tn), -segD) - seg->r;	if(minNeg > 0.0f || minNorm > 0.0f) return 0;		int mini = 0;	cpFloat poly_min = segValueOnAxis(seg, axes->n, axes->d);	if(poly_min > 0.0f) return 0;	for(int i=0; i<poly->numVerts; i++){		cpFloat dist = segValueOnAxis(seg, axes[i].n, axes[i].d);		if(dist > 0.0f){			return 0;		} else if(dist > poly_min){			poly_min = dist;			mini = i;		}	}		int max = 0;	int num = 0;		cpVect poly_n = cpvneg(axes[mini].n);		cpVect va = cpvadd(seg->ta, cpvmult(poly_n, seg->r));	cpVect vb = cpvadd(seg->tb, cpvmult(poly_n, seg->r));	if(cpPolyShapeContainsVert(poly, va))		cpContactInit(addContactPoint(arr, &max, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg, 0));	if(cpPolyShapeContainsVert(poly, vb))		cpContactInit(addContactPoint(arr, &max, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg, 1));	// Floating point precision problems here.	// This will have to do for now.	poly_min -= cp_collision_slop;	if(minNorm >= poly_min || minNeg >= poly_min) {		if(minNorm > minNeg)			findPointsBehindSeg(arr, &max, &num, seg, poly, minNorm, 1.0f);		else			findPointsBehindSeg(arr, &max, &num, seg, poly, minNeg, -1.0f);	}		// If no other collision points are found, try colliding endpoints.	if(num == 0){		cpVect poly_a = poly->tVerts[mini];		cpVect poly_b = poly->tVerts[(mini + 1)%poly->numVerts];				if(circle2circleQuery(seg->ta, poly_a, seg->r, 0.0f, arr))			return 1;					if(circle2circleQuery(seg->tb, poly_a, seg->r, 0.0f, arr))			return 1;					if(circle2circleQuery(seg->ta, poly_b, seg->r, 0.0f, arr))			return 1;					if(circle2circleQuery(seg->tb, poly_b, seg->r, 0.0f, arr))			return 1;	}	return num;}// This one is less gross, but still gross.// TODO: Comment me!static intcircle2poly(cpShape *shape1, cpShape *shape2, cpContact **con){	cpCircleShape *circ = (cpCircleShape *)shape1;	cpPolyShape *poly = (cpPolyShape *)shape2;	cpPolyShapeAxis *axes = poly->tAxes;		int mini = 0;	cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;	for(int i=0; i<poly->numVerts; i++){		cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;		if(dist > 0.0){			return 0;		} else if(dist > min) {			min = dist;			mini = i;		}	}		cpVect n = axes[mini].n;	cpVect a = poly->tVerts[mini];	cpVect b = poly->tVerts[(mini + 1)%poly->numVerts];	cpFloat dta = cpvcross(n, a);	cpFloat dtb = cpvcross(n, b);	cpFloat dt = cpvcross(n, circ->tc);			if(dt < dtb){		return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);	} else if(dt < dta) {		(*con) = (cpContact *)malloc(sizeof(cpContact));		cpContactInit(			(*con),			cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),			cpvneg(n),			min,			0				 		);			return 1;	} else {		return circle2circleQuery(circ->tc, a, circ->r, 0.0f, con);	}}static voidaddColFunc(cpShapeType a, cpShapeType b, collisionFunc func){	colfuncs[a + b*CP_NUM_SHAPES] = func;}#ifdef __cplusplusextern "C" {#endif	// Initializes the array of collision functions.	// Called by cpInitChipmunk().	void	cpInitCollisionFuncs(void)	{		if(!colfuncs)			colfuncs = (collisionFunc *)calloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));				addColFunc(CP_CIRCLE_SHAPE,  CP_CIRCLE_SHAPE,  circle2circle);		addColFunc(CP_CIRCLE_SHAPE,  CP_SEGMENT_SHAPE, circle2segment);		addColFunc(CP_SEGMENT_SHAPE, CP_POLY_SHAPE,    seg2poly);		addColFunc(CP_CIRCLE_SHAPE,  CP_POLY_SHAPE,    circle2poly);		addColFunc(CP_POLY_SHAPE,    CP_POLY_SHAPE,    poly2poly);	}	#ifdef __cplusplus}#endifintcpCollideShapes(cpShape *a, cpShape *b, cpContact **arr){	// Their shape types must be in order.	assert(a->klass->type <= b->klass->type);		collisionFunc cfunc = colfuncs[a->klass->type + b->klass->type*CP_NUM_SHAPES];	return (cfunc) ? cfunc(a, b, arr) : 0;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
麻豆成人久久精品二区三区小说| 精品国产三级电影在线观看| 中文字幕中文乱码欧美一区二区| 国产精品一区二区三区网站| 久久午夜老司机| 国产成人综合视频| 国产精品卡一卡二| 欧美午夜精品久久久| 日韩电影免费在线看| 精品国产电影一区二区| 国产成人精品免费网站| 亚洲日本青草视频在线怡红院| 色综合天天综合网天天狠天天 | 国产精品家庭影院| 99re成人精品视频| 日本不卡123| 久久久久青草大香线综合精品| 粉嫩av一区二区三区在线播放 | 国产麻豆视频精品| 亚洲精选免费视频| 欧美成人高清电影在线| 成人高清在线视频| 日韩专区欧美专区| 国产精品久久久一本精品| 精品视频资源站| 精品亚洲国内自在自线福利| 国产精品久久久久9999吃药| 欧美精品v日韩精品v韩国精品v| 精品在线亚洲视频| 一片黄亚洲嫩模| 久久久久久久久久看片| 欧美在线999| 国产ts人妖一区二区| 丝袜美腿亚洲色图| 国产精品成人免费| 欧美成人一级视频| 欧美色男人天堂| 99在线热播精品免费| 美女国产一区二区三区| 亚洲免费观看在线视频| 337p粉嫩大胆色噜噜噜噜亚洲| 在线这里只有精品| 粉嫩绯色av一区二区在线观看 | 国产精品一区二区你懂的| 亚洲精品中文在线| 国产日产亚洲精品系列| 欧美一区二区在线播放| 色欧美片视频在线观看在线视频| 韩国女主播一区| 视频一区在线播放| 亚洲精品久久久久久国产精华液| 久久九九国产精品| 日韩一区二区三区三四区视频在线观看| 99久久er热在这里只有精品15| 九色综合国产一区二区三区| 亚洲高清免费视频| 亚洲欧美激情小说另类| 久久精品一区二区三区av| 欧美一区二区三区在线电影| 在线观看91精品国产入口| 99re8在线精品视频免费播放| 国产成人在线看| 激情综合网天天干| 国产一区二区在线观看免费| 日本aⅴ亚洲精品中文乱码| 亚洲一区视频在线| 亚洲资源中文字幕| 有码一区二区三区| 一区二区三区欧美久久| 亚洲欧美日韩一区二区| ...xxx性欧美| 自拍偷在线精品自拍偷无码专区| 欧美激情一区二区三区蜜桃视频| 2021中文字幕一区亚洲| 久久女同精品一区二区| 久久男人中文字幕资源站| 久久综合九色综合欧美亚洲| 精品少妇一区二区三区免费观看| 日韩欧美中文一区二区| 日韩视频免费观看高清完整版在线观看 | 欧美精品三级在线观看| 欧美日韩视频不卡| 91精品国产综合久久久蜜臀图片| 91麻豆精品国产自产在线观看一区 | 欧美一区二区三区喷汁尤物| 欧美喷水一区二区| 欧美一级高清大全免费观看| 91精品欧美福利在线观看| 日韩色在线观看| 精品国产乱子伦一区| 久久综合999| 国产精品网站在线观看| 中文字幕日韩av资源站| 亚洲国产另类精品专区| 蜜臀久久久久久久| 国产精品1区二区.| 99精品视频一区| 欧美日韩国产综合一区二区| 日韩一区二区三区四区五区六区| 精品国产成人在线影院 | 99精品欧美一区二区蜜桃免费| www.亚洲国产| 欧美日韩国产不卡| 久久先锋资源网| 亚洲乱码中文字幕| 男男视频亚洲欧美| 成人免费三级在线| 欧美无砖砖区免费| 精品国产乱子伦一区| 亚洲美女在线国产| 久久不见久久见免费视频7| 国产69精品一区二区亚洲孕妇| 色噜噜狠狠成人中文综合| 日韩精品一区二区三区四区 | 99久久精品99国产精品| 91精品国产乱码| 欧美国产一区在线| 首页亚洲欧美制服丝腿| 成人97人人超碰人人99| 欧美精品欧美精品系列| 中文字幕精品综合| 日本午夜精品视频在线观看 | 国内精品免费**视频| 欧美综合视频在线观看| 久久久久久夜精品精品免费| 一区二区三区成人在线视频| 精品一区二区三区视频在线观看| youjizz国产精品| 欧美videossexotv100| 亚洲国产视频一区二区| 成人性生交大片| 欧美va亚洲va在线观看蝴蝶网| 亚洲裸体在线观看| 国产成人丝袜美腿| 日韩欧美资源站| 日韩电影在线观看一区| 一本一道久久a久久精品综合蜜臀| 欧美大片顶级少妇| 亚洲成av人片在www色猫咪| 波多野结衣中文一区| 久久综合九色综合97_久久久| 午夜精品一区二区三区三上悠亚 | 色噜噜狠狠成人网p站| 日本一区二区三区视频视频| 久久99久久久久| 欧美日韩高清一区| 亚洲一区二区三区四区在线观看 | 亚洲三级免费观看| 国产91在线看| 国产色91在线| 韩国v欧美v日本v亚洲v| 日韩精品一区二区三区中文精品| 亚洲成人福利片| 欧美综合天天夜夜久久| 一区二区三区中文字幕电影| www.一区二区| 亚洲丝袜自拍清纯另类| av中文一区二区三区| 国产精品你懂的在线欣赏| 国产精品亚洲专一区二区三区| 欧美一三区三区四区免费在线看| 视频一区视频二区在线观看| 欧美日韩视频第一区| 亚洲国产日韩a在线播放性色| 91成人免费在线| 午夜视频在线观看一区| 欧美视频自拍偷拍| 午夜亚洲国产au精品一区二区| 欧美亚洲丝袜传媒另类| 午夜激情久久久| 制服丝袜在线91| 久久精品久久精品| 久久亚洲综合av| 成人午夜视频福利| 中文字幕日本不卡| 在线亚洲人成电影网站色www| 亚洲最新视频在线观看| 欧美日韩在线观看一区二区| 亚洲福利一二三区| 日韩一级片网站| 国产福利精品一区| 国产精品国产三级国产| 色诱视频网站一区| 石原莉奈在线亚洲二区| 欧美精品一区二区高清在线观看 | 欧美成人免费网站| 国产 日韩 欧美大片| 中文字幕一区二区三区在线播放| 日本久久精品电影| 日韩激情视频在线观看| 精品久久久久久最新网址| 国产不卡视频在线播放| 亚洲视频一二区| 欧美一区二区视频网站| 国产伦精品一区二区三区免费迷 | 在线看日本不卡| 精品无人区卡一卡二卡三乱码免费卡| 国产日韩成人精品| 欧美日韩在线电影| 高清在线观看日韩|