⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vrml_interpolators.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Scene Graph sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/scenegraph_dev.h>#include <gpac/nodes_mpeg4.h>#include <gpac/nodes_x3d.h>Fixed Interpolate(Fixed keyValue1, Fixed keyValue2, Fixed fraction){	return gf_mulfix(keyValue2 - keyValue1, fraction) + keyValue1;}Fixed GetInterpolateFraction(Fixed key1, Fixed key2, Fixed fraction){	Fixed keyDiff = key2 - key1;	assert((fraction >= key1) && (fraction <= key2));	if (ABS(keyDiff) < FIX_EPSILON) return 0;	return gf_divfix(fraction - key1, keyDiff);}static void CI2D_SetFraction(GF_Node *n){	Fixed frac;	u32 numElemPerKey, i, j;	M_CoordinateInterpolator2D *_this = (M_CoordinateInterpolator2D *) n;	if (! _this->key.count) return;	if (_this->keyValue.count % _this->key.count) return;		numElemPerKey = _this->keyValue.count / _this->key.count;	//set size	if (_this->value_changed.count != numElemPerKey)		gf_sg_vrml_mf_alloc(&_this->value_changed, GF_SG_VRML_MFVEC2F, numElemPerKey);	if (_this->set_fraction < _this->key.vals[0]) {		for (i=0; i<numElemPerKey; i++)			_this->value_changed.vals[i] = _this->keyValue.vals[i];	} else if (_this->set_fraction > _this->key.vals[_this->key.count - 1]) {		for (i=0; i<numElemPerKey; i++)			_this->value_changed.vals[i] = _this->keyValue.vals[(_this->keyValue.count) - numElemPerKey + i];	} else {		for (j = 1; j < _this->key.count; j++) {			// Find the key values the fraction lies between			if ( _this->set_fraction < _this->key.vals[j-1]) continue;			if (_this->set_fraction >= _this->key.vals[j]) continue;			frac = GetInterpolateFraction(_this->key.vals[j-1], _this->key.vals[j], _this->set_fraction);			for (i=0; i<numElemPerKey; i++) {				_this->value_changed.vals[i].x = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].x,															_this->keyValue.vals[(j)*numElemPerKey + i].x, 															frac);				_this->value_changed.vals[i].y = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].y,															_this->keyValue.vals[(j)*numElemPerKey + i].y,															frac);			}			break;		}	}	//invalidate	gf_node_event_out_str(n, "value_changed");}Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node){	node->on_set_fraction = CI2D_SetFraction;	if (node->key.count && !(node->keyValue.count % node->key.count) ) {		u32 numElemPerKey, i;		numElemPerKey = node->keyValue.count / node->key.count;		gf_sg_vrml_mf_alloc(&node->value_changed, GF_SG_VRML_MFVEC2F, numElemPerKey);		for (i=0; i<numElemPerKey; i++)			node->value_changed.vals[i] = node->keyValue.vals[i];	}	return 1;}static Bool CI_SetFraction(Fixed fraction, MFVec3f *vals, MFFloat *key, MFVec3f *keyValue){	Fixed frac;	u32 numElemPerKey, i, j;	if (! key->count) return 0;	if (keyValue->count % key->count) return 0;		numElemPerKey = keyValue->count / key->count;	if (vals->count != numElemPerKey) gf_sg_vrml_mf_alloc(vals, GF_SG_VRML_MFVEC3F, numElemPerKey);	if (fraction < key->vals[0]) {		for (i=0; i<numElemPerKey; i++)			vals->vals[i] = keyValue->vals[i];	} else if (fraction > key->vals[key->count - 1]) {		for (i=0; i<numElemPerKey; i++)			vals->vals[i] = keyValue->vals[(keyValue->count) - numElemPerKey + i];	} else {		for (j = 1; j < key->count; j++) {			// Find the key values the fraction lies between			if (fraction < key->vals[j-1]) continue;			if (fraction >= key->vals[j]) continue;			frac = GetInterpolateFraction(key->vals[j-1], key->vals[j], fraction);			for (i=0; i<numElemPerKey; i++) {				vals->vals[i].x = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].x,															keyValue->vals[(j)*numElemPerKey + i].x,															frac);				vals->vals[i].y = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].y,															keyValue->vals[(j)*numElemPerKey + i].y,															frac);				vals->vals[i].z = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].z,															keyValue->vals[(j)*numElemPerKey + i].z, 															frac);			}			break;		}	}	return 1;}static void CoordInt_SetFraction(GF_Node *n){	M_CoordinateInterpolator *_this = (M_CoordinateInterpolator *) n;	if (CI_SetFraction(_this->set_fraction, &_this->value_changed, &_this->key, &_this->keyValue)) 		gf_node_event_out_str(n, "value_changed");}Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n){	n->on_set_fraction = CoordInt_SetFraction;	CI_SetFraction(0, &n->value_changed, &n->key, &n->keyValue);	return 1;}static void NormInt_SetFraction(GF_Node *n){	u32 i;	M_NormalInterpolator *_this = (M_NormalInterpolator *) n;	if (!CI_SetFraction(_this->set_fraction, &_this->value_changed, &_this->key, &_this->keyValue)) return;	/*renorm*/	for (i=0; i<_this->value_changed.count; i++) {		gf_vec_norm(&_this->value_changed.vals[i]);	}	gf_node_event_out_str(n, "value_changed");}Bool InitNormalInterpolator(M_NormalInterpolator *n){	n->on_set_fraction = NormInt_SetFraction;	CI_SetFraction(0, &n->value_changed, &n->key, &n->keyValue);	return 1;}static void ColorInt_SetFraction(GF_Node *node){	u32 i;	Fixed frac;	M_ColorInterpolator *_this = (M_ColorInterpolator *)node;	if (! _this->key.count) return;	if (_this->keyValue.count != _this->key.count) return;		// The given fraction is less than the specified range	if (_this->set_fraction < _this->key.vals[0]) {		_this->value_changed = _this->keyValue.vals[0];	} else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {		_this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];	} else {		for (i=1; i<_this->key.count; i++) {			// Find the key values the fraction lies between			if (_this->set_fraction < _this->key.vals[i-1]) continue;			if (_this->set_fraction >= _this->key.vals[i]) continue;			frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);			_this->value_changed.red = Interpolate(_this->keyValue.vals[i-1].red, 													_this->keyValue.vals[i].red, 													frac);			_this->value_changed.green = Interpolate(_this->keyValue.vals[i-1].green,													_this->keyValue.vals[i].green, 													frac);			_this->value_changed.blue = Interpolate(_this->keyValue.vals[i-1].blue,													_this->keyValue.vals[i].blue,													frac);			break;		}	}	gf_node_event_out_str(node, "value_changed");}Bool InitColorInterpolator(M_ColorInterpolator *node){	node->on_set_fraction = ColorInt_SetFraction; 	if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];	return 1;}static void PosInt2D_SetFraction(GF_Node *node){	M_PositionInterpolator2D *_this = (M_PositionInterpolator2D *)node;	u32 i;	Fixed frac;	if (! _this->key.count) return;	if (_this->keyValue.count != _this->key.count) return;		// The given fraction is less than the specified range	if (_this->set_fraction < _this->key.vals[0]) {		_this->value_changed = _this->keyValue.vals[0];	} else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {		_this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];	} else {		for (i=1; i<_this->key.count; i++) {			// Find the key values the fraction lies between			if (_this->set_fraction < _this->key.vals[i-1]) continue;			if (_this->set_fraction >= _this->key.vals[i]) continue;			frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);			_this->value_changed.x = Interpolate(_this->keyValue.vals[i-1].x, _this->keyValue.vals[i].x, frac);			_this->value_changed.y = Interpolate(_this->keyValue.vals[i-1].y, _this->keyValue.vals[i].y, frac);			break;		}	}	gf_node_event_out_str(node, "value_changed");}Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node){	node->on_set_fraction = PosInt2D_SetFraction; 	if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];	return 1;}static void PosInt_SetFraction(GF_Node *node){	u32 i;	Fixed frac;	M_PositionInterpolator *_this = (M_PositionInterpolator *)node;	if (! _this->key.count) return;	if (_this->keyValue.count != _this->key.count) return;		// The given fraction is less than the specified range	if (_this->set_fraction < _this->key.vals[0]) {		_this->value_changed = _this->keyValue.vals[0];	} else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {		_this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];	} else {		for (i=1; i<_this->key.count; i++) {			// Find the key values the fraction lies between			if (_this->set_fraction < _this->key.vals[i-1]) continue;			if (_this->set_fraction >= _this->key.vals[i]) continue;			frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);			_this->value_changed.x = Interpolate(_this->keyValue.vals[i-1].x, _this->keyValue.vals[i].x, frac);			_this->value_changed.y = Interpolate(_this->keyValue.vals[i-1].y, _this->keyValue.vals[i].y, frac);			_this->value_changed.z = Interpolate(_this->keyValue.vals[i-1].z, _this->keyValue.vals[i].z, frac);			break;		}	}	gf_node_event_out_str(node, "value_changed");}Bool InitPositionInterpolator(M_PositionInterpolator *node){	node->on_set_fraction = PosInt_SetFraction; 	if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];	return 1;}static void ScalarInt_SetFraction(GF_Node *node){	M_ScalarInterpolator *_this = (M_ScalarInterpolator *)node;	u32 i;	Fixed frac;	if (! _this->key.count) return;	if (_this->keyValue.count != _this->key.count) return;		// The given fraction is less than the specified range	if (_this->set_fraction < _this->key.vals[0]) {		_this->value_changed = _this->keyValue.vals[0];	} else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {		_this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];	} else {		for (i=1; i<_this->key.count; i++) {			// Find the key values the fraction lies between			if (_this->set_fraction < _this->key.vals[i-1]) continue;			if (_this->set_fraction >= _this->key.vals[i]) continue;			frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);			_this->value_changed = Interpolate(_this->keyValue.vals[i-1], _this->keyValue.vals[i], frac);			break;		}	}	gf_node_event_out_str(node, "value_changed");}Bool InitScalarInterpolator(M_ScalarInterpolator *node){	node->on_set_fraction = ScalarInt_SetFraction; 	if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];	return 1;}/*taken from freeWRL*/GF_EXPORTSFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction){	SFRotation res;	Fixed newa, olda;	Bool stzero = ( ABS(kv1.q) < FIX_EPSILON) ? 1 : 0;	Bool endzero = ( ABS(kv2.q) < FIX_EPSILON) ? 1 : 0;	Fixed testa = gf_mulfix(kv1.x, kv2.x) + gf_mulfix(kv1.y, kv2.y) + gf_mulfix(kv1.y, kv2.y);	if (testa>= 0) {		res.x = kv1.x + gf_mulfix(fraction, kv2.x-kv1.x);		res.y = kv1.y + gf_mulfix(fraction, kv2.y-kv1.y);		res.z = kv1.z + gf_mulfix(fraction, kv2.z-kv1.z);		newa = kv2.q;	} else {		res.x = kv1.x + gf_mulfix(fraction, -kv2.x -kv1.x);		res.y = kv1.y + gf_mulfix(fraction, -kv2.y-kv1.y);		res.z = kv1.z + gf_mulfix(fraction, -kv2.z-kv1.z);		newa = -kv2.q;	}	olda = kv1.q;	testa = newa - olda;	/* make it so we smoothly transition */	if (ABS(testa) > GF_PI) {		if (ABS(testa) > GF_2PI) {			if (testa>0) {				olda += 2*GF_2PI;			} else {				newa += 2*GF_2PI; 			}		} else {			if (testa>0) {				olda += GF_2PI;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -