|
Blender
V2.59
|
00001 /* 00002 * Generate random pulses 00003 * 00004 * $Id: SCA_RandomSensor.cpp 35169 2011-02-25 13:32:11Z jesterking $ 00005 * 00006 * ***** BEGIN GPL LICENSE BLOCK ***** 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00023 * All rights reserved. 00024 * 00025 * The Original Code is: all of this file. 00026 * 00027 * Contributor(s): none yet. 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 */ 00031 00037 #include <stddef.h> 00038 00039 #include "SCA_RandomSensor.h" 00040 #include "SCA_EventManager.h" 00041 #include "SCA_RandomEventManager.h" 00042 #include "SCA_LogicManager.h" 00043 #include "ConstExpr.h" 00044 #include <iostream> 00045 00046 /* ------------------------------------------------------------------------- */ 00047 /* Native functions */ 00048 /* ------------------------------------------------------------------------- */ 00049 00050 SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, 00051 SCA_IObject* gameobj, 00052 int startseed) 00053 : SCA_ISensor(gameobj,eventmgr) 00054 { 00055 m_basegenerator = new SCA_RandomNumberGenerator(startseed); 00056 Init(); 00057 } 00058 00059 00060 00061 SCA_RandomSensor::~SCA_RandomSensor() 00062 { 00063 m_basegenerator->Release(); 00064 } 00065 00066 void SCA_RandomSensor::Init() 00067 { 00068 m_iteration = 0; 00069 m_interval = 0; 00070 m_lastdraw = false; 00071 m_currentDraw = m_basegenerator->Draw(); 00072 } 00073 00074 00075 CValue* SCA_RandomSensor::GetReplica() 00076 { 00077 CValue* replica = new SCA_RandomSensor(*this); 00078 // this will copy properties and so on... 00079 replica->ProcessReplica(); 00080 00081 return replica; 00082 } 00083 00084 void SCA_RandomSensor::ProcessReplica() 00085 { 00086 SCA_ISensor::ProcessReplica(); 00087 // increment reference count so that we can release the generator at this end 00088 m_basegenerator->AddRef(); 00089 } 00090 00091 00092 bool SCA_RandomSensor::IsPositiveTrigger() 00093 { 00094 return (m_invert !=m_lastdraw); 00095 } 00096 00097 00098 bool SCA_RandomSensor::Evaluate() 00099 { 00100 /* Random generator is the generator from Line 25 of Table 1 in */ 00101 /* [KNUTH 1981, The Art of Computer Programming Vol. 2 */ 00102 /* (2nd Ed.), pp102] */ 00103 /* It's a very simple max. length sequence generator. We can */ 00104 /* draw 32 bool values before having to generate the next */ 00105 /* sequence value. There are some theorems that will tell you */ 00106 /* this is a reasonable way of generating bools. Check Knuth. */ 00107 /* Furthermore, we only draw each <delay>-eth frame. */ 00108 00109 bool evaluateResult = false; 00110 00111 if (++m_interval > m_pulse_frequency) { 00112 bool drawResult = false; 00113 m_interval = 0; 00114 if (m_iteration > 31) { 00115 m_currentDraw = m_basegenerator->Draw(); 00116 drawResult = (m_currentDraw & 0x1) == 0; 00117 m_iteration = 1; 00118 } else { 00119 drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0; 00120 m_iteration++; 00121 } 00122 evaluateResult = drawResult != m_lastdraw; 00123 m_lastdraw = drawResult; 00124 } 00125 00126 /* now pass this result to some controller */ 00127 return evaluateResult; 00128 } 00129 00130 #ifdef WITH_PYTHON 00131 00132 /* ------------------------------------------------------------------------- */ 00133 /* Python functions */ 00134 /* ------------------------------------------------------------------------- */ 00135 00136 /* Integration hooks ------------------------------------------------------- */ 00137 PyTypeObject SCA_RandomSensor::Type = { 00138 PyVarObject_HEAD_INIT(NULL, 0) 00139 "SCA_RandomSensor", 00140 sizeof(PyObjectPlus_Proxy), 00141 0, 00142 py_base_dealloc, 00143 0, 00144 0, 00145 0, 00146 0, 00147 py_base_repr, 00148 0,0,0,0,0,0,0,0,0, 00149 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 00150 0,0,0,0,0,0,0, 00151 Methods, 00152 0, 00153 0, 00154 &SCA_ISensor::Type, 00155 0,0,0,0,0,0, 00156 py_base_new 00157 }; 00158 00159 PyMethodDef SCA_RandomSensor::Methods[] = { 00160 {NULL,NULL} //Sentinel 00161 }; 00162 00163 PyAttributeDef SCA_RandomSensor::Attributes[] = { 00164 KX_PYATTRIBUTE_BOOL_RO("lastDraw",SCA_RandomSensor,m_lastdraw), 00165 KX_PYATTRIBUTE_RW_FUNCTION("seed", SCA_RandomSensor, pyattr_get_seed, pyattr_set_seed), 00166 {NULL} //Sentinel 00167 }; 00168 00169 PyObject* SCA_RandomSensor::pyattr_get_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00170 { 00171 SCA_RandomSensor* self= static_cast<SCA_RandomSensor*>(self_v); 00172 return PyLong_FromSsize_t(self->m_basegenerator->GetSeed()); 00173 } 00174 00175 int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) 00176 { 00177 SCA_RandomSensor* self= static_cast<SCA_RandomSensor*>(self_v); 00178 if (!PyLong_Check(value)) { 00179 PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer"); 00180 return PY_SET_ATTR_FAIL; 00181 } 00182 self->m_basegenerator->SetSeed(PyLong_AsSsize_t(value)); 00183 return PY_SET_ATTR_SUCCESS; 00184 } 00185 00186 #endif // WITH_PYTHON 00187 00188 /* eof */