13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _RSGBUILTINFUNCTIONS_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _RSGBUILTINFUNCTIONS_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Random Shader Generator
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Built-in Functions.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgExpression.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgUtils.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rsg
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Template for built-in functions with form "GenType func(GenType val)".
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UnaryBuiltinVecFunc : public Expression
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UnaryBuiltinVecFunc		(GeneratorState& state, const char* function, ConstValueRangeAccess valueRange);
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~UnaryBuiltinVecFunc	(void);
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Expression*					createNextChild			(GeneratorState& state);
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						tokenize				(GeneratorState& state, TokenStream& str) const;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						evaluate				(ExecutionContext& execCtx);
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecConstValueAccess		getValue				(void) const { return m_value.getValue(m_inValueRange.getType()); }
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static float				getWeight				(const GeneratorState& state, ConstValueRangeAccess valueRange);
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string					m_function;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueRange					m_inValueRange;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueStorage			m_value;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Expression*					m_child;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::UnaryBuiltinVecFunc (GeneratorState& state, const char* function, ConstValueRangeAccess valueRange)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_function		(function)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_inValueRange	(valueRange.getType())
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_child			(DE_NULL)
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(valueRange.getType().isFloatOrVec());
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value.setStorage(valueRange.getType());
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute input value range
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < m_inValueRange.getType().getNumElements(); ndx++)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ConstValueRangeAccess	outRange	= valueRange.component(ndx);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRangeAccess		inRange		= m_inValueRange.asAccess().component(ndx);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ComputeValueRange()(outRange.getMin().asFloat(), outRange.getMax().asFloat(), inRange.getMin().asFloat(), inRange.getMax().asFloat());
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::~UnaryBuiltinVecFunc (void)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_child;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::createNextChild (GeneratorState& state)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_child)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
90ba84b6ddb4fa9742f31bca9e48777387989f65d8Jarkko Pöyry	m_child = Expression::createRandom(state, m_inValueRange.asAccess());
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_child;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::tokenize (GeneratorState& state, TokenStream& str) const
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token(m_function.c_str()) << Token::LEFT_PAREN;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child->tokenize(state, str);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::RIGHT_PAREN;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::evaluate (ExecutionContext& execCtx)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child->evaluate(execCtx);
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecConstValueAccess	srcValue	= m_child->getValue();
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess			dstValue	= m_value.getValue(m_inValueRange.getType());
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elemNdx = 0; elemNdx < m_inValueRange.getType().getNumElements(); elemNdx++)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecConstValueAccess	srcComp		= srcValue.component(elemNdx);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecValueAccess			dstComp		= dstValue.component(elemNdx);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dstComp.asFloat(compNdx) = Evaluate()(srcComp.asFloat(compNdx));
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2011-06-14 pyry] Void support?
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.getType().isFloatOrVec())
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (availableLevels < getConservativeValueExprDepth(state, valueRange) + 1)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute value range weight
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float combinedWeight = 1.0f;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elemNdx = 0; elemNdx < valueRange.getType().getNumElements(); elemNdx++)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float elemWeight = GetValueRangeWeight()(valueRange.component(elemNdx).getMin().asFloat(), valueRange.component(elemNdx).getMax().asFloat());
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedWeight *= elemWeight;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return combinedWeight;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Proxy template.
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GetUnaryBuiltinVecWeight
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline float operator() (float outMin, float outMax) const { return C::getCompWeight(outMin, outMax); }
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ComputeUnaryBuiltinVecRange
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline void operator() (float outMin, float outMax, float& inMin, float& inMax) const { C::computeValueRange(outMin, outMax, inMin, inMax); }
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct EvaluateUnaryBuiltinVec
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline float operator() (float inVal) const { return C::evaluateComp(inVal); }
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UnaryBuiltinVecTemplateProxy : public UnaryBuiltinVecFunc<GetUnaryBuiltinVecWeight<C>, ComputeUnaryBuiltinVecRange<C>, EvaluateUnaryBuiltinVec<C> >
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UnaryBuiltinVecTemplateProxy (GeneratorState& state, const char* function, ConstValueRangeAccess valueRange)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryBuiltinVecFunc<GetUnaryBuiltinVecWeight<C>, ComputeUnaryBuiltinVecRange<C>, EvaluateUnaryBuiltinVec<C> >(state, function, valueRange)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Template for trigonometric function group.
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UnaryTrigonometricFunc : public UnaryBuiltinVecTemplateProxy<C>
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UnaryTrigonometricFunc (GeneratorState& state, const char* function, ConstValueRangeAccess valueRange)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryBuiltinVecTemplateProxy<C>(state, function, valueRange)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float getCompWeight (float outMin, float outMax)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<float>() == outMin || Scalar::max<float>() == outMax)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 1.0f; // Infinite value range, anything goes
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Transform range
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float inMin, inMax;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!C::transformValueRange(outMin, outMax, inMin, inMax))
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f; // Not possible to transform value range (out of range perhaps)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Quantize
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!quantizeFloatRange(inMin, inMax))
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f; // Not possible to quantize - would cause accuracy issues
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMin == outMax)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 1.0f; // Constant value and passed quantization
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Evaluate new intersection
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float intersectionLen	= C::evaluateComp(inMax) - C::evaluateComp(inMin);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float valRangeLen		= outMax - outMin;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatMax(0.1f, intersectionLen/valRangeLen);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline void computeValueRange (float outMin, float outMax, float& inMin, float& inMax)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_VERIFY(C::transformValueRange(outMin, outMax, inMin, inMax));
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_VERIFY(quantizeFloatRange(inMin, inMax));
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(inMin <= inMax);
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (state.getProgramParameters().trigonometricBaseWeight <= 0.0f)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return UnaryBuiltinVecTemplateProxy<C>::getWeight(state, valueRange) * state.getProgramParameters().trigonometricBaseWeight;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SinOp : public UnaryTrigonometricFunc<SinOp>
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SinOp (GeneratorState& state, ConstValueRangeAccess valueRange)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<SinOp>(state, "sin", valueRange)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < -1.0f || outMin > 1.0f)
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = (outMin >= -1.0f) ? deFloatAsin(outMin) : -0.5f*DE_PI;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = (outMax <= +1.0f) ? deFloatAsin(outMax) : +0.5f*DE_PI;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatSin(inVal);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CosOp : public UnaryTrigonometricFunc<CosOp>
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CosOp (GeneratorState& state, ConstValueRangeAccess valueRange)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<CosOp>(state, "cos", valueRange)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < -1.0f || outMin > 1.0f)
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = (outMin >= -1.0f) ? deFloatAcos(outMin) : +DE_PI;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = (outMax <= +1.0f) ? deFloatAcos(outMax) : -DE_PI;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatCos(inVal);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TanOp : public UnaryTrigonometricFunc<TanOp>
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TanOp (GeneratorState& state, ConstValueRangeAccess valueRange)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<TanOp>(state, "tan", valueRange)
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Currently tan() is limited to -4..4 range. Otherwise we will run into accuracy issues
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = -4.0f;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = +4.0f;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatAtanOver(deFloatMax(outMin, rangeMin));
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatAtanOver(deFloatMin(outMax, rangeMax));
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatTan(inVal);
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AsinOp : public UnaryTrigonometricFunc<AsinOp>
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AsinOp (GeneratorState& state, ConstValueRangeAccess valueRange)
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<AsinOp>(state, "asin", valueRange)
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = -DE_PI/2.0f;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = +DE_PI/2.0f;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatSin(deFloatMax(outMin, rangeMin));
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatSin(deFloatMin(outMax, rangeMax));
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatAsin(inVal);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AcosOp : public UnaryTrigonometricFunc<AcosOp>
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AcosOp (GeneratorState& state, ConstValueRangeAccess valueRange)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<AcosOp>(state, "acos", valueRange)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.0f;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = DE_PI;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatCos(deFloatMax(outMin, rangeMin));
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatCos(deFloatMin(outMax, rangeMax));
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatAcos(inVal);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AtanOp : public UnaryTrigonometricFunc<AtanOp>
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AtanOp (GeneratorState& state, ConstValueRangeAccess valueRange)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryTrigonometricFunc<AtanOp>(state, "atan", valueRange)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note For accuracy reasons output range is limited to -1..1
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = -1.0f;
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = +1.0f;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatTan(deFloatMax(outMin, rangeMin));
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatTan(deFloatMin(outMax, rangeMax));
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatAtanOver(inVal);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Template for exponential function group.
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2011-07-07 pyry] Shares most of the code with Trigonometric variant..
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class C>
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UnaryExponentialFunc : public UnaryBuiltinVecTemplateProxy<C>
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UnaryExponentialFunc (GeneratorState& state, const char* function, ConstValueRangeAccess valueRange)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryBuiltinVecTemplateProxy<C>(state, function, valueRange)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float getCompWeight (float outMin, float outMax)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<float>() == outMin || Scalar::max<float>() == outMax)
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 1.0f; // Infinite value range, anything goes
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Transform range
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float inMin, inMax;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!C::transformValueRange(outMin, outMax, inMin, inMax))
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f; // Not possible to transform value range (out of range perhaps)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Quantize
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!quantizeFloatRange(inMin, inMax))
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f; // Not possible to quantize - would cause accuracy issues
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMin == outMax)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 1.0f; // Constant value and passed quantization
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Evaluate new intersection
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float intersectionLen	= C::evaluateComp(inMax) - C::evaluateComp(inMin);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float valRangeLen		= outMax - outMin;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatMax(0.1f, intersectionLen/valRangeLen);
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline void computeValueRange (float outMin, float outMax, float& inMin, float& inMax)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_VERIFY(C::transformValueRange(outMin, outMax, inMin, inMax));
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_VERIFY(quantizeFloatRange(inMin, inMax));
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(inMin <= inMax);
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (state.getProgramParameters().exponentialBaseWeight <= 0.0f)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return UnaryBuiltinVecTemplateProxy<C>::getWeight(state, valueRange) * state.getProgramParameters().exponentialBaseWeight;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExpOp : public UnaryExponentialFunc<ExpOp>
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExpOp (GeneratorState& state, ConstValueRangeAccess valueRange)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<ExpOp>(state, "exp", valueRange)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons, should be 0..+inf
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.1f;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 10.0f;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatLog(deFloatMax(outMin, rangeMin));
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatLog(deFloatMin(outMax, rangeMax));
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatExp(inVal);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LogOp : public UnaryExponentialFunc<LogOp>
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LogOp (GeneratorState& state, ConstValueRangeAccess valueRange)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<LogOp>(state, "log", valueRange)
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons, should be -inf..+inf
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.1f;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 6.0f;
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatExp(deFloatMax(outMin, rangeMin));
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatExp(deFloatMin(outMax, rangeMax));
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatLog(inVal);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Exp2Op : public UnaryExponentialFunc<Exp2Op>
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Exp2Op (GeneratorState& state, ConstValueRangeAccess valueRange)
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<Exp2Op>(state, "exp2", valueRange)
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons, should be 0..+inf
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.1f;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 10.0f;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatLog2(deFloatMax(outMin, rangeMin));
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatLog2(deFloatMin(outMax, rangeMax));
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatExp2(inVal);
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Log2Op : public UnaryExponentialFunc<Log2Op>
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Log2Op (GeneratorState& state, ConstValueRangeAccess valueRange)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<Log2Op>(state, "log2", valueRange)
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons, should be -inf..+inf
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.1f;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 6.0f;
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatExp2(deFloatMax(outMin, rangeMin));
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatExp2(deFloatMin(outMax, rangeMax));
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatLog2(inVal);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SqrtOp : public UnaryExponentialFunc<SqrtOp>
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SqrtOp (GeneratorState& state, ConstValueRangeAccess valueRange)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<SqrtOp>(state, "sqrt", valueRange)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons, should be 0..+inf
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.0f;
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 4.0f;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = deFloatMax(outMin, rangeMin);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = deFloatMin(outMax, rangeMax);
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin *= inMin;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax *= inMax;
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatSqrt(inVal);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvSqrtOp : public UnaryExponentialFunc<InvSqrtOp>
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InvSqrtOp (GeneratorState& state, ConstValueRangeAccess valueRange)
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: UnaryExponentialFunc<InvSqrtOp>(state, "inversesqrt", valueRange)
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline bool transformValueRange (float outMin, float outMax, float& inMin, float& inMax)
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Limited due to accuracy reasons
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMin = 0.4f;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float rangeMax = 3.0f;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (outMax < rangeMin || outMin > rangeMax)
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Out of range
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax = 1.0f/deFloatMax(outMin, rangeMin);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin = 1.0f/deFloatMin(outMax, rangeMax);
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMin *= inMin;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		inMax *= inMax;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline float evaluateComp (float inVal)
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 1.0f/deFloatSqrt(inVal);
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rsg
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _RSGBUILTINFUNCTIONS_HPP
620