bleh
This commit is contained in:
@@ -1,578 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* Blender's Ketsji startpoint
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32
|
||||
// don't show stl-warnings
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "KX_BlenderGL.h"
|
||||
#include "KX_BlenderCanvas.h"
|
||||
#include "KX_BlenderKeyboardDevice.h"
|
||||
#include "KX_BlenderMouseDevice.h"
|
||||
#include "KX_BlenderRenderTools.h"
|
||||
#include "KX_BlenderSystem.h"
|
||||
#include "BL_Material.h"
|
||||
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
#include "KX_PythonInit.h"
|
||||
#include "KX_PyConstraintBinding.h"
|
||||
|
||||
#include "RAS_GLExtensionManager.h"
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
#include "RAS_VAOpenGLRasterizer.h"
|
||||
#include "RAS_ListRasterizer.h"
|
||||
|
||||
#include "NG_LoopBackNetworkDeviceInterface.h"
|
||||
|
||||
#include "SYS_System.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
#include "Value.h"
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/***/
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
//XXX #include "BIF_screen.h"
|
||||
//XXX #include "BIF_scrarea.h"
|
||||
|
||||
#include "BKE_main.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLO_readfile.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "BKE_ipo.h"
|
||||
/***/
|
||||
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
//XXX #include "BSE_headerbuttons.h"
|
||||
#include "BKE_context.h"
|
||||
#include "../../blender/windowmanager/WM_types.h"
|
||||
#include "../../blender/windowmanager/wm_window.h"
|
||||
#include "../../blender/windowmanager/wm_event_system.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static BlendFileData *load_game_data(char *filename)
|
||||
{
|
||||
ReportList reports;
|
||||
BlendFileData *bfd;
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
bfd= BLO_read_from_file(filename, &reports);
|
||||
|
||||
if (!bfd) {
|
||||
printf("Loading %s failed: ", filename);
|
||||
BKE_reports_print(&reports, RPT_ERROR);
|
||||
}
|
||||
|
||||
BKE_reports_clear(&reports);
|
||||
|
||||
return bfd;
|
||||
}
|
||||
|
||||
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
|
||||
{
|
||||
/* context values */
|
||||
struct wmWindow *win= CTX_wm_window(C);
|
||||
struct Scene *startscene= CTX_data_scene(C);
|
||||
struct Main* maggie1= CTX_data_main(C);
|
||||
|
||||
|
||||
RAS_Rect area_rect;
|
||||
area_rect.SetLeft(cam_frame->xmin);
|
||||
area_rect.SetBottom(cam_frame->ymin);
|
||||
area_rect.SetRight(cam_frame->xmax);
|
||||
area_rect.SetTop(cam_frame->ymax);
|
||||
|
||||
int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
|
||||
Main* blenderdata = maggie1;
|
||||
|
||||
char* startscenename = startscene->id.name+2;
|
||||
char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE];
|
||||
STR_String exitstring = "";
|
||||
BlendFileData *bfd= NULL;
|
||||
|
||||
BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
|
||||
BLI_strncpy(oldsce, G.sce, sizeof(oldsce));
|
||||
#ifndef DISABLE_PYTHON
|
||||
resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
|
||||
setGamePythonPath(G.sce);
|
||||
|
||||
// Acquire Python's GIL (global interpreter lock)
|
||||
// so we can safely run Python code and API calls
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
|
||||
#endif
|
||||
|
||||
bgl::InitExtensions(true);
|
||||
|
||||
do
|
||||
{
|
||||
View3D *v3d= CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
||||
|
||||
// get some preferences
|
||||
SYS_SystemHandle syshandle = SYS_GetSystem();
|
||||
bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
|
||||
bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
|
||||
bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
|
||||
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
|
||||
bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0);
|
||||
bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
|
||||
#ifndef DISABLE_PYTHON
|
||||
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
|
||||
#endif
|
||||
bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
|
||||
if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */
|
||||
|
||||
// create the canvas, rasterizer and rendertools
|
||||
RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar);
|
||||
canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
|
||||
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
|
||||
RAS_IRasterizer* rasterizer = NULL;
|
||||
|
||||
if(displaylists) {
|
||||
if (GLEW_VERSION_1_1 && !novertexarrays)
|
||||
rasterizer = new RAS_ListRasterizer(canvas, true, true);
|
||||
else
|
||||
rasterizer = new RAS_ListRasterizer(canvas);
|
||||
}
|
||||
else if (GLEW_VERSION_1_1 && !novertexarrays)
|
||||
rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
|
||||
else
|
||||
rasterizer = new RAS_OpenGLRasterizer(canvas);
|
||||
|
||||
// create the inputdevices
|
||||
KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
|
||||
KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
|
||||
|
||||
// create a networkdevice
|
||||
NG_NetworkDeviceInterface* networkdevice = new
|
||||
NG_LoopBackNetworkDeviceInterface();
|
||||
|
||||
//
|
||||
// create a ketsji/blendersystem (only needed for timing and stuff)
|
||||
KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
|
||||
|
||||
// create the ketsjiengine
|
||||
KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
|
||||
|
||||
// set the devices
|
||||
ketsjiengine->SetKeyboardDevice(keyboarddevice);
|
||||
ketsjiengine->SetMouseDevice(mousedevice);
|
||||
ketsjiengine->SetNetworkDevice(networkdevice);
|
||||
ketsjiengine->SetCanvas(canvas);
|
||||
ketsjiengine->SetRenderTools(rendertools);
|
||||
ketsjiengine->SetRasterizer(rasterizer);
|
||||
ketsjiengine->SetNetworkDevice(networkdevice);
|
||||
ketsjiengine->SetUseFixedTime(usefixed);
|
||||
ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
CValue::SetDeprecationWarnings(nodepwarnings);
|
||||
#endif
|
||||
|
||||
//lock frame and camera enabled - storing global values
|
||||
int tmp_lay= startscene->lay;
|
||||
Object *tmp_camera = startscene->camera;
|
||||
|
||||
if (v3d->scenelock==0){
|
||||
startscene->lay= v3d->lay;
|
||||
startscene->camera= v3d->camera;
|
||||
}
|
||||
|
||||
// some blender stuff
|
||||
MT_CmMatrix4x4 projmat;
|
||||
MT_CmMatrix4x4 viewmat;
|
||||
float camzoom;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
float *viewmat_linear= (float*) rv3d->viewmat;
|
||||
viewmat.setElem(i, viewmat_linear[i]);
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
float *projmat_linear= (float*) rv3d->winmat;
|
||||
projmat.setElem(i, projmat_linear[i]);
|
||||
}
|
||||
|
||||
if(rv3d->persp==RV3D_CAMOB) {
|
||||
if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
|
||||
camzoom = 1.0f;
|
||||
}
|
||||
else {
|
||||
camzoom = (1.41421 + (rv3d->camzoom / 50.0));
|
||||
camzoom *= camzoom;
|
||||
camzoom = 4.0 / camzoom;
|
||||
}
|
||||
}
|
||||
else {
|
||||
camzoom = 2.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ketsjiengine->SetDrawType(v3d->drawtype);
|
||||
ketsjiengine->SetCameraZoom(camzoom);
|
||||
|
||||
// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
|
||||
if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
|
||||
{
|
||||
exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
|
||||
if (bfd) BLO_blendfiledata_free(bfd);
|
||||
|
||||
char basedpath[240];
|
||||
// base the actuator filename with respect
|
||||
// to the original file working directory
|
||||
|
||||
if (exitstring != "")
|
||||
strcpy(basedpath, exitstring.Ptr());
|
||||
|
||||
// load relative to the last loaded file, this used to be relative
|
||||
// to the first file but that makes no sense, relative paths in
|
||||
// blend files should be relative to that file, not some other file
|
||||
// that happened to be loaded first
|
||||
BLI_path_abs(basedpath, pathname);
|
||||
bfd = load_game_data(basedpath);
|
||||
|
||||
// if it wasn't loaded, try it forced relative
|
||||
if (!bfd)
|
||||
{
|
||||
// just add "//" in front of it
|
||||
char temppath[242];
|
||||
strcpy(temppath, "//");
|
||||
strcat(temppath, basedpath);
|
||||
|
||||
BLI_path_abs(temppath, pathname);
|
||||
bfd = load_game_data(temppath);
|
||||
}
|
||||
|
||||
// if we got a loaded blendfile, proceed
|
||||
if (bfd)
|
||||
{
|
||||
blenderdata = bfd->main;
|
||||
startscenename = bfd->curscene->id.name + 2;
|
||||
|
||||
if(blenderdata) {
|
||||
BLI_strncpy(G.sce, blenderdata->name, sizeof(G.sce));
|
||||
BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
|
||||
#ifndef DISABLE_PYTHON
|
||||
setGamePythonPath(G.sce);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// else forget it, we can't find it
|
||||
else
|
||||
{
|
||||
exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
|
||||
}
|
||||
}
|
||||
|
||||
Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2);
|
||||
|
||||
if (scene)
|
||||
{
|
||||
int startFrame = scene->r.cfra;
|
||||
ketsjiengine->SetAnimRecordMode(animation_record, startFrame);
|
||||
|
||||
// Quad buffered needs a special window.
|
||||
if(scene->gm.stereoflag == STEREO_ENABLED){
|
||||
if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
|
||||
rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode);
|
||||
|
||||
rasterizer->SetEyeSeparation(scene->gm.eyeseparation);
|
||||
}
|
||||
|
||||
rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f);
|
||||
}
|
||||
|
||||
if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
|
||||
{
|
||||
if (rv3d->persp != RV3D_CAMOB)
|
||||
{
|
||||
ketsjiengine->EnableCameraOverride(startscenename);
|
||||
ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO));
|
||||
ketsjiengine->SetCameraOverrideProjectionMatrix(projmat);
|
||||
ketsjiengine->SetCameraOverrideViewMatrix(viewmat);
|
||||
ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
|
||||
ketsjiengine->SetCameraOverrideLens(v3d->lens);
|
||||
}
|
||||
|
||||
// create a scene converter, create and convert the startingscene
|
||||
KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
|
||||
ketsjiengine->SetSceneConverter(sceneconverter);
|
||||
sceneconverter->addInitFromFrame=false;
|
||||
if (always_use_expand_framing)
|
||||
sceneconverter->SetAlwaysUseExpandFraming(true);
|
||||
|
||||
bool usemat = false, useglslmat = false;
|
||||
|
||||
if(GLEW_ARB_multitexture && GLEW_VERSION_1_1)
|
||||
usemat = true;
|
||||
|
||||
if(GPU_glsl_support())
|
||||
useglslmat = true;
|
||||
else if(scene->gm.matmode == GAME_MAT_GLSL)
|
||||
usemat = false;
|
||||
|
||||
if(usemat && (scene->gm.matmode != GAME_MAT_TEXFACE))
|
||||
sceneconverter->SetMaterials(true);
|
||||
if(useglslmat && (scene->gm.matmode == GAME_MAT_GLSL))
|
||||
sceneconverter->SetGLSLMaterials(true);
|
||||
|
||||
KX_Scene* startscene = new KX_Scene(keyboarddevice,
|
||||
mousedevice,
|
||||
networkdevice,
|
||||
startscenename,
|
||||
scene,
|
||||
canvas);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
// some python things
|
||||
PyObject *gameLogic, *gameLogic_keys;
|
||||
setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL);
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
//initialize Dome Settings
|
||||
if(scene->gm.stereoflag == STEREO_DOME)
|
||||
ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext);
|
||||
|
||||
// initialize 3D Audio Settings
|
||||
//BMESH_TODO merge issue!
|
||||
// AUD_setSpeedOfSound(scene->audio.speed_of_sound);
|
||||
// AUD_setDopplerFactor(scene->audio.doppler_factor);
|
||||
// AUD_setDistanceModel(AUD_DistanceModel(scene->audio.distance_model));
|
||||
|
||||
// from see blender.c:
|
||||
// FIXME: this version patching should really be part of the file-reading code,
|
||||
// but we still get too many unrelated data-corruption crashes otherwise...
|
||||
if (blenderdata->versionfile < 250)
|
||||
do_versions_ipos_to_animato(blenderdata);
|
||||
|
||||
if (sceneconverter)
|
||||
{
|
||||
// convert and add scene
|
||||
sceneconverter->ConvertScene(
|
||||
startscene,
|
||||
rendertools,
|
||||
canvas);
|
||||
ketsjiengine->AddScene(startscene);
|
||||
|
||||
// init the rasterizer
|
||||
rasterizer->Init();
|
||||
|
||||
// start the engine
|
||||
ketsjiengine->StartEngine(true);
|
||||
|
||||
|
||||
// Set the animation playback rate for ipo's and actions
|
||||
// the framerate below should patch with FPS macro defined in blendef.h
|
||||
// Could be in StartEngine set the framerate, we need the scene to do this
|
||||
ketsjiengine->SetAnimFrameRate(FPS);
|
||||
|
||||
// the mainloop
|
||||
printf("\nBlender Game Engine Started\n\n");
|
||||
while (!exitrequested)
|
||||
{
|
||||
// first check if we want to exit
|
||||
exitrequested = ketsjiengine->GetExitCode();
|
||||
|
||||
// kick the engine
|
||||
bool render = ketsjiengine->NextFrame(); // XXX 2.5 Bug, This is never true! FIXME- Campbell
|
||||
|
||||
if (render)
|
||||
{
|
||||
// render the frame
|
||||
ketsjiengine->Render();
|
||||
}
|
||||
|
||||
wm_window_process_events_nosleep(C);
|
||||
|
||||
// test for the ESC key
|
||||
//XXX while (qtest())
|
||||
while(wmEvent *event= (wmEvent *)win->queue.first)
|
||||
{
|
||||
short val = 0;
|
||||
//unsigned short event = 0; //XXX extern_qread(&val);
|
||||
|
||||
if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
|
||||
exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
|
||||
|
||||
/* Coordinate conversion... where
|
||||
* should this really be?
|
||||
*/
|
||||
if (event->type==MOUSEMOVE) {
|
||||
/* Note, not nice! XXX 2.5 event hack */
|
||||
val = event->x - ar->winrct.xmin;
|
||||
mousedevice->ConvertBlenderEvent(MOUSEX, val);
|
||||
|
||||
val = ar->winy - (event->y - ar->winrct.ymin) - 1;
|
||||
mousedevice->ConvertBlenderEvent(MOUSEY, val);
|
||||
}
|
||||
else {
|
||||
mousedevice->ConvertBlenderEvent(event->type,event->val);
|
||||
}
|
||||
|
||||
BLI_remlink(&win->queue, event);
|
||||
wm_event_free(event);
|
||||
}
|
||||
|
||||
}
|
||||
printf("\nBlender Game Engine Finished\n\n");
|
||||
exitstring = ketsjiengine->GetExitString();
|
||||
|
||||
|
||||
// when exiting the mainloop
|
||||
#ifndef DISABLE_PYTHON
|
||||
// Clears the dictionary by hand:
|
||||
// This prevents, extra references to global variables
|
||||
// inside the GameLogic dictionary when the python interpreter is finalized.
|
||||
// which allows the scene to safely delete them :)
|
||||
// see: (space.c)->start_game
|
||||
|
||||
//PyDict_Clear(PyModule_GetDict(gameLogic));
|
||||
|
||||
// Keep original items, means python plugins will autocomplete members
|
||||
int listIndex;
|
||||
PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
|
||||
for (listIndex=0; listIndex < PyList_Size(gameLogic_keys_new); listIndex++) {
|
||||
PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex);
|
||||
if (!PySequence_Contains(gameLogic_keys, item)) {
|
||||
PyDict_DelItem( PyModule_GetDict(gameLogic), item);
|
||||
}
|
||||
}
|
||||
Py_DECREF(gameLogic_keys_new);
|
||||
gameLogic_keys_new = NULL;
|
||||
#endif
|
||||
ketsjiengine->StopEngine();
|
||||
#ifndef DISABLE_PYTHON
|
||||
exitGamePythonScripting();
|
||||
#endif
|
||||
networkdevice->Disconnect();
|
||||
}
|
||||
if (sceneconverter)
|
||||
{
|
||||
delete sceneconverter;
|
||||
sceneconverter = NULL;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
Py_DECREF(gameLogic_keys);
|
||||
gameLogic_keys = NULL;
|
||||
#endif
|
||||
}
|
||||
//lock frame and camera enabled - restoring global values
|
||||
if (v3d->scenelock==0){
|
||||
startscene->lay= tmp_lay;
|
||||
startscene->camera= tmp_camera;
|
||||
}
|
||||
|
||||
// set the cursor back to normal
|
||||
canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
|
||||
|
||||
// clean up some stuff
|
||||
if (ketsjiengine)
|
||||
{
|
||||
delete ketsjiengine;
|
||||
ketsjiengine = NULL;
|
||||
}
|
||||
if (kxsystem)
|
||||
{
|
||||
delete kxsystem;
|
||||
kxsystem = NULL;
|
||||
}
|
||||
if (networkdevice)
|
||||
{
|
||||
delete networkdevice;
|
||||
networkdevice = NULL;
|
||||
}
|
||||
if (keyboarddevice)
|
||||
{
|
||||
delete keyboarddevice;
|
||||
keyboarddevice = NULL;
|
||||
}
|
||||
if (mousedevice)
|
||||
{
|
||||
delete mousedevice;
|
||||
mousedevice = NULL;
|
||||
}
|
||||
if (rasterizer)
|
||||
{
|
||||
delete rasterizer;
|
||||
rasterizer = NULL;
|
||||
}
|
||||
if (rendertools)
|
||||
{
|
||||
delete rendertools;
|
||||
rendertools = NULL;
|
||||
}
|
||||
if (canvas)
|
||||
{
|
||||
delete canvas;
|
||||
canvas = NULL;
|
||||
}
|
||||
|
||||
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
|
||||
|
||||
if (bfd) BLO_blendfiledata_free(bfd);
|
||||
|
||||
BLI_strncpy(G.sce, oldsce, sizeof(G.sce));
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
Py_DECREF(pyGlobalDict);
|
||||
|
||||
// Release Python's GIL
|
||||
PyGILState_Release(gilstate);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
SET(INC
|
||||
.
|
||||
../../../source/kernel/gen_system
|
||||
../../../intern/string
|
||||
../../../intern/guardedalloc
|
||||
../../../intern/audaspace/intern
|
||||
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
|
||||
../../../source/gameengine/Converter
|
||||
../../../source/blender/imbuf
|
||||
../../../intern/ghost/include
|
||||
../../../intern/moto/include
|
||||
../../../source/gameengine/Ketsji
|
||||
../../../source/blender/blenlib
|
||||
../../../source/blender/blenkernel
|
||||
../../../source/blender/blenfont
|
||||
../../../source/blender/editors/include
|
||||
../../../source/blender/windowmanager
|
||||
../../../source/blender
|
||||
../../../source/blender/include
|
||||
../../../source/blender/makesdna
|
||||
../../../source/blender/makesrna
|
||||
../../../source/gameengine/Rasterizer
|
||||
../../../source/gameengine/GameLogic
|
||||
../../../source/gameengine/Expressions
|
||||
../../../source/gameengine/Network
|
||||
../../../source/gameengine/SceneGraph
|
||||
../../../source/gameengine/Physics/common
|
||||
../../../source/gameengine/Physics/Bullet
|
||||
../../../source/gameengine/Network/LoopBackNetwork
|
||||
../../../source/blender/misc
|
||||
../../../source/blender/blenloader
|
||||
../../../source/blender/gpu
|
||||
../../../extern/bullet2/src
|
||||
../../../extern/glew/include
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DGLEW_STATIC)
|
||||
|
||||
IF(WITH_FFMPEG)
|
||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||
ENDIF(WITH_FFMPEG)
|
||||
|
||||
IF(WITH_PYTHON)
|
||||
SET(INC ${INC} ${PYTHON_INC})
|
||||
ELSE(WITH_PYTHON)
|
||||
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
||||
ENDIF(WITH_PYTHON)
|
||||
|
||||
BLENDERLIB(bf_blroutines "${SRC}" "${INC}")
|
||||
@@ -1,207 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_BlenderCanvas.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) :
|
||||
m_win(win),
|
||||
m_frame_rect(rect)
|
||||
{
|
||||
// area boundaries needed for mouse coordinates in Letterbox framing mode
|
||||
m_area_left = ar->winrct.xmin;
|
||||
m_area_top = ar->winrct.ymax;
|
||||
}
|
||||
|
||||
KX_BlenderCanvas::~KX_BlenderCanvas()
|
||||
{
|
||||
}
|
||||
|
||||
void KX_BlenderCanvas::Init()
|
||||
{
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderCanvas::SwapBuffers()
|
||||
{
|
||||
BL_SwapBuffers(m_win);
|
||||
}
|
||||
|
||||
void KX_BlenderCanvas::BeginFrame()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderCanvas::EndFrame()
|
||||
{
|
||||
// this is needed, else blender distorts a lot
|
||||
glPopAttrib();
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_BlenderCanvas::ClearColor(float r,float g,float b,float a)
|
||||
{
|
||||
glClearColor(r,g,b,a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_BlenderCanvas::ClearBuffer(int type)
|
||||
{
|
||||
int ogltype = 0;
|
||||
|
||||
if (type & RAS_ICanvas::COLOR_BUFFER )
|
||||
ogltype |= GL_COLOR_BUFFER_BIT;
|
||||
|
||||
if (type & RAS_ICanvas::DEPTH_BUFFER )
|
||||
ogltype |= GL_DEPTH_BUFFER_BIT;
|
||||
glClear(ogltype);
|
||||
}
|
||||
|
||||
int KX_BlenderCanvas::GetWidth(
|
||||
) const {
|
||||
return m_frame_rect.GetWidth();
|
||||
}
|
||||
|
||||
int KX_BlenderCanvas::GetHeight(
|
||||
) const {
|
||||
return m_frame_rect.GetHeight();
|
||||
}
|
||||
|
||||
int KX_BlenderCanvas::GetMouseX(int x)
|
||||
{
|
||||
float left = GetWindowArea().GetLeft();
|
||||
return float(x - (left - m_area_left));
|
||||
}
|
||||
|
||||
int KX_BlenderCanvas::GetMouseY(int y)
|
||||
{
|
||||
float top = GetWindowArea().GetTop();
|
||||
return float(y - (m_area_top - top));
|
||||
}
|
||||
|
||||
float KX_BlenderCanvas::GetMouseNormalizedX(int x)
|
||||
{
|
||||
int can_x = GetMouseX(x);
|
||||
return float(can_x)/this->GetWidth();
|
||||
}
|
||||
|
||||
float KX_BlenderCanvas::GetMouseNormalizedY(int y)
|
||||
{
|
||||
int can_y = GetMouseY(y);
|
||||
return float(can_y)/this->GetHeight();
|
||||
}
|
||||
|
||||
RAS_Rect &
|
||||
KX_BlenderCanvas::
|
||||
GetWindowArea(
|
||||
){
|
||||
return m_area_rect;
|
||||
}
|
||||
|
||||
void
|
||||
KX_BlenderCanvas::
|
||||
SetViewPort(
|
||||
int x1, int y1,
|
||||
int x2, int y2
|
||||
){
|
||||
/* x1 and y1 are the min pixel coordinate (e.g. 0)
|
||||
x2 and y2 are the max pixel coordinate
|
||||
the width,height is calculated including both pixels
|
||||
therefore: max - min + 1
|
||||
*/
|
||||
int vp_width = (x2 - x1) + 1;
|
||||
int vp_height = (y2 - y1) + 1;
|
||||
int minx = m_frame_rect.GetLeft();
|
||||
int miny = m_frame_rect.GetBottom();
|
||||
|
||||
m_area_rect.SetLeft(minx + x1);
|
||||
m_area_rect.SetBottom(miny + y1);
|
||||
m_area_rect.SetRight(minx + x2);
|
||||
m_area_rect.SetTop(miny + y2);
|
||||
|
||||
glViewport(minx + x1, miny + y1, vp_width, vp_height);
|
||||
glScissor(minx + x1, miny + y1, vp_width, vp_height);
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderCanvas::SetMouseState(RAS_MouseState mousestate)
|
||||
{
|
||||
m_mousestate = mousestate;
|
||||
|
||||
switch (mousestate)
|
||||
{
|
||||
case MOUSE_INVISIBLE:
|
||||
{
|
||||
BL_HideMouse(m_win);
|
||||
break;
|
||||
}
|
||||
case MOUSE_WAIT:
|
||||
{
|
||||
BL_WaitMouse(m_win);
|
||||
break;
|
||||
}
|
||||
case MOUSE_NORMAL:
|
||||
{
|
||||
BL_NormalMouse(m_win);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// (0,0) is top left, (width,height) is bottom right
|
||||
void KX_BlenderCanvas::SetMousePosition(int x,int y)
|
||||
{
|
||||
int winX = m_frame_rect.GetLeft();
|
||||
int winY = m_frame_rect.GetBottom();
|
||||
int winH = m_frame_rect.GetHeight();
|
||||
|
||||
BL_warp_pointer(m_win, winX + x, winY + (winH-y));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_BlenderCanvas::MakeScreenShot(const char* filename)
|
||||
{
|
||||
// BL_MakeScreenShot(m_ar, filename);
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERCANVAS
|
||||
#define __KX_BLENDERCANVAS
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "RAS_ICanvas.h"
|
||||
#include "RAS_Rect.h"
|
||||
|
||||
#include "KX_BlenderGL.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
struct ARegion;
|
||||
struct wmWindow;
|
||||
|
||||
/**
|
||||
* 2D Blender device context abstraction.
|
||||
* The connection from 3d rendercontext to 2d Blender surface embedding.
|
||||
*/
|
||||
|
||||
class KX_BlenderCanvas : public RAS_ICanvas
|
||||
{
|
||||
private:
|
||||
/** Rect that defines the area used for rendering,
|
||||
relative to the context */
|
||||
RAS_Rect m_displayarea;
|
||||
|
||||
public:
|
||||
/* Construct a new canvas.
|
||||
*
|
||||
* @param area The Blender ARegion to run the game within.
|
||||
*/
|
||||
KX_BlenderCanvas(struct wmWindow* win, class RAS_Rect &rect, struct ARegion* ar);
|
||||
~KX_BlenderCanvas();
|
||||
|
||||
void
|
||||
Init(
|
||||
);
|
||||
|
||||
void
|
||||
SwapBuffers(
|
||||
);
|
||||
void
|
||||
Resize(
|
||||
int width,
|
||||
int height
|
||||
);
|
||||
|
||||
void
|
||||
BeginFrame(
|
||||
);
|
||||
|
||||
void
|
||||
EndFrame(
|
||||
);
|
||||
|
||||
void
|
||||
ClearColor(
|
||||
float r,
|
||||
float g,
|
||||
float b,
|
||||
float a
|
||||
);
|
||||
|
||||
void
|
||||
ClearBuffer(
|
||||
int type
|
||||
);
|
||||
|
||||
int
|
||||
GetWidth(
|
||||
) const ;
|
||||
|
||||
int
|
||||
GetHeight(
|
||||
) const ;
|
||||
|
||||
int
|
||||
GetMouseX(int x
|
||||
);
|
||||
|
||||
int
|
||||
GetMouseY(int y
|
||||
);
|
||||
|
||||
float
|
||||
GetMouseNormalizedX(int x
|
||||
);
|
||||
|
||||
float
|
||||
GetMouseNormalizedY(int y
|
||||
);
|
||||
|
||||
const
|
||||
RAS_Rect &
|
||||
GetDisplayArea(
|
||||
) const {
|
||||
return m_displayarea;
|
||||
};
|
||||
|
||||
void
|
||||
SetDisplayArea(RAS_Rect *rect
|
||||
) {
|
||||
m_displayarea= *rect;
|
||||
};
|
||||
|
||||
RAS_Rect &
|
||||
GetWindowArea(
|
||||
);
|
||||
|
||||
void
|
||||
SetViewPort(
|
||||
int x1, int y1,
|
||||
int x2, int y2
|
||||
);
|
||||
|
||||
void
|
||||
SetMouseState(
|
||||
RAS_MouseState mousestate
|
||||
);
|
||||
|
||||
void
|
||||
SetMousePosition(
|
||||
int x,
|
||||
int y
|
||||
);
|
||||
|
||||
void
|
||||
MakeScreenShot(
|
||||
const char* filename
|
||||
);
|
||||
|
||||
/**
|
||||
* Nothing needs be done for BlenderCanvas
|
||||
* Begin/End Draw, as the game engine GL context
|
||||
* is always current/active.
|
||||
*/
|
||||
|
||||
bool
|
||||
BeginDraw(
|
||||
) {
|
||||
return true;
|
||||
};
|
||||
|
||||
void
|
||||
EndDraw(
|
||||
) {
|
||||
};
|
||||
|
||||
private:
|
||||
/** Blender area the game engine is running within */
|
||||
struct wmWindow* m_win;
|
||||
RAS_Rect m_frame_rect;
|
||||
RAS_Rect m_area_rect;
|
||||
short m_area_left;
|
||||
short m_area_top;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderCanvas"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __KX_BLENDERCANVAS
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_BlenderGL.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "BLF_api.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This little block needed for linking to Blender...
|
||||
*/
|
||||
#ifdef WIN32
|
||||
#include <vector>
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "BL_Material.h" // MAXTEX
|
||||
|
||||
/* Data types encoding the game world: */
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_bmfont.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
extern "C" {
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
#include "wm_event_system.h"
|
||||
#include "wm_cursors.h"
|
||||
#include "wm_window.h"
|
||||
}
|
||||
|
||||
/* end of blender block */
|
||||
|
||||
/* was in drawmesh.c */
|
||||
void spack(unsigned int ucol)
|
||||
{
|
||||
char *cp= (char *)&ucol;
|
||||
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
}
|
||||
|
||||
void BL_warp_pointer(wmWindow *win, int x,int y)
|
||||
{
|
||||
WM_cursor_warp(win, x, y);
|
||||
}
|
||||
|
||||
void BL_SwapBuffers(wmWindow *win)
|
||||
{
|
||||
wm_window_swap_buffers(win);
|
||||
}
|
||||
|
||||
void DisableForText()
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */
|
||||
|
||||
if(glIsEnabled(GL_BLEND)) glDisable(GL_BLEND);
|
||||
if(glIsEnabled(GL_ALPHA_TEST)) glDisable(GL_ALPHA_TEST);
|
||||
|
||||
if(glIsEnabled(GL_LIGHTING)) {
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
if(GLEW_ARB_multitexture) {
|
||||
for(int i=0; i<MAXTEX; i++) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB+i);
|
||||
|
||||
if(GLEW_ARB_texture_cube_map)
|
||||
if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
|
||||
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
|
||||
if(glIsEnabled(GL_TEXTURE_2D))
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
else {
|
||||
if(GLEW_ARB_texture_cube_map)
|
||||
if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
|
||||
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
|
||||
if(glIsEnabled(GL_TEXTURE_2D))
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height)
|
||||
{
|
||||
/* gl prepping */
|
||||
DisableForText();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0, width, 0, height, -100, 100);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
/* the actual drawing */
|
||||
glColor3ub(255, 255, 255);
|
||||
BLF_draw_default(xco, height-yco, 0.0f, (char *)text);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height)
|
||||
{
|
||||
/* This is a rather important line :( The gl-mode hasn't been left
|
||||
* behind quite as neatly as we'd have wanted to. I don't know
|
||||
* what cause it, though :/ .*/
|
||||
DisableForText();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0, width, 0, height, -100, 100);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
/* draw in black first*/
|
||||
glColor3ub(0, 0, 0);
|
||||
BLF_draw_default(xco+2, height-yco-2, 0.0f, (char *)text);
|
||||
glColor3ub(255, 255, 255);
|
||||
BLF_draw_default(xco, height-yco, 0.0f, (char *)text);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void BL_HideMouse(wmWindow *win)
|
||||
{
|
||||
WM_cursor_set(win, CURSOR_NONE);
|
||||
}
|
||||
|
||||
|
||||
void BL_WaitMouse(wmWindow *win)
|
||||
{
|
||||
WM_cursor_set(win, CURSOR_WAIT);
|
||||
}
|
||||
|
||||
|
||||
void BL_NormalMouse(wmWindow *win)
|
||||
{
|
||||
WM_cursor_set(win, CURSOR_STD);
|
||||
}
|
||||
#define MAX_FILE_LENGTH 512
|
||||
|
||||
|
||||
void BL_MakeScreenShot(struct ARegion *ar, const char* filename)
|
||||
{
|
||||
char copyfilename[MAX_FILE_LENGTH];
|
||||
strcpy(copyfilename,filename);
|
||||
|
||||
// filename read - only
|
||||
|
||||
/* XXX will need to change at some point */
|
||||
//XXX BIF_screendump(0);
|
||||
|
||||
// write+read filename
|
||||
//XXX write_screendump((char*) copyfilename);
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BLENDERGL
|
||||
#define __BLENDERGL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
struct wmWindow;
|
||||
struct ARegion;
|
||||
|
||||
// special swapbuffers, that takes care of which area (viewport) needs to be swapped
|
||||
void BL_SwapBuffers(struct wmWindow *win);
|
||||
|
||||
void BL_warp_pointer(struct wmWindow *win,int x,int y);
|
||||
|
||||
void BL_MakeScreenShot(struct ARegion *ar, const char* filename);
|
||||
|
||||
void BL_HideMouse(struct wmWindow *win);
|
||||
void BL_NormalMouse(struct wmWindow *win);
|
||||
void BL_WaitMouse(struct wmWindow *win);
|
||||
|
||||
void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height);
|
||||
void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //__BLENDERGL
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#include "KX_BlenderInputDevice.h"
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERINPUTDEVICE
|
||||
#define __KX_BLENDERINPUTDEVICE
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable : 4786) // shut off 255 char limit debug template warning
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "wm_event_types.h"
|
||||
#include "WM_types.h"
|
||||
#include "SCA_IInputDevice.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
Base Class for Blender specific inputdevices. Blender specific inputdevices are used when the gameengine is running in embedded mode instead of standalone mode.
|
||||
*/
|
||||
class BL_BlenderInputDevice : public SCA_IInputDevice
|
||||
{
|
||||
// this map is Blender specific: a conversion between blender and ketsji enums
|
||||
std::map<int,KX_EnumInputs> m_reverseKeyTranslateTable;
|
||||
public:
|
||||
BL_BlenderInputDevice()
|
||||
{
|
||||
|
||||
/* The reverse table. In order to not confuse ourselves, we */
|
||||
/* immediately convert all events that come in to KX codes. */
|
||||
m_reverseKeyTranslateTable[LEFTMOUSE ] = KX_LEFTMOUSE ;
|
||||
m_reverseKeyTranslateTable[MIDDLEMOUSE ] = KX_MIDDLEMOUSE ;
|
||||
m_reverseKeyTranslateTable[RIGHTMOUSE ] = KX_RIGHTMOUSE ;
|
||||
m_reverseKeyTranslateTable[WHEELUPMOUSE ] = KX_WHEELUPMOUSE ;
|
||||
m_reverseKeyTranslateTable[WHEELDOWNMOUSE ] = KX_WHEELDOWNMOUSE ;
|
||||
m_reverseKeyTranslateTable[MOUSEX ] = KX_MOUSEX ;
|
||||
m_reverseKeyTranslateTable[MOUSEY ] = KX_MOUSEY ;
|
||||
|
||||
// TIMERS
|
||||
|
||||
m_reverseKeyTranslateTable[TIMER0 ] = KX_TIMER0 ;
|
||||
m_reverseKeyTranslateTable[TIMER1 ] = KX_TIMER1 ;
|
||||
m_reverseKeyTranslateTable[TIMER2 ] = KX_TIMER2 ;
|
||||
|
||||
// SYSTEM
|
||||
#if 0
|
||||
/* **** XXX **** */
|
||||
m_reverseKeyTranslateTable[KEYBD ] = KX_KEYBD ;
|
||||
m_reverseKeyTranslateTable[RAWKEYBD ] = KX_RAWKEYBD ;
|
||||
m_reverseKeyTranslateTable[REDRAW ] = KX_REDRAW ;
|
||||
m_reverseKeyTranslateTable[INPUTCHANGE ] = KX_INPUTCHANGE ;
|
||||
m_reverseKeyTranslateTable[QFULL ] = KX_QFULL ;
|
||||
m_reverseKeyTranslateTable[WINFREEZE ] = KX_WINFREEZE ;
|
||||
m_reverseKeyTranslateTable[WINTHAW ] = KX_WINTHAW ;
|
||||
m_reverseKeyTranslateTable[WINCLOSE ] = KX_WINCLOSE ;
|
||||
m_reverseKeyTranslateTable[WINQUIT ] = KX_WINQUIT ;
|
||||
m_reverseKeyTranslateTable[Q_FIRSTTIME ] = KX_Q_FIRSTTIME ;
|
||||
/* **** XXX **** */
|
||||
#endif
|
||||
// standard keyboard
|
||||
|
||||
m_reverseKeyTranslateTable[AKEY ] = KX_AKEY ;
|
||||
m_reverseKeyTranslateTable[BKEY ] = KX_BKEY ;
|
||||
m_reverseKeyTranslateTable[CKEY ] = KX_CKEY ;
|
||||
m_reverseKeyTranslateTable[DKEY ] = KX_DKEY ;
|
||||
m_reverseKeyTranslateTable[EKEY ] = KX_EKEY ;
|
||||
m_reverseKeyTranslateTable[FKEY ] = KX_FKEY ;
|
||||
m_reverseKeyTranslateTable[GKEY ] = KX_GKEY ;
|
||||
//XXX clean up
|
||||
#ifdef WIN32
|
||||
#define HKEY 'h'
|
||||
#endif
|
||||
m_reverseKeyTranslateTable[HKEY ] = KX_HKEY ;
|
||||
//XXX clean up
|
||||
#ifdef WIN32
|
||||
#undef HKEY
|
||||
#endif
|
||||
m_reverseKeyTranslateTable[IKEY ] = KX_IKEY ;
|
||||
m_reverseKeyTranslateTable[JKEY ] = KX_JKEY ;
|
||||
m_reverseKeyTranslateTable[KKEY ] = KX_KKEY ;
|
||||
m_reverseKeyTranslateTable[LKEY ] = KX_LKEY ;
|
||||
m_reverseKeyTranslateTable[MKEY ] = KX_MKEY ;
|
||||
m_reverseKeyTranslateTable[NKEY ] = KX_NKEY ;
|
||||
m_reverseKeyTranslateTable[OKEY ] = KX_OKEY ;
|
||||
m_reverseKeyTranslateTable[PKEY ] = KX_PKEY ;
|
||||
m_reverseKeyTranslateTable[QKEY ] = KX_QKEY ;
|
||||
m_reverseKeyTranslateTable[RKEY ] = KX_RKEY ;
|
||||
m_reverseKeyTranslateTable[SKEY ] = KX_SKEY ;
|
||||
m_reverseKeyTranslateTable[TKEY ] = KX_TKEY ;
|
||||
m_reverseKeyTranslateTable[UKEY ] = KX_UKEY ;
|
||||
m_reverseKeyTranslateTable[VKEY ] = KX_VKEY ;
|
||||
m_reverseKeyTranslateTable[WKEY ] = KX_WKEY ;
|
||||
m_reverseKeyTranslateTable[XKEY ] = KX_XKEY ;
|
||||
m_reverseKeyTranslateTable[YKEY ] = KX_YKEY ;
|
||||
m_reverseKeyTranslateTable[ZKEY ] = KX_ZKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[ZEROKEY ] = KX_ZEROKEY ;
|
||||
m_reverseKeyTranslateTable[ONEKEY ] = KX_ONEKEY ;
|
||||
m_reverseKeyTranslateTable[TWOKEY ] = KX_TWOKEY ;
|
||||
m_reverseKeyTranslateTable[THREEKEY ] = KX_THREEKEY ;
|
||||
m_reverseKeyTranslateTable[FOURKEY ] = KX_FOURKEY ;
|
||||
m_reverseKeyTranslateTable[FIVEKEY ] = KX_FIVEKEY ;
|
||||
m_reverseKeyTranslateTable[SIXKEY ] = KX_SIXKEY ;
|
||||
m_reverseKeyTranslateTable[SEVENKEY ] = KX_SEVENKEY ;
|
||||
m_reverseKeyTranslateTable[EIGHTKEY ] = KX_EIGHTKEY ;
|
||||
m_reverseKeyTranslateTable[NINEKEY ] = KX_NINEKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[CAPSLOCKKEY ] = KX_CAPSLOCKKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[LEFTCTRLKEY ] = KX_LEFTCTRLKEY ;
|
||||
m_reverseKeyTranslateTable[LEFTALTKEY ] = KX_LEFTALTKEY ;
|
||||
m_reverseKeyTranslateTable[RIGHTALTKEY ] = KX_RIGHTALTKEY ;
|
||||
m_reverseKeyTranslateTable[RIGHTCTRLKEY ] = KX_RIGHTCTRLKEY ;
|
||||
m_reverseKeyTranslateTable[RIGHTSHIFTKEY ] = KX_RIGHTSHIFTKEY ;
|
||||
m_reverseKeyTranslateTable[LEFTSHIFTKEY ] = KX_LEFTSHIFTKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[ESCKEY ] = KX_ESCKEY ;
|
||||
m_reverseKeyTranslateTable[TABKEY ] = KX_TABKEY ;
|
||||
m_reverseKeyTranslateTable[RETKEY ] = KX_RETKEY ;
|
||||
m_reverseKeyTranslateTable[SPACEKEY ] = KX_SPACEKEY ;
|
||||
m_reverseKeyTranslateTable[LINEFEEDKEY ] = KX_LINEFEEDKEY ;
|
||||
m_reverseKeyTranslateTable[BACKSPACEKEY ] = KX_BACKSPACEKEY ;
|
||||
m_reverseKeyTranslateTable[DELKEY ] = KX_DELKEY ;
|
||||
m_reverseKeyTranslateTable[SEMICOLONKEY ] = KX_SEMICOLONKEY ;
|
||||
m_reverseKeyTranslateTable[PERIODKEY ] = KX_PERIODKEY ;
|
||||
m_reverseKeyTranslateTable[COMMAKEY ] = KX_COMMAKEY ;
|
||||
m_reverseKeyTranslateTable[QUOTEKEY ] = KX_QUOTEKEY ;
|
||||
m_reverseKeyTranslateTable[ACCENTGRAVEKEY ] = KX_ACCENTGRAVEKEY ;
|
||||
m_reverseKeyTranslateTable[MINUSKEY ] = KX_MINUSKEY ;
|
||||
m_reverseKeyTranslateTable[SLASHKEY ] = KX_SLASHKEY ;
|
||||
m_reverseKeyTranslateTable[BACKSLASHKEY ] = KX_BACKSLASHKEY ;
|
||||
m_reverseKeyTranslateTable[EQUALKEY ] = KX_EQUALKEY ;
|
||||
m_reverseKeyTranslateTable[LEFTBRACKETKEY ] = KX_LEFTBRACKETKEY ;
|
||||
m_reverseKeyTranslateTable[RIGHTBRACKETKEY ] = KX_RIGHTBRACKETKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[LEFTARROWKEY ] = KX_LEFTARROWKEY ;
|
||||
m_reverseKeyTranslateTable[DOWNARROWKEY ] = KX_DOWNARROWKEY ;
|
||||
m_reverseKeyTranslateTable[RIGHTARROWKEY ] = KX_RIGHTARROWKEY ;
|
||||
m_reverseKeyTranslateTable[UPARROWKEY ] = KX_UPARROWKEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[PAD2 ] = KX_PAD2 ;
|
||||
m_reverseKeyTranslateTable[PAD4 ] = KX_PAD4 ;
|
||||
m_reverseKeyTranslateTable[PAD6 ] = KX_PAD6 ;
|
||||
m_reverseKeyTranslateTable[PAD8 ] = KX_PAD8 ;
|
||||
|
||||
m_reverseKeyTranslateTable[PAD1 ] = KX_PAD1 ;
|
||||
m_reverseKeyTranslateTable[PAD3 ] = KX_PAD3 ;
|
||||
m_reverseKeyTranslateTable[PAD5 ] = KX_PAD5 ;
|
||||
m_reverseKeyTranslateTable[PAD7 ] = KX_PAD7 ;
|
||||
m_reverseKeyTranslateTable[PAD9 ] = KX_PAD9 ;
|
||||
|
||||
m_reverseKeyTranslateTable[PADPERIOD ] = KX_PADPERIOD ;
|
||||
m_reverseKeyTranslateTable[PADSLASHKEY ] = KX_PADSLASHKEY ;
|
||||
m_reverseKeyTranslateTable[PADASTERKEY ] = KX_PADASTERKEY ;
|
||||
|
||||
|
||||
m_reverseKeyTranslateTable[PAD0 ] = KX_PAD0 ;
|
||||
m_reverseKeyTranslateTable[PADMINUS ] = KX_PADMINUS ;
|
||||
m_reverseKeyTranslateTable[PADENTER ] = KX_PADENTER ;
|
||||
m_reverseKeyTranslateTable[PADPLUSKEY ] = KX_PADPLUSKEY ;
|
||||
|
||||
|
||||
m_reverseKeyTranslateTable[F1KEY ] = KX_F1KEY ;
|
||||
m_reverseKeyTranslateTable[F2KEY ] = KX_F2KEY ;
|
||||
m_reverseKeyTranslateTable[F3KEY ] = KX_F3KEY ;
|
||||
m_reverseKeyTranslateTable[F4KEY ] = KX_F4KEY ;
|
||||
m_reverseKeyTranslateTable[F5KEY ] = KX_F5KEY ;
|
||||
m_reverseKeyTranslateTable[F6KEY ] = KX_F6KEY ;
|
||||
m_reverseKeyTranslateTable[F7KEY ] = KX_F7KEY ;
|
||||
m_reverseKeyTranslateTable[F8KEY ] = KX_F8KEY ;
|
||||
m_reverseKeyTranslateTable[F9KEY ] = KX_F9KEY ;
|
||||
m_reverseKeyTranslateTable[F10KEY ] = KX_F10KEY ;
|
||||
m_reverseKeyTranslateTable[F11KEY ] = KX_F11KEY ;
|
||||
m_reverseKeyTranslateTable[F12KEY ] = KX_F12KEY ;
|
||||
m_reverseKeyTranslateTable[F13KEY ] = KX_F13KEY ;
|
||||
m_reverseKeyTranslateTable[F14KEY ] = KX_F14KEY ;
|
||||
m_reverseKeyTranslateTable[F15KEY ] = KX_F15KEY ;
|
||||
m_reverseKeyTranslateTable[F16KEY ] = KX_F16KEY ;
|
||||
m_reverseKeyTranslateTable[F17KEY ] = KX_F17KEY ;
|
||||
m_reverseKeyTranslateTable[F18KEY ] = KX_F18KEY ;
|
||||
m_reverseKeyTranslateTable[F19KEY ] = KX_F19KEY ;
|
||||
|
||||
m_reverseKeyTranslateTable[PAUSEKEY ] = KX_PAUSEKEY ;
|
||||
m_reverseKeyTranslateTable[INSERTKEY ] = KX_INSERTKEY ;
|
||||
m_reverseKeyTranslateTable[HOMEKEY ] = KX_HOMEKEY ;
|
||||
m_reverseKeyTranslateTable[PAGEUPKEY ] = KX_PAGEUPKEY ;
|
||||
m_reverseKeyTranslateTable[PAGEDOWNKEY ] = KX_PAGEDOWNKEY ;
|
||||
m_reverseKeyTranslateTable[ENDKEY ] = KX_ENDKEY ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual ~BL_BlenderInputDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
KX_EnumInputs ToNative(unsigned short incode) {
|
||||
return m_reverseKeyTranslateTable[incode];
|
||||
}
|
||||
|
||||
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
|
||||
// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
|
||||
virtual bool ConvertBlenderEvent(unsigned short incode,short val)=0;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_BlenderInputDevice"); }
|
||||
void operator delete(void *mem) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
#endif //__KX_BLENDERINPUTDEVICE
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
// annoying warnings about truncated STL debug info
|
||||
#pragma warning (disable :4786)
|
||||
#endif
|
||||
|
||||
#include "KX_BlenderKeyboardDevice.h"
|
||||
|
||||
KX_BlenderKeyboardDevice::KX_BlenderKeyboardDevice()
|
||||
: m_hookesc(false)
|
||||
{
|
||||
|
||||
}
|
||||
KX_BlenderKeyboardDevice::~KX_BlenderKeyboardDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
IsPressed gives boolean information about keyboard status, true if pressed, false if not
|
||||
*/
|
||||
|
||||
bool KX_BlenderKeyboardDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
|
||||
{
|
||||
const SCA_InputEvent & inevent = m_eventStatusTables[m_currentTable][inputcode];
|
||||
bool pressed = (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
|
||||
inevent.m_status == SCA_InputEvent::KX_ACTIVE);
|
||||
return pressed;
|
||||
}
|
||||
/*const SCA_InputEvent& KX_BlenderKeyboardDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
|
||||
{
|
||||
return m_eventStatusTables[m_currentTable][inputcode];
|
||||
}
|
||||
*/
|
||||
/**
|
||||
NextFrame toggles currentTable with previousTable,
|
||||
and copy relevant event information from previous to current
|
||||
(pressed keys need to be remembered)
|
||||
*/
|
||||
void KX_BlenderKeyboardDevice::NextFrame()
|
||||
{
|
||||
SCA_IInputDevice::NextFrame();
|
||||
|
||||
// now convert justpressed keyevents into regular (active) keyevents
|
||||
int previousTable = 1-m_currentTable;
|
||||
for (int keyevent= KX_BEGINKEY; keyevent<= KX_ENDKEY;keyevent++)
|
||||
{
|
||||
SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][keyevent];
|
||||
if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
|
||||
oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][keyevent] = oldevent;
|
||||
m_eventStatusTables[m_currentTable][keyevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
ConvertBlenderEvent translates blender keyboard events into ketsji kbd events
|
||||
extra event information is stored, like ramp-mode (just released/pressed)
|
||||
*/
|
||||
|
||||
|
||||
bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short val)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// convert event
|
||||
KX_EnumInputs kxevent = this->ToNative(incode);
|
||||
|
||||
// only process it, if it's a key
|
||||
if (kxevent >= KX_BEGINKEY && kxevent <= KX_ENDKEY)
|
||||
{
|
||||
int previousTable = 1-m_currentTable;
|
||||
|
||||
if (val == KM_PRESS)
|
||||
{
|
||||
if (kxevent == KX_ESCKEY && val != 0 && !m_hookesc)
|
||||
result = true;
|
||||
if (kxevent == KX_PAUSEKEY && val && (IsPressed(KX_LEFTCTRLKEY) || IsPressed(KX_RIGHTCTRLKEY)))
|
||||
result = true;
|
||||
|
||||
// todo: convert val ??
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
|
||||
|
||||
switch (m_eventStatusTables[previousTable][kxevent].m_status)
|
||||
{
|
||||
case SCA_InputEvent::KX_JUSTACTIVATED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
break;
|
||||
}
|
||||
case SCA_InputEvent::KX_ACTIVE:
|
||||
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
break;
|
||||
}
|
||||
case SCA_InputEvent::KX_NO_INPUTSTATUS:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (val == KM_RELEASE)
|
||||
{
|
||||
// blender eventval == 0
|
||||
switch (m_eventStatusTables[previousTable][kxevent].m_status)
|
||||
{
|
||||
case SCA_InputEvent::KX_JUSTACTIVATED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
|
||||
break;
|
||||
}
|
||||
case SCA_InputEvent::KX_ACTIVE:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void KX_BlenderKeyboardDevice::HookEscape()
|
||||
{
|
||||
m_hookesc = true;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERKEYBOARDDEVICE
|
||||
#define __KX_BLENDERKEYBOARDDEVICE
|
||||
|
||||
#include "KX_BlenderInputDevice.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
class KX_BlenderKeyboardDevice : public BL_BlenderInputDevice
|
||||
{
|
||||
bool m_hookesc;
|
||||
public:
|
||||
KX_BlenderKeyboardDevice();
|
||||
virtual ~KX_BlenderKeyboardDevice();
|
||||
|
||||
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
|
||||
// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
|
||||
virtual bool ConvertBlenderEvent(unsigned short incode,short val);
|
||||
virtual void NextFrame();
|
||||
virtual void HookEscape();
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderKeyboardDevice"); }
|
||||
void operator delete(void *mem) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_BLENDERKEYBOARDDEVICE
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
// annoying warnings about truncated STL debug info
|
||||
#pragma warning (disable :4786)
|
||||
#endif
|
||||
|
||||
#include "KX_BlenderMouseDevice.h"
|
||||
|
||||
KX_BlenderMouseDevice::KX_BlenderMouseDevice()
|
||||
{
|
||||
|
||||
}
|
||||
KX_BlenderMouseDevice::~KX_BlenderMouseDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
IsPressed gives boolean information about mouse status, true if pressed, false if not
|
||||
*/
|
||||
|
||||
bool KX_BlenderMouseDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
|
||||
{
|
||||
const SCA_InputEvent & inevent = m_eventStatusTables[m_currentTable][inputcode];
|
||||
bool pressed = (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
|
||||
inevent.m_status == SCA_InputEvent::KX_ACTIVE);
|
||||
return pressed;
|
||||
}
|
||||
/*const SCA_InputEvent& KX_BlenderMouseDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
|
||||
{
|
||||
return m_eventStatusTables[m_currentTable][inputcode];
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
NextFrame toggles currentTable with previousTable,
|
||||
and copy relevant event information from previous to current
|
||||
(pressed keys need to be remembered)
|
||||
*/
|
||||
void KX_BlenderMouseDevice::NextFrame()
|
||||
{
|
||||
SCA_IInputDevice::NextFrame();
|
||||
|
||||
// now convert justpressed keyevents into regular (active) keyevents
|
||||
int previousTable = 1-m_currentTable;
|
||||
for (int mouseevent= KX_BEGINMOUSE; mouseevent< KX_ENDMOUSEBUTTONS;mouseevent++)
|
||||
{
|
||||
SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mouseevent];
|
||||
if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
|
||||
oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][mouseevent] = oldevent;
|
||||
m_eventStatusTables[m_currentTable][mouseevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
}
|
||||
}
|
||||
for (int mousemove= KX_ENDMOUSEBUTTONS; mousemove< KX_ENDMOUSE;mousemove++)
|
||||
{
|
||||
SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mousemove];
|
||||
m_eventStatusTables[m_currentTable][mousemove] = oldevent;
|
||||
if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
|
||||
oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
|
||||
{
|
||||
|
||||
m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_JUSTRELEASED;
|
||||
} else
|
||||
{
|
||||
if (oldevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
|
||||
{
|
||||
|
||||
m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
ConvertBlenderEvent translates blender mouse events into ketsji kbd events
|
||||
extra event information is stored, like ramp-mode (just released/pressed)
|
||||
*/
|
||||
|
||||
|
||||
bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode,short val)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// convert event
|
||||
KX_EnumInputs kxevent = this->ToNative(incode);
|
||||
int previousTable = 1-m_currentTable;
|
||||
|
||||
// only process it, if it's a key
|
||||
if (kxevent > KX_BEGINMOUSE && kxevent < KX_ENDMOUSEBUTTONS)
|
||||
{
|
||||
if (val == KM_PRESS)
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
|
||||
|
||||
switch (m_eventStatusTables[previousTable][kxevent].m_status)
|
||||
{
|
||||
|
||||
case SCA_InputEvent::KX_ACTIVE:
|
||||
case SCA_InputEvent::KX_JUSTACTIVATED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
break;
|
||||
}
|
||||
case SCA_InputEvent::KX_JUSTRELEASED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (val == KM_RELEASE)
|
||||
{
|
||||
// blender eventval == 0
|
||||
switch (m_eventStatusTables[previousTable][kxevent].m_status)
|
||||
{
|
||||
case SCA_InputEvent::KX_JUSTACTIVATED:
|
||||
case SCA_InputEvent::KX_ACTIVE:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kxevent > KX_ENDMOUSEBUTTONS && kxevent < KX_ENDMOUSE)
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //remember mouse position
|
||||
|
||||
switch (m_eventStatusTables[previousTable][kxevent].m_status)
|
||||
{
|
||||
|
||||
case SCA_InputEvent::KX_ACTIVE:
|
||||
case SCA_InputEvent::KX_JUSTACTIVATED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
break;
|
||||
}
|
||||
case SCA_InputEvent::KX_JUSTRELEASED:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERMOUSEDEVICE
|
||||
#define __KX_BLENDERMOUSEDEVICE
|
||||
|
||||
#include "KX_BlenderInputDevice.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
class KX_BlenderMouseDevice : public BL_BlenderInputDevice
|
||||
{
|
||||
public:
|
||||
KX_BlenderMouseDevice();
|
||||
virtual ~KX_BlenderMouseDevice();
|
||||
|
||||
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
|
||||
// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
|
||||
virtual bool ConvertBlenderEvent(unsigned short incode,short val);
|
||||
virtual void NextFrame();
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderMouseDevice"); }
|
||||
void operator delete(void *mem) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_BLENDERMOUSEDEVICE
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "RAS_IRenderTools.h"
|
||||
#include "RAS_IRasterizer.h"
|
||||
#include "RAS_LightObject.h"
|
||||
#include "RAS_ICanvas.h"
|
||||
#include "RAS_GLExtensionManager.h"
|
||||
|
||||
#include "KX_GameObject.h"
|
||||
#include "KX_PolygonMaterial.h"
|
||||
#include "KX_BlenderMaterial.h"
|
||||
#include "KX_RayCast.h"
|
||||
#include "KX_IPhysicsController.h"
|
||||
#include "KX_Light.h"
|
||||
|
||||
#include "PHY_IPhysicsEnvironment.h"
|
||||
|
||||
#include "STR_String.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
|
||||
#include "KX_BlenderGL.h" // for text printing
|
||||
#include "KX_BlenderRenderTools.h"
|
||||
|
||||
unsigned int KX_BlenderRenderTools::m_numgllights;
|
||||
|
||||
KX_BlenderRenderTools::KX_BlenderRenderTools()
|
||||
{
|
||||
glGetIntegerv(GL_MAX_LIGHTS, (GLint*) &m_numgllights);
|
||||
if (m_numgllights < 8)
|
||||
m_numgllights = 8;
|
||||
}
|
||||
|
||||
KX_BlenderRenderTools::~KX_BlenderRenderTools()
|
||||
{
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty)
|
||||
{
|
||||
m_clientobject = NULL;
|
||||
m_lastlightlayer = -1;
|
||||
m_lastauxinfo = NULL;
|
||||
m_lastlighting = true; /* force disable in DisableOpenGLLights() */
|
||||
DisableOpenGLLights();
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
|
||||
{
|
||||
}
|
||||
|
||||
/* ProcessLighting performs lighting on objects. the layer is a bitfield that
|
||||
* contains layer information. There are 20 'official' layers in blender. A
|
||||
* light is applied on an object only when they are in the same layer. OpenGL
|
||||
* has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
|
||||
* a scene. */
|
||||
|
||||
void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat)
|
||||
{
|
||||
bool enable = false;
|
||||
int layer= -1;
|
||||
|
||||
/* find the layer */
|
||||
if(uselights) {
|
||||
if(m_clientobject)
|
||||
layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
|
||||
}
|
||||
|
||||
/* avoid state switching */
|
||||
if(m_lastlightlayer == layer && m_lastauxinfo == m_auxilaryClientInfo)
|
||||
return;
|
||||
|
||||
m_lastlightlayer = layer;
|
||||
m_lastauxinfo = m_auxilaryClientInfo;
|
||||
|
||||
/* enable/disable lights as needed */
|
||||
if(layer >= 0)
|
||||
enable = applyLights(layer, viewmat);
|
||||
|
||||
if(enable)
|
||||
EnableOpenGLLights(rasty);
|
||||
else
|
||||
DisableOpenGLLights();
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
|
||||
{
|
||||
if(m_lastlighting == true)
|
||||
return;
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||||
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
|
||||
if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
|
||||
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
|
||||
|
||||
m_lastlighting = true;
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::DisableOpenGLLights()
|
||||
{
|
||||
if(m_lastlighting == false)
|
||||
return;
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
|
||||
m_lastlighting = false;
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderRenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj)
|
||||
{
|
||||
if (m_clientobject != obj)
|
||||
{
|
||||
bool ccw = (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling());
|
||||
rasty->SetFrontFace(ccw);
|
||||
|
||||
m_clientobject = obj;
|
||||
}
|
||||
}
|
||||
|
||||
bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
|
||||
{
|
||||
double* const oglmatrix = (double* const) data;
|
||||
MT_Point3 resultpoint(result->m_hitPoint);
|
||||
MT_Vector3 resultnormal(result->m_hitNormal);
|
||||
MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
|
||||
MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
|
||||
left = (dir.cross(resultnormal)).safe_normalized();
|
||||
// for the up vector, we take the 'resultnormal' returned by the physics
|
||||
|
||||
double maat[16]={
|
||||
left[0], left[1], left[2], 0,
|
||||
dir[0], dir[1], dir[2], 0,
|
||||
resultnormal[0],resultnormal[1],resultnormal[2], 0,
|
||||
0, 0, 0, 1};
|
||||
glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]);
|
||||
//glMultMatrixd(oglmatrix);
|
||||
glMultMatrixd(maat);
|
||||
return true;
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode )
|
||||
{
|
||||
/* FIXME:
|
||||
blender: intern/moto/include/MT_Vector3.inl:42: MT_Vector3 operator/(const
|
||||
MT_Vector3&, double): Assertion `!MT_fuzzyZero(s)' failed.
|
||||
|
||||
Program received signal SIGABRT, Aborted.
|
||||
[Switching to Thread 16384 (LWP 1519)]
|
||||
0x40477571 in kill () from /lib/libc.so.6
|
||||
(gdb) bt
|
||||
#7 0x08334368 in MT_Vector3::normalized() const ()
|
||||
#8 0x0833e6ec in KX_BlenderRenderTools::applyTransform(RAS_IRasterizer*, double*, int) ()
|
||||
*/
|
||||
|
||||
if (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED ||
|
||||
objectdrawmode & RAS_IPolyMaterial::BILLBOARD_AXISALIGNED)
|
||||
{
|
||||
// rotate the billboard/halo
|
||||
//page 360/361 3D Game Engine Design, David Eberly for a discussion
|
||||
// on screen aligned and axis aligned billboards
|
||||
// assumed is that the preprocessor transformed all billboard polygons
|
||||
// so that their normal points into the positive x direction (1.0 , 0.0 , 0.0)
|
||||
// when new parenting for objects is done, this rotation
|
||||
// will be moved into the object
|
||||
|
||||
MT_Point3 objpos (oglmatrix[12],oglmatrix[13],oglmatrix[14]);
|
||||
MT_Point3 campos = rasty->GetCameraPosition();
|
||||
MT_Vector3 dir = (campos - objpos).safe_normalized();
|
||||
MT_Vector3 up(0,0,1.0);
|
||||
|
||||
KX_GameObject* gameobj = (KX_GameObject*)m_clientobject;
|
||||
// get scaling of halo object
|
||||
MT_Vector3 size = gameobj->GetSGNode()->GetLocalScale();
|
||||
|
||||
bool screenaligned = (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED)!=0;//false; //either screen or axisaligned
|
||||
if (screenaligned)
|
||||
{
|
||||
up = (up - up.dot(dir) * dir).safe_normalized();
|
||||
} else
|
||||
{
|
||||
dir = (dir - up.dot(dir)*up).safe_normalized();
|
||||
}
|
||||
|
||||
MT_Vector3 left = dir.normalized();
|
||||
dir = (left.cross(up)).normalized();
|
||||
|
||||
// we have calculated the row vectors, now we keep
|
||||
// local scaling into account:
|
||||
|
||||
left *= size[0];
|
||||
dir *= size[1];
|
||||
up *= size[2];
|
||||
double maat[16]={
|
||||
left[0], left[1],left[2], 0,
|
||||
dir[0], dir[1],dir[2],0,
|
||||
up[0],up[1],up[2],0,
|
||||
0,0,0,1};
|
||||
glTranslated(objpos[0],objpos[1],objpos[2]);
|
||||
glMultMatrixd(maat);
|
||||
|
||||
} else
|
||||
{
|
||||
if (objectdrawmode & RAS_IPolyMaterial::SHADOW)
|
||||
{
|
||||
// shadow must be cast to the ground, physics system needed here!
|
||||
MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
|
||||
KX_GameObject *gameobj = (KX_GameObject*)m_clientobject;
|
||||
MT_Vector3 direction = MT_Vector3(0,0,-1);
|
||||
|
||||
direction.normalize();
|
||||
direction *= 100000;
|
||||
|
||||
MT_Point3 topoint = frompoint + direction;
|
||||
|
||||
KX_Scene* kxscene = (KX_Scene*) m_auxilaryClientInfo;
|
||||
PHY_IPhysicsEnvironment* physics_environment = kxscene->GetPhysicsEnvironment();
|
||||
KX_IPhysicsController* physics_controller = gameobj->GetPhysicsController();
|
||||
|
||||
KX_GameObject *parent = gameobj->GetParent();
|
||||
if (!physics_controller && parent)
|
||||
physics_controller = parent->GetPhysicsController();
|
||||
if (parent)
|
||||
parent->Release();
|
||||
|
||||
KX_RayCast::Callback<KX_BlenderRenderTools> callback(this, physics_controller, oglmatrix);
|
||||
if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
|
||||
{
|
||||
// couldn't find something to cast the shadow on...
|
||||
glMultMatrixd(oglmatrix);
|
||||
}
|
||||
else
|
||||
{ // we found the "ground", but the cast matrix doesn't take
|
||||
// scaling in consideration, so we must apply the object scale
|
||||
MT_Vector3 size = gameobj->GetSGNode()->GetLocalScale();
|
||||
glScalef(size[0], size[1], size[2]);
|
||||
}
|
||||
} else
|
||||
{
|
||||
|
||||
// 'normal' object
|
||||
glMultMatrixd(oglmatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
|
||||
const char* text,
|
||||
int xco,
|
||||
int yco,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if(mode == RAS_IRenderTools::RAS_TEXT_PADDED)
|
||||
BL_print_gamedebug_line_padded(text, xco, yco, width, height);
|
||||
else
|
||||
BL_print_gamedebug_line(text, xco, yco, width, height);
|
||||
}
|
||||
|
||||
/* Render Text renders text into a (series of) polygon, using a texture font,
|
||||
* Each character consists of one polygon (one quad or two triangles) */
|
||||
|
||||
void KX_BlenderRenderTools::RenderText(
|
||||
int mode,
|
||||
RAS_IPolyMaterial* polymat,
|
||||
float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
|
||||
{
|
||||
const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
|
||||
|
||||
const unsigned int flag = polymat->GetFlag();
|
||||
struct MTFace* tface = 0;
|
||||
unsigned int *col = 0;
|
||||
|
||||
if(flag & RAS_BLENDERMAT) {
|
||||
KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(polymat);
|
||||
tface = bl_mat->GetMTFace();
|
||||
col = bl_mat->GetMCol();
|
||||
} else {
|
||||
KX_PolygonMaterial* blenderpoly = static_cast<KX_PolygonMaterial*>(polymat);
|
||||
tface = blenderpoly->GetMTFace();
|
||||
col = blenderpoly->GetMCol();
|
||||
}
|
||||
|
||||
GPU_render_text(tface, mode, mytext, mytext.Length(), col, v1, v2, v3, v4, glattrib);
|
||||
}
|
||||
|
||||
|
||||
void KX_BlenderRenderTools::PushMatrix()
|
||||
{
|
||||
glPushMatrix();
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::PopMatrix()
|
||||
{
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& viewmat)
|
||||
{
|
||||
// taken from blender source, incompatibility between Blender Object / GameObject
|
||||
KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
|
||||
float glviewmat[16];
|
||||
unsigned int count;
|
||||
std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin();
|
||||
|
||||
for(count=0; count<m_numgllights; count++)
|
||||
glDisable((GLenum)(GL_LIGHT0+count));
|
||||
|
||||
viewmat.getValue(glviewmat);
|
||||
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(glviewmat);
|
||||
for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
|
||||
{
|
||||
RAS_LightObject* lightdata = (*lit);
|
||||
KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light;
|
||||
|
||||
if(kxlight->ApplyLight(kxscene, objectlayer, count))
|
||||
count++;
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
|
||||
{
|
||||
int state = rasterizer->GetMotionBlurState();
|
||||
float motionblurvalue;
|
||||
if(state)
|
||||
{
|
||||
motionblurvalue = rasterizer->GetMotionBlurValue();
|
||||
if(state==1)
|
||||
{
|
||||
//bugfix:load color buffer into accum buffer for the first time(state=1)
|
||||
glAccum(GL_LOAD, 1.0);
|
||||
rasterizer->SetMotionBlurState(2);
|
||||
}
|
||||
else if(motionblurvalue>=0.0 && motionblurvalue<=1.0)
|
||||
{
|
||||
glAccum(GL_MULT, motionblurvalue);
|
||||
glAccum(GL_ACCUM, 1-motionblurvalue);
|
||||
glAccum(GL_RETURN, 1.0);
|
||||
glFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_BLENDERRENDERTOOLS
|
||||
#define __KX_BLENDERRENDERTOOLS
|
||||
|
||||
#ifdef WIN32
|
||||
// don't show stl-warnings
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include "RAS_IRenderTools.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
struct KX_ClientObjectInfo;
|
||||
class KX_RayCast;
|
||||
|
||||
/* BlenderRenderTools are a set of tools to apply 2D/3D graphics effects, which
|
||||
* are not part of the (polygon) Rasterizer. Effects like 2D text, 3D (polygon)
|
||||
* text, lighting.
|
||||
*
|
||||
* Most of this code is duplicated in GPC_RenderTools, so this should be
|
||||
* moved to some common location to avoid duplication. */
|
||||
|
||||
class KX_BlenderRenderTools : public RAS_IRenderTools
|
||||
{
|
||||
int m_lastlightlayer;
|
||||
bool m_lastlighting;
|
||||
void *m_lastauxinfo;
|
||||
static unsigned int m_numgllights;
|
||||
|
||||
public:
|
||||
KX_BlenderRenderTools();
|
||||
virtual ~KX_BlenderRenderTools();
|
||||
|
||||
void EndFrame(RAS_IRasterizer* rasty);
|
||||
void BeginFrame(RAS_IRasterizer* rasty);
|
||||
|
||||
void EnableOpenGLLights(RAS_IRasterizer *rasty);
|
||||
void DisableOpenGLLights();
|
||||
void ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat);
|
||||
|
||||
void RenderText2D(RAS_TEXT_RENDER_MODE mode,
|
||||
const char* text,
|
||||
int xco,
|
||||
int yco,
|
||||
int width,
|
||||
int height);
|
||||
void RenderText(int mode,
|
||||
class RAS_IPolyMaterial* polymat,
|
||||
float v1[3],
|
||||
float v2[3],
|
||||
float v3[3],
|
||||
float v4[3],
|
||||
int glattrib);
|
||||
|
||||
void applyTransform(RAS_IRasterizer* rasty, double* oglmatrix, int objectdrawmode);
|
||||
int applyLights(int objectlayer, const MT_Transform& viewmat);
|
||||
|
||||
void PushMatrix();
|
||||
void PopMatrix();
|
||||
|
||||
bool RayHit(KX_ClientObjectInfo* client, class KX_RayCast* result, void * const data);
|
||||
bool NeedRayCast(KX_ClientObjectInfo*) { return true; }
|
||||
|
||||
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
|
||||
|
||||
virtual void SetClientObject(RAS_IRasterizer *rasty, void* obj);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderRenderTools"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_BLENDERRENDERTOOLS
|
||||
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_ISystem.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable :4786)
|
||||
#include <windows.h>
|
||||
#endif //WIN32
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include "KX_BlenderInputDevice.h"
|
||||
#include "KX_BlenderSystem.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
KX_BlenderSystem::KX_BlenderSystem()
|
||||
: KX_ISystem()
|
||||
{
|
||||
m_starttime = PIL_check_seconds_timer();
|
||||
}
|
||||
|
||||
double KX_BlenderSystem::GetTimeInSeconds()
|
||||
{
|
||||
return PIL_check_seconds_timer() - m_starttime;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERSYSTEM
|
||||
#define __KX_BLENDERSYSTEM
|
||||
|
||||
/**
|
||||
* Blender System embedding. Needed when gameengine runs embedded within Blender.
|
||||
*/
|
||||
#include "KX_ISystem.h"
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
class KX_BlenderSystem : public KX_ISystem
|
||||
{
|
||||
double m_starttime;
|
||||
|
||||
public:
|
||||
KX_BlenderSystem();
|
||||
virtual ~KX_BlenderSystem() {};
|
||||
virtual double GetTimeInSeconds();
|
||||
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderSystem"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_BLENDERSYSTEM
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = bloutines
|
||||
DIR = $(OCGDIR)/gameengine/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||
CPPFLAGS += -I$(NAN_STRING)/include
|
||||
CPPFLAGS += -I$(NAN_MOTO)/include
|
||||
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
CPPFLAGS += -I$(NAN_AUDASPACE)/include
|
||||
# because of kernel dependency on makesdna
|
||||
CPPFLAGS += -I../../blender/makesdna
|
||||
CPPFLAGS += -I../../blender/editors/include
|
||||
# because of kernel dependency on imbuf
|
||||
CPPFLAGS += -I../../blender/windowmanager
|
||||
CPPFLAGS += -I../../blender/imbuf
|
||||
CPPFLAGS += -I../../blender/blenlib
|
||||
CPPFLAGS += -I../../blender/blenkernel
|
||||
CPPFLAGS += -I../../blender/render/extern/include
|
||||
CPPFLAGS += -I../../blender/blenloader
|
||||
CPPFLAGS += -I../../blender/blenfont
|
||||
CPPFLAGS += -I../../blender/gpu
|
||||
CPPFLAGS += -I../../blender/makesrna
|
||||
CPPFLAGS += -I../Converter
|
||||
CPPFLAGS += -I../Expressions
|
||||
CPPFLAGS += -I../GameLogic
|
||||
CPPFLAGS += -I../Ketsji
|
||||
CPPFLAGS += -I../Rasterizer
|
||||
CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
|
||||
CPPFLAGS += -I../SceneGraph
|
||||
CPPFLAGS += -I../../kernel/gen_system
|
||||
CPPFLAGS += -I../Network
|
||||
CPPFLAGS += -I../Network/LoopBackNetwork
|
||||
CPPFLAGS += -I../Physics/common
|
||||
CPPFLAGS += -I.
|
||||
|
||||
ifeq ($(OS),windows)
|
||||
CPPFLAGS += -I../../blender
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
|
||||
|
||||
ifeq ($(WITH_FFMPEG), true)
|
||||
CPPFLAGS += -DWITH_FFMPEG
|
||||
endif
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('*.cpp')
|
||||
defs = [ 'GLEW_STATIC' ]
|
||||
|
||||
incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
|
||||
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
|
||||
incs += ' #source/gameengine/Converter #source/blender/imbuf'
|
||||
incs += ' #intern/ghost/include'
|
||||
incs += ' #intern/audaspace/intern'
|
||||
incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib'
|
||||
incs += ' #source/blender/blenkernel #source/blender'
|
||||
incs += ' #source/blender/blenfont #source/blender/editors/include'
|
||||
incs += ' #source/blender/makesdna #source/blender/makesrna'
|
||||
incs += ' #source/gameengine/Rasterizer #source/gameengine/GameLogic'
|
||||
incs += ' #source/gameengine/Expressions #source/gameengine/Network'
|
||||
incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common'
|
||||
incs += ' #source/gameengine/Physics/Bullet'
|
||||
incs += ' #source/gameengine/Network/LoopBackNetwork'
|
||||
incs += ' #source/blender/misc #source/blender/blenloader'
|
||||
incs += ' #extern/glew/include #source/blender/gpu'
|
||||
incs += ' #source/blender/windowmanager'
|
||||
|
||||
if env['WITH_BF_FFMPEG']:
|
||||
defs.append('WITH_FFMPEG')
|
||||
|
||||
if env['WITH_BF_PYTHON']:
|
||||
incs += ' ' + env['BF_PYTHON_INC']
|
||||
else:
|
||||
defs.append('DISABLE_PYTHON')
|
||||
|
||||
incs += ' ' + env['BF_BULLET_INC']
|
||||
incs += ' ' + env['BF_OPENGL_INC']
|
||||
|
||||
env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core','player'], priority=[300,35] , cxx_compileflags=env['BGE_CXXFLAGS'])
|
||||
@@ -1,48 +0,0 @@
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
ADD_SUBDIRECTORY(BlenderRoutines)
|
||||
ADD_SUBDIRECTORY(Converter)
|
||||
ADD_SUBDIRECTORY(Expressions)
|
||||
ADD_SUBDIRECTORY(GameLogic)
|
||||
ADD_SUBDIRECTORY(Ketsji)
|
||||
ADD_SUBDIRECTORY(Ketsji/KXNetwork)
|
||||
ADD_SUBDIRECTORY(Network)
|
||||
ADD_SUBDIRECTORY(Network/LoopBackNetwork)
|
||||
ADD_SUBDIRECTORY(Physics/common)
|
||||
ADD_SUBDIRECTORY(Physics/Dummy)
|
||||
ADD_SUBDIRECTORY(Rasterizer)
|
||||
ADD_SUBDIRECTORY(Rasterizer/RAS_OpenGLRasterizer)
|
||||
ADD_SUBDIRECTORY(SceneGraph)
|
||||
ADD_SUBDIRECTORY(Physics/Bullet)
|
||||
|
||||
IF(WITH_PYTHON)
|
||||
ADD_SUBDIRECTORY(VideoTexture)
|
||||
ENDIF(WITH_PYTHON)
|
||||
|
||||
IF(WITH_PLAYER)
|
||||
ADD_SUBDIRECTORY(GamePlayer)
|
||||
ENDIF(WITH_PLAYER)
|
||||
@@ -1,677 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#if defined (__sgi)
|
||||
#include <math.h>
|
||||
#else
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include "SCA_LogicManager.h"
|
||||
#include "BL_ActionActuator.h"
|
||||
#include "BL_ArmatureObject.h"
|
||||
#include "BL_SkinDeformer.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "DNA_nla_types.h"
|
||||
#include "BKE_action.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "MT_Matrix4x4.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "FloatValue.h"
|
||||
#include "PyObjectPlus.h"
|
||||
#include "KX_PyMath.h"
|
||||
|
||||
extern "C" {
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
}
|
||||
|
||||
BL_ActionActuator::~BL_ActionActuator()
|
||||
{
|
||||
if (m_pose)
|
||||
game_free_pose(m_pose);
|
||||
if (m_userpose)
|
||||
game_free_pose(m_userpose);
|
||||
if (m_blendpose)
|
||||
game_free_pose(m_blendpose);
|
||||
}
|
||||
|
||||
void BL_ActionActuator::ProcessReplica()
|
||||
{
|
||||
SCA_IActuator::ProcessReplica();
|
||||
|
||||
m_pose = NULL;
|
||||
m_blendpose = NULL;
|
||||
m_localtime=m_startframe;
|
||||
m_lastUpdate=-1;
|
||||
|
||||
}
|
||||
|
||||
void BL_ActionActuator::SetBlendTime (float newtime){
|
||||
m_blendframe = newtime;
|
||||
}
|
||||
|
||||
CValue* BL_ActionActuator::GetReplica() {
|
||||
BL_ActionActuator* replica = new BL_ActionActuator(*this);//m_float,GetName());
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
bool BL_ActionActuator::ClampLocalTime()
|
||||
{
|
||||
if (m_startframe < m_endframe)
|
||||
{
|
||||
if (m_localtime < m_startframe)
|
||||
{
|
||||
m_localtime = m_startframe;
|
||||
return true;
|
||||
}
|
||||
else if (m_localtime > m_endframe)
|
||||
{
|
||||
m_localtime = m_endframe;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (m_localtime > m_startframe)
|
||||
{
|
||||
m_localtime = m_startframe;
|
||||
return true;
|
||||
}
|
||||
else if (m_localtime < m_endframe)
|
||||
{
|
||||
m_localtime = m_endframe;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BL_ActionActuator::SetStartTime(float curtime)
|
||||
{
|
||||
float direction = m_startframe < m_endframe ? 1.0 : -1.0;
|
||||
|
||||
if (!(m_flag & ACT_FLAG_REVERSE))
|
||||
m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate();
|
||||
else
|
||||
m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate();
|
||||
}
|
||||
|
||||
void BL_ActionActuator::SetLocalTime(float curtime)
|
||||
{
|
||||
float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
|
||||
if (m_endframe < m_startframe)
|
||||
delta_time = -delta_time;
|
||||
|
||||
if (!(m_flag & ACT_FLAG_REVERSE))
|
||||
m_localtime = m_startframe + delta_time;
|
||||
else
|
||||
m_localtime = m_endframe - delta_time;
|
||||
}
|
||||
|
||||
|
||||
bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
bool bNegativeEvent = false;
|
||||
bool bPositiveEvent = false;
|
||||
bool keepgoing = true;
|
||||
bool wrap = false;
|
||||
bool apply=true;
|
||||
int priority;
|
||||
float newweight;
|
||||
|
||||
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
|
||||
|
||||
// result = true if animation has to be continued, false if animation stops
|
||||
// maybe there are events for us in the queue !
|
||||
if (frame)
|
||||
{
|
||||
bNegativeEvent = m_negevent;
|
||||
bPositiveEvent = m_posevent;
|
||||
RemoveAllEvents();
|
||||
|
||||
if (bPositiveEvent)
|
||||
m_flag |= ACT_FLAG_ACTIVE;
|
||||
|
||||
if (bNegativeEvent)
|
||||
{
|
||||
// dont continue where we left off when restarting
|
||||
if (m_end_reset) {
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
|
||||
if (!(m_flag & ACT_FLAG_ACTIVE))
|
||||
return false;
|
||||
m_flag &= ~ACT_FLAG_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We know that action actuators have been discarded from all non armature objects:
|
||||
if we're being called, we're attached to a BL_ArmatureObject */
|
||||
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
|
||||
float length = m_endframe - m_startframe;
|
||||
|
||||
priority = m_priority;
|
||||
|
||||
/* Determine pre-incrementation behaviour and set appropriate flags */
|
||||
switch (m_playtype){
|
||||
case ACT_ACTION_MOTION:
|
||||
if (bNegativeEvent){
|
||||
keepgoing=false;
|
||||
apply=false;
|
||||
};
|
||||
break;
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
if (bNegativeEvent){
|
||||
apply=false;
|
||||
keepgoing=false;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_END:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_KEYUP;
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
m_localtime = m_startframe;
|
||||
m_starttime = curtime;
|
||||
}
|
||||
}
|
||||
if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_KEYUP;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag &= ~ACT_FLAG_KEYUP;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
}
|
||||
if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_KEYUP;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
keepgoing=false;
|
||||
apply=false;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_FLIPPER:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
}
|
||||
else if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_REVERSE;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_PLAY:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_localtime = m_starttime;
|
||||
m_starttime = curtime;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Perform increment */
|
||||
if (keepgoing){
|
||||
if (m_playtype == ACT_ACTION_MOTION){
|
||||
MT_Point3 newpos;
|
||||
MT_Point3 deltapos;
|
||||
|
||||
newpos = obj->NodeGetWorldPosition();
|
||||
|
||||
/* Find displacement */
|
||||
deltapos = newpos-m_lastpos;
|
||||
m_localtime += (length/m_stridelength) * deltapos.length();
|
||||
m_lastpos = newpos;
|
||||
}
|
||||
else{
|
||||
SetLocalTime(curtime);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if a wrapping response is needed */
|
||||
if (length){
|
||||
if (m_localtime < m_startframe || m_localtime > m_endframe)
|
||||
{
|
||||
m_localtime = m_startframe + fmod(m_localtime, length);
|
||||
wrap = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_localtime = m_startframe;
|
||||
|
||||
/* Perform post-increment tasks */
|
||||
switch (m_playtype){
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
{
|
||||
CValue* propval = GetParent()->GetProperty(m_propname);
|
||||
if (propval)
|
||||
m_localtime = propval->GetNumber();
|
||||
|
||||
if (bNegativeEvent){
|
||||
keepgoing=false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_MOTION:
|
||||
break;
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
break;
|
||||
case ACT_ACTION_FLIPPER:
|
||||
if (wrap){
|
||||
if (!(m_flag & ACT_FLAG_REVERSE)){
|
||||
m_localtime=m_endframe;
|
||||
//keepgoing = false;
|
||||
}
|
||||
else {
|
||||
m_localtime=m_startframe;
|
||||
keepgoing = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_END:
|
||||
if (wrap){
|
||||
if (m_flag & ACT_FLAG_KEYUP){
|
||||
keepgoing = false;
|
||||
m_localtime = m_endframe;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_PLAY:
|
||||
if (wrap){
|
||||
m_localtime = m_endframe;
|
||||
keepgoing = false;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
keepgoing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the property if its defined */
|
||||
if (m_framepropname[0] != '\0') {
|
||||
CValue* propowner = GetParent();
|
||||
CValue* oldprop = propowner->GetProperty(m_framepropname);
|
||||
CValue* newval = new CFloatValue(m_localtime);
|
||||
if (oldprop) {
|
||||
oldprop->SetValue(newval);
|
||||
} else {
|
||||
propowner->SetProperty(m_framepropname, newval);
|
||||
}
|
||||
newval->Release();
|
||||
}
|
||||
|
||||
if (bNegativeEvent)
|
||||
m_blendframe=0.0;
|
||||
|
||||
/* Apply the pose if necessary*/
|
||||
if (apply){
|
||||
|
||||
/* Priority test */
|
||||
if (obj->SetActiveAction(this, priority, curtime)){
|
||||
|
||||
/* Get the underlying pose from the armature */
|
||||
obj->GetPose(&m_pose);
|
||||
|
||||
// 2.4x function,
|
||||
/* Override the necessary channels with ones from the action */
|
||||
// XXX extract_pose_from_action(m_pose, m_action, m_localtime);
|
||||
|
||||
|
||||
// 2.5x - replacement for extract_pose_from_action(...) above.
|
||||
{
|
||||
struct PointerRNA id_ptr;
|
||||
Object *arm= obj->GetArmatureObject();
|
||||
bPose *pose_back= arm->pose;
|
||||
|
||||
arm->pose= m_pose;
|
||||
RNA_id_pointer_create((ID *)arm, &id_ptr);
|
||||
animsys_evaluate_action(&id_ptr, m_action, NULL, m_localtime);
|
||||
|
||||
arm->pose= pose_back;
|
||||
|
||||
// 2.5x - could also do this but looks too high level, constraints use this, it works ok.
|
||||
// Object workob; /* evaluate using workob */
|
||||
// what_does_obaction((Scene *)obj->GetScene(), obj->GetArmatureObject(), &workob, m_pose, m_action, NULL, m_localtime);
|
||||
}
|
||||
|
||||
// done getting the pose from the action
|
||||
|
||||
/* Perform the user override (if any) */
|
||||
if (m_userpose){
|
||||
extract_pose_from_pose(m_pose, m_userpose);
|
||||
game_free_pose(m_userpose); //cant use MEM_freeN(m_userpose) because the channels need freeing too.
|
||||
m_userpose = NULL;
|
||||
}
|
||||
#if 1
|
||||
/* Handle blending */
|
||||
if (m_blendin && (m_blendframe<m_blendin)){
|
||||
/* If this is the start of a blending sequence... */
|
||||
if ((m_blendframe==0.0) || (!m_blendpose)){
|
||||
obj->GetMRDPose(&m_blendpose);
|
||||
m_blendstart = curtime;
|
||||
}
|
||||
|
||||
/* Find percentages */
|
||||
newweight = (m_blendframe/(float)m_blendin);
|
||||
game_blend_poses(m_pose, m_blendpose, 1.0 - newweight);
|
||||
|
||||
/* Increment current blending percentage */
|
||||
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
if (m_blendframe>m_blendin)
|
||||
m_blendframe = m_blendin;
|
||||
|
||||
}
|
||||
#endif
|
||||
m_lastUpdate = m_localtime;
|
||||
obj->SetPose (m_pose);
|
||||
}
|
||||
else{
|
||||
m_blendframe = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!keepgoing){
|
||||
m_blendframe = 0.0;
|
||||
}
|
||||
return keepgoing;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) {
|
||||
char *string= _PyUnicode_AsString(value);
|
||||
|
||||
if (!string) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a single string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bPoseChannel *pchan;
|
||||
|
||||
if(m_userpose==NULL && m_pose==NULL) {
|
||||
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
|
||||
obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
|
||||
}
|
||||
|
||||
// get_pose_channel accounts for NULL pose, run on both incase one exists but
|
||||
// the channel doesnt
|
||||
if( !(pchan=get_pose_channel(m_userpose, string)) &&
|
||||
!(pchan=get_pose_channel(m_pose, string)) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "channel doesnt exist");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *ret = PyTuple_New(3);
|
||||
|
||||
PyObject *list = PyList_New(3);
|
||||
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->loc[0]));
|
||||
PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->loc[1]));
|
||||
PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->loc[2]));
|
||||
PyTuple_SET_ITEM(ret, 0, list);
|
||||
|
||||
list = PyList_New(3);
|
||||
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->size[0]));
|
||||
PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->size[1]));
|
||||
PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->size[2]));
|
||||
PyTuple_SET_ITEM(ret, 1, list);
|
||||
|
||||
list = PyList_New(4);
|
||||
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->quat[0]));
|
||||
PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->quat[1]));
|
||||
PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->quat[2]));
|
||||
PyList_SET_ITEM(list, 3, PyFloat_FromDouble(pchan->quat[3]));
|
||||
PyTuple_SET_ITEM(ret, 2, list);
|
||||
|
||||
return ret;
|
||||
/*
|
||||
return Py_BuildValue("([fff][fff][ffff])",
|
||||
pchan->loc[0], pchan->loc[1], pchan->loc[2],
|
||||
pchan->size[0], pchan->size[1], pchan->size[2],
|
||||
pchan->quat[0], pchan->quat[1], pchan->quat[2], pchan->quat[3] );
|
||||
*/
|
||||
}
|
||||
|
||||
/* setChannel */
|
||||
KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
|
||||
"setChannel(channel, matrix)\n"
|
||||
"\t - channel : A string specifying the name of the bone channel.\n"
|
||||
"\t - matrix : A 4x4 matrix specifying the overriding transformation\n"
|
||||
"\t as an offset from the bone's rest position.\n")
|
||||
{
|
||||
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
|
||||
char *string;
|
||||
PyObject *pymat= NULL;
|
||||
PyObject *pyloc= NULL, *pysize= NULL, *pyquat= NULL;
|
||||
bPoseChannel *pchan;
|
||||
|
||||
if(PyTuple_Size(args)==2) {
|
||||
if (!PyArg_ParseTuple(args,"sO:setChannel", &string, &pymat)) // matrix
|
||||
return NULL;
|
||||
}
|
||||
else if(PyTuple_Size(args)==4) {
|
||||
if (!PyArg_ParseTuple(args,"sOOO:setChannel", &string, &pyloc, &pysize, &pyquat)) // loc/size/quat
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string and a 4x4 matrix (2 args) or a string and loc/size/quat sequences (4 args)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pymat) {
|
||||
float matrix[4][4];
|
||||
MT_Matrix4x4 mat;
|
||||
|
||||
if(!PyMatTo(pymat, mat))
|
||||
return NULL;
|
||||
|
||||
mat.getValue((float*)matrix);
|
||||
|
||||
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
|
||||
|
||||
if (!m_userpose) {
|
||||
if(!m_pose)
|
||||
obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
|
||||
game_copy_pose(&m_userpose, m_pose, 0);
|
||||
}
|
||||
// pchan= verify_pose_channel(m_userpose, string); // adds the channel if its not there.
|
||||
pchan= get_pose_channel(m_userpose, string); // adds the channel if its not there.
|
||||
|
||||
if(pchan) {
|
||||
VECCOPY (pchan->loc, matrix[3]);
|
||||
mat4_to_size( pchan->size,matrix);
|
||||
mat4_to_quat( pchan->quat,matrix);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MT_Vector3 loc;
|
||||
MT_Vector3 size;
|
||||
MT_Quaternion quat;
|
||||
|
||||
if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyQuatTo(pyquat, quat))
|
||||
return NULL;
|
||||
|
||||
// same as above
|
||||
if (!m_userpose) {
|
||||
if(!m_pose)
|
||||
obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
|
||||
game_copy_pose(&m_userpose, m_pose, 0);
|
||||
}
|
||||
// pchan= verify_pose_channel(m_userpose, string);
|
||||
pchan= get_pose_channel(m_userpose, string); // adds the channel if its not there.
|
||||
|
||||
// for some reason loc.setValue(pchan->loc) fails
|
||||
if(pchan) {
|
||||
pchan->loc[0]= loc[0]; pchan->loc[1]= loc[1]; pchan->loc[2]= loc[2];
|
||||
pchan->size[0]= size[0]; pchan->size[1]= size[1]; pchan->size[2]= size[2];
|
||||
pchan->quat[0]= quat[3]; pchan->quat[1]= quat[0]; pchan->quat[2]= quat[1]; pchan->quat[3]= quat[2]; /* notice xyzw -> wxyz is intentional */
|
||||
}
|
||||
}
|
||||
|
||||
if(pchan==NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Channel could not be found, use the 'channelNames' attribute to get a list of valid channels");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python Integration Hooks */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
PyTypeObject BL_ActionActuator::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ActionActuator",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&SCA_IActuator::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyMethodDef BL_ActionActuator::Methods[] = {
|
||||
{"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_O},
|
||||
KX_PYMETHODTABLE(BL_ActionActuator, setChannel),
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef BL_ActionActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ActionActuator, m_startframe),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ActionActuator, m_endframe),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ActionActuator, m_blendin),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ActionActuator, pyattr_get_action, pyattr_set_action),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("channelNames", BL_ActionActuator, pyattr_get_channel_names),
|
||||
KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ActionActuator, m_priority),
|
||||
KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ActionActuator, m_localtime, CheckFrame),
|
||||
KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ActionActuator, m_propname),
|
||||
KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ActionActuator, m_framepropname),
|
||||
KX_PYATTRIBUTE_BOOL_RW("useContinue", BL_ActionActuator, m_end_reset),
|
||||
KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime),
|
||||
KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ActionActuator,m_playtype,CheckType),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* BL_ActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ActionActuator* self= static_cast<BL_ActionActuator*>(self_v);
|
||||
return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : "");
|
||||
}
|
||||
|
||||
int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ActionActuator* self= static_cast<BL_ActionActuator*>(self_v);
|
||||
|
||||
if (!PyUnicode_Check(value))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, expected the string name of the action");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
bAction *action= NULL;
|
||||
STR_String val = _PyUnicode_AsString(value);
|
||||
|
||||
if (val != "")
|
||||
{
|
||||
action= (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(val);
|
||||
if (!action)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, action not found!");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
self->SetAction(action);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
PyObject* BL_ActionActuator::pyattr_get_channel_names(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ActionActuator* self= static_cast<BL_ActionActuator*>(self_v);
|
||||
PyObject *ret= PyList_New(0);
|
||||
PyObject *item;
|
||||
|
||||
bPose *pose= ((BL_ArmatureObject*)self->GetParent())->GetOrigPose();
|
||||
|
||||
if(pose) {
|
||||
bPoseChannel *pchan;
|
||||
for(pchan= (bPoseChannel *)pose->chanbase.first; pchan; pchan= (bPoseChannel *)pchan->next) {
|
||||
item= PyUnicode_FromString(pchan->name);
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,177 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_ACTIONACTUATOR
|
||||
#define BL_ACTIONACTUATOR
|
||||
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "SCA_IActuator.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
#include "MT_Point3.h"
|
||||
|
||||
class BL_ActionActuator : public SCA_IActuator
|
||||
{
|
||||
public:
|
||||
Py_Header;
|
||||
BL_ActionActuator(SCA_IObject* gameobj,
|
||||
const STR_String& propname,
|
||||
const STR_String& framepropname,
|
||||
float starttime,
|
||||
float endtime,
|
||||
struct bAction *action,
|
||||
short playtype,
|
||||
short blendin,
|
||||
short priority,
|
||||
short end_reset,
|
||||
float stride)
|
||||
: SCA_IActuator(gameobj, KX_ACT_ACTION),
|
||||
|
||||
m_lastpos(0, 0, 0),
|
||||
m_blendframe(0),
|
||||
m_flag(0),
|
||||
m_startframe (starttime),
|
||||
m_endframe(endtime) ,
|
||||
m_starttime(0),
|
||||
m_localtime(starttime),
|
||||
m_lastUpdate(-1),
|
||||
m_blendin(blendin),
|
||||
m_blendstart(0),
|
||||
m_stridelength(stride),
|
||||
m_playtype(playtype),
|
||||
m_priority(priority),
|
||||
m_end_reset(end_reset),
|
||||
m_pose(NULL),
|
||||
m_blendpose(NULL),
|
||||
m_userpose(NULL),
|
||||
m_action(action),
|
||||
m_propname(propname),
|
||||
m_framepropname(framepropname)
|
||||
{
|
||||
};
|
||||
virtual ~BL_ActionActuator();
|
||||
virtual bool Update(double curtime, bool frame);
|
||||
virtual CValue* GetReplica();
|
||||
virtual void ProcessReplica();
|
||||
|
||||
void SetBlendTime (float newtime);
|
||||
|
||||
bAction* GetAction() { return m_action; }
|
||||
void SetAction(bAction* act) { m_action= act; }
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
KX_PYMETHOD_O(BL_ActionActuator,GetChannel);
|
||||
KX_PYMETHOD_DOC(BL_ActionActuator,setChannel);
|
||||
|
||||
static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_channel_names(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
/* attribute check */
|
||||
static int CheckFrame(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ActionActuator* act = reinterpret_cast<BL_ActionActuator*>(self);
|
||||
|
||||
if (act->m_localtime < act->m_startframe)
|
||||
act->m_localtime = act->m_startframe;
|
||||
else if (act->m_localtime > act->m_endframe)
|
||||
act->m_localtime = act->m_endframe;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CheckBlendTime(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ActionActuator* act = reinterpret_cast<BL_ActionActuator*>(self);
|
||||
|
||||
if (act->m_blendframe > act->m_blendin)
|
||||
act->m_blendframe = act->m_blendin;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CheckType(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ActionActuator* act = reinterpret_cast<BL_ActionActuator*>(self);
|
||||
|
||||
switch (act->m_playtype) {
|
||||
case ACT_ACTION_PLAY:
|
||||
case ACT_ACTION_FLIPPER:
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
case ACT_ACTION_LOOP_END:
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
return 0;
|
||||
default:
|
||||
PyErr_SetString(PyExc_ValueError, "Action Actuator, invalid play type supplied");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
protected:
|
||||
|
||||
void SetStartTime(float curtime);
|
||||
void SetLocalTime(float curtime);
|
||||
bool ClampLocalTime();
|
||||
|
||||
MT_Point3 m_lastpos;
|
||||
float m_blendframe;
|
||||
int m_flag;
|
||||
/** The frame this action starts */
|
||||
float m_startframe;
|
||||
/** The frame this action ends */
|
||||
float m_endframe;
|
||||
/** The time this action started */
|
||||
float m_starttime;
|
||||
/** The current time of the action */
|
||||
float m_localtime;
|
||||
|
||||
float m_lastUpdate;
|
||||
float m_blendin;
|
||||
float m_blendstart;
|
||||
float m_stridelength;
|
||||
short m_playtype;
|
||||
short m_priority;
|
||||
bool m_end_reset;
|
||||
struct bPose* m_pose;
|
||||
struct bPose* m_blendpose;
|
||||
struct bPose* m_userpose;
|
||||
struct bAction *m_action;
|
||||
STR_String m_propname;
|
||||
STR_String m_framepropname;
|
||||
};
|
||||
|
||||
enum {
|
||||
ACT_FLAG_REVERSE = 0x00000001,
|
||||
ACT_FLAG_LOCKINPUT = 0x00000002,
|
||||
ACT_FLAG_KEYUP = 0x00000004,
|
||||
ACT_FLAG_ACTIVE = 0x00000008
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureActuator.cpp 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BL_ArmatureActuator.h"
|
||||
#include "BL_ArmatureObject.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
/**
|
||||
* This class is the conversion of the Pose channel constraint.
|
||||
* It makes a link between the pose constraint and the KX scene.
|
||||
* The main purpose is to give access to the constraint target
|
||||
* to link it to a game object.
|
||||
* It also allows to activate/deactivate constraints during the game.
|
||||
* Later it will also be possible to create constraint on the fly
|
||||
*/
|
||||
|
||||
BL_ArmatureActuator::BL_ArmatureActuator(SCA_IObject* obj,
|
||||
int type,
|
||||
const char *posechannel,
|
||||
const char *constraintname,
|
||||
KX_GameObject* targetobj,
|
||||
KX_GameObject* subtargetobj,
|
||||
float weight) :
|
||||
SCA_IActuator(obj, KX_ACT_ARMATURE),
|
||||
m_constraint(NULL),
|
||||
m_gametarget(targetobj),
|
||||
m_gamesubtarget(subtargetobj),
|
||||
m_posechannel(posechannel),
|
||||
m_constraintname(constraintname),
|
||||
m_weight(weight),
|
||||
m_type(type)
|
||||
{
|
||||
if (m_gametarget)
|
||||
m_gametarget->RegisterActuator(this);
|
||||
if (m_gamesubtarget)
|
||||
m_gamesubtarget->RegisterActuator(this);
|
||||
FindConstraint();
|
||||
}
|
||||
|
||||
BL_ArmatureActuator::~BL_ArmatureActuator()
|
||||
{
|
||||
if (m_gametarget)
|
||||
m_gametarget->UnregisterActuator(this);
|
||||
if (m_gamesubtarget)
|
||||
m_gamesubtarget->UnregisterActuator(this);
|
||||
}
|
||||
|
||||
void BL_ArmatureActuator::ProcessReplica()
|
||||
{
|
||||
// the replica is tracking the same object => register it (this may be changed in Relnk())
|
||||
if (m_gametarget)
|
||||
m_gametarget->RegisterActuator(this);
|
||||
if (m_gamesubtarget)
|
||||
m_gamesubtarget->UnregisterActuator(this);
|
||||
SCA_IActuator::ProcessReplica();
|
||||
}
|
||||
|
||||
void BL_ArmatureActuator::ReParent(SCA_IObject* parent)
|
||||
{
|
||||
SCA_IActuator::ReParent(parent);
|
||||
// must remap the constraint
|
||||
FindConstraint();
|
||||
}
|
||||
|
||||
bool BL_ArmatureActuator::UnlinkObject(SCA_IObject* clientobj)
|
||||
{
|
||||
bool res=false;
|
||||
if (clientobj == m_gametarget)
|
||||
{
|
||||
// this object is being deleted, we cannot continue to track it.
|
||||
m_gametarget = NULL;
|
||||
res = true;
|
||||
}
|
||||
if (clientobj == m_gamesubtarget)
|
||||
{
|
||||
// this object is being deleted, we cannot continue to track it.
|
||||
m_gamesubtarget = NULL;
|
||||
res = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void BL_ArmatureActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
|
||||
{
|
||||
void **h_obj = (*obj_map)[m_gametarget];
|
||||
if (h_obj) {
|
||||
if (m_gametarget)
|
||||
m_gametarget->UnregisterActuator(this);
|
||||
m_gametarget = (KX_GameObject*)(*h_obj);
|
||||
m_gametarget->RegisterActuator(this);
|
||||
}
|
||||
h_obj = (*obj_map)[m_gamesubtarget];
|
||||
if (h_obj) {
|
||||
if (m_gamesubtarget)
|
||||
m_gamesubtarget->UnregisterActuator(this);
|
||||
m_gamesubtarget = (KX_GameObject*)(*h_obj);
|
||||
m_gamesubtarget->RegisterActuator(this);
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ArmatureActuator::FindConstraint()
|
||||
{
|
||||
m_constraint = NULL;
|
||||
|
||||
if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
|
||||
BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
|
||||
m_constraint = armobj->GetConstraint(m_posechannel, m_constraintname);
|
||||
}
|
||||
}
|
||||
|
||||
bool BL_ArmatureActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
// the only role of this actuator is to ensure that the armature pose will be evaluated
|
||||
bool result = false;
|
||||
bool bNegativeEvent = IsNegativeEvent();
|
||||
RemoveAllEvents();
|
||||
|
||||
if (!bNegativeEvent) {
|
||||
BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
|
||||
switch (m_type) {
|
||||
case ACT_ARM_RUN:
|
||||
result = true;
|
||||
obj->SetActiveAction(NULL, 0, curtime);
|
||||
break;
|
||||
case ACT_ARM_ENABLE:
|
||||
if (m_constraint)
|
||||
m_constraint->ClrConstraintFlag(CONSTRAINT_OFF);
|
||||
break;
|
||||
case ACT_ARM_DISABLE:
|
||||
if (m_constraint)
|
||||
m_constraint->SetConstraintFlag(CONSTRAINT_OFF);
|
||||
break;
|
||||
case ACT_ARM_SETTARGET:
|
||||
if (m_constraint) {
|
||||
m_constraint->SetTarget(m_gametarget);
|
||||
m_constraint->SetSubtarget(m_gamesubtarget);
|
||||
}
|
||||
break;
|
||||
case ACT_ARM_SETWEIGHT:
|
||||
if (m_constraint)
|
||||
m_constraint->SetWeight(m_weight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python Integration Hooks */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
PyTypeObject BL_ArmatureActuator::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ArmatureActuator",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&SCA_IActuator::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
|
||||
PyMethodDef BL_ArmatureActuator::Methods[] = {
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef BL_ArmatureActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("constraint", BL_ArmatureActuator, pyattr_get_constraint),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("target", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("subtarget", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("weight",0.0f,1.0f,BL_ArmatureActuator,m_weight),
|
||||
KX_PYATTRIBUTE_INT_RW("type",0,ACT_ARM_MAXTYPE,false,BL_ArmatureActuator,m_type),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* BL_ArmatureActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
|
||||
KX_GameObject *target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
|
||||
if (!target)
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
return target->GetProxy();
|
||||
}
|
||||
|
||||
int BL_ArmatureActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
|
||||
KX_GameObject* &target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
|
||||
KX_GameObject *gameobj;
|
||||
|
||||
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: BL_ArmatureActuator"))
|
||||
return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
|
||||
|
||||
if (target != NULL)
|
||||
target->UnregisterActuator(actuator);
|
||||
|
||||
target = gameobj;
|
||||
|
||||
if (target)
|
||||
target->RegisterActuator(actuator);
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* BL_ArmatureActuator::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
|
||||
BL_ArmatureConstraint* constraint = actuator->m_constraint;
|
||||
if (!constraint)
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
return constraint->GetProxy();
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureActuator.h 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef BL_ARMATUREACTUATOR
|
||||
#define BL_ARMATUREACTUATOR
|
||||
|
||||
#include "SCA_IActuator.h"
|
||||
#include "BL_ArmatureConstraint.h"
|
||||
|
||||
/**
|
||||
* This class is the conversion of the Pose channel constraint.
|
||||
* It makes a link between the pose constraint and the KX scene.
|
||||
* The main purpose is to give access to the constraint target
|
||||
* to link it to a game object.
|
||||
* It also allows to activate/deactivate constraints during the game.
|
||||
* Later it will also be possible to create constraint on the fly
|
||||
*/
|
||||
|
||||
class BL_ArmatureActuator : public SCA_IActuator
|
||||
{
|
||||
Py_Header;
|
||||
public:
|
||||
BL_ArmatureActuator(SCA_IObject* gameobj,
|
||||
int type,
|
||||
const char *posechannel,
|
||||
const char *constraintname,
|
||||
KX_GameObject* targetobj,
|
||||
KX_GameObject* subtargetobj,
|
||||
float weight);
|
||||
|
||||
virtual ~BL_ArmatureActuator();
|
||||
|
||||
virtual CValue* GetReplica() {
|
||||
BL_ArmatureActuator* replica = new BL_ArmatureActuator(*this);
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
};
|
||||
virtual void ProcessReplica();
|
||||
virtual bool UnlinkObject(SCA_IObject* clientobj);
|
||||
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
|
||||
virtual bool Update(double curtime, bool frame);
|
||||
virtual void ReParent(SCA_IObject* parent);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* These are used to get and set m_target */
|
||||
static PyObject* pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
private:
|
||||
// identify the constraint that this actuator controls
|
||||
void FindConstraint();
|
||||
|
||||
BL_ArmatureConstraint* m_constraint;
|
||||
KX_GameObject* m_gametarget;
|
||||
KX_GameObject* m_gamesubtarget;
|
||||
STR_String m_posechannel;
|
||||
STR_String m_constraintname;
|
||||
float m_weight;
|
||||
int m_type;
|
||||
};
|
||||
|
||||
#endif //BL_ARMATUREACTUATOR
|
||||
|
||||
|
||||
@@ -1,465 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureChannel.cpp 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "BL_ArmatureChannel.h"
|
||||
#include "BL_ArmatureObject.h"
|
||||
#include "BL_ArmatureConstraint.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
PyTypeObject BL_ArmatureChannel::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ArmatureChannel",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&CValue::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyObject* BL_ArmatureChannel::py_repr(void)
|
||||
{
|
||||
return PyUnicode_FromString(m_posechannel->name);
|
||||
}
|
||||
|
||||
PyObject *BL_ArmatureChannel::GetProxy()
|
||||
{
|
||||
return GetProxyPlus_Ext(this, &Type, m_posechannel);
|
||||
}
|
||||
|
||||
PyObject *BL_ArmatureChannel::NewProxy(bool py_owns)
|
||||
{
|
||||
return NewProxyPlus_Ext(this, &Type, m_posechannel, py_owns);
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
BL_ArmatureChannel::BL_ArmatureChannel(
|
||||
BL_ArmatureObject *armature,
|
||||
bPoseChannel *posechannel)
|
||||
: PyObjectPlus(), m_posechannel(posechannel), m_armature(armature)
|
||||
{
|
||||
}
|
||||
|
||||
BL_ArmatureChannel::~BL_ArmatureChannel()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
// PYTHON
|
||||
|
||||
PyMethodDef BL_ArmatureChannel::Methods[] = {
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
// order of definition of attributes, must match Attributes[] array
|
||||
#define BCA_BONE 0
|
||||
#define BCA_PARENT 1
|
||||
|
||||
PyAttributeDef BL_ArmatureChannel::Attributes[] = {
|
||||
// Keep these attributes in order of BCA_ defines!!! used by py_attr_getattr and py_attr_setattr
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("bone",BL_ArmatureChannel,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("parent",BL_ArmatureChannel,py_attr_getattr),
|
||||
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
/* attributes directly taken from bPoseChannel */
|
||||
PyAttributeDef BL_ArmatureChannel::AttributesPtr[] = {
|
||||
KX_PYATTRIBUTE_CHAR_RO("name",bPoseChannel,name),
|
||||
KX_PYATTRIBUTE_FLAG_RO("is_in_ik_chain",bPoseChannel,flag, POSE_CHAIN),
|
||||
KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_x",bPoseChannel,ikflag, BONE_IK_NO_XDOF),
|
||||
KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_y",bPoseChannel,ikflag, BONE_IK_NO_YDOF),
|
||||
KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("ik_dof_z",bPoseChannel,ikflag, BONE_IK_NO_ZDOF),
|
||||
KX_PYATTRIBUTE_FLAG_RO("use_ik_limit_x",bPoseChannel,ikflag, BONE_IK_XLIMIT),
|
||||
KX_PYATTRIBUTE_FLAG_RO("use_ik_limit_y",bPoseChannel,ikflag, BONE_IK_YLIMIT),
|
||||
KX_PYATTRIBUTE_FLAG_RO("use_ik_limit_z",bPoseChannel,ikflag, BONE_IK_ZLIMIT),
|
||||
KX_PYATTRIBUTE_FLAG_RO("use_ik_rotation_control",bPoseChannel,ikflag, BONE_IK_ROTCTL),
|
||||
KX_PYATTRIBUTE_FLAG_RO("use_ik_linear_control",bPoseChannel,ikflag, BONE_IK_LINCTL),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RW("location",-FLT_MAX,FLT_MAX,bPoseChannel,loc,3),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RW("scale",-FLT_MAX,FLT_MAX,bPoseChannel,size,3),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RW("rotation_quaternion",-1.0f,1.0f,bPoseChannel,quat,4),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RW("rotation_euler",-10.f,10.f,bPoseChannel,eul,3),
|
||||
KX_PYATTRIBUTE_SHORT_RW("rotation_mode",0,ROT_MODE_MAX-1,false,bPoseChannel,rotmode),
|
||||
KX_PYATTRIBUTE_FLOAT_MATRIX_RO("channel_matrix",bPoseChannel,chan_mat,4),
|
||||
KX_PYATTRIBUTE_FLOAT_MATRIX_RO("pose_matrix",bPoseChannel,pose_mat,4),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("pose_head",bPoseChannel,pose_head,3),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("pose_tail",bPoseChannel,pose_tail,3),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_min_x",bPoseChannel,limitmin[0]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_max_x",bPoseChannel,limitmax[0]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_min_y",bPoseChannel,limitmin[1]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_max_y",bPoseChannel,limitmax[1]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_min_z",bPoseChannel,limitmin[2]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_max_z",bPoseChannel,limitmax[2]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_x",bPoseChannel,stiffness[0]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_y",bPoseChannel,stiffness[1]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_stiffness_z",bPoseChannel,stiffness[2]),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("ik_stretch",bPoseChannel,ikstretch),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("ik_rotation_weight",0,1.0f,bPoseChannel,ikrotweight),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("ik_linear_weight",0,1.0f,bPoseChannel,iklinweight),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("joint_rotation",BL_ArmatureChannel,py_attr_get_joint_rotation,py_attr_set_joint_rotation),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* BL_ArmatureChannel::py_attr_getattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
|
||||
bPoseChannel* channel = self->m_posechannel;
|
||||
int attr_order = attrdef-Attributes;
|
||||
|
||||
if (!channel) {
|
||||
PyErr_SetString(PyExc_AttributeError, "channel is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (attr_order) {
|
||||
case BCA_BONE:
|
||||
// bones are standalone proxy
|
||||
return NewProxyPlus_Ext(NULL,&BL_ArmatureBone::Type,channel->bone,false);
|
||||
case BCA_PARENT:
|
||||
{
|
||||
BL_ArmatureChannel* parent = self->m_armature->GetChannel(channel->parent);
|
||||
if (parent)
|
||||
return parent->GetProxy();
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_AttributeError, "channel unknown attribute");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int BL_ArmatureChannel::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
|
||||
bPoseChannel* channel = self->m_posechannel;
|
||||
int attr_order = attrdef-Attributes;
|
||||
|
||||
// int ival;
|
||||
// double dval;
|
||||
// char* sval;
|
||||
// KX_GameObject *oval;
|
||||
|
||||
if (!channel) {
|
||||
PyErr_SetString(PyExc_AttributeError, "channel is NULL");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
switch (attr_order) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_AttributeError, "channel unknown attribute");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
|
||||
bPoseChannel* pchan = self->m_posechannel;
|
||||
// decompose the pose matrix in euler rotation
|
||||
float rest_mat[3][3];
|
||||
float pose_mat[3][3];
|
||||
float joint_mat[3][3];
|
||||
float joints[3];
|
||||
float norm;
|
||||
double sa, ca;
|
||||
// get rotation in armature space
|
||||
copy_m3_m4(pose_mat, pchan->pose_mat);
|
||||
normalize_m3(pose_mat);
|
||||
if (pchan->parent) {
|
||||
// bone has a parent, compute the rest pose of the bone taking actual pose of parent
|
||||
mul_m3_m3m4(rest_mat, pchan->bone->bone_mat, pchan->parent->pose_mat);
|
||||
normalize_m3(rest_mat);
|
||||
} else {
|
||||
// otherwise, the bone matrix in armature space is the rest pose
|
||||
copy_m3_m4(rest_mat, pchan->bone->arm_mat);
|
||||
}
|
||||
// remove the rest pose to get the joint movement
|
||||
transpose_m3(rest_mat);
|
||||
mul_m3_m3m3(joint_mat, rest_mat, pose_mat);
|
||||
joints[0] = joints[1] = joints[2] = 0.f;
|
||||
// returns a 3 element list that gives corresponding joint
|
||||
int flag = 0;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_XDOF))
|
||||
flag |= 1;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_YDOF))
|
||||
flag |= 2;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
|
||||
flag |= 4;
|
||||
switch (flag) {
|
||||
case 0: // fixed joint
|
||||
break;
|
||||
case 1: // X only
|
||||
mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
|
||||
joints[1] = joints[2] = 0.f;
|
||||
break;
|
||||
case 2: // Y only
|
||||
mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
|
||||
joints[0] = joints[2] = 0.f;
|
||||
break;
|
||||
case 3: // X+Y
|
||||
mat3_to_eulO( joints, EULER_ORDER_ZYX,joint_mat);
|
||||
joints[2] = 0.f;
|
||||
break;
|
||||
case 4: // Z only
|
||||
mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
|
||||
joints[0] = joints[1] = 0.f;
|
||||
break;
|
||||
case 5: // X+Z
|
||||
// decompose this as an equivalent rotation vector in X/Z plane
|
||||
joints[0] = joint_mat[1][2];
|
||||
joints[2] = -joint_mat[1][0];
|
||||
norm = normalize_v3(joints);
|
||||
if (norm < FLT_EPSILON) {
|
||||
norm = (joint_mat[1][1] < 0.f) ? M_PI : 0.f;
|
||||
} else {
|
||||
norm = acos(joint_mat[1][1]);
|
||||
}
|
||||
mul_v3_fl(joints, norm);
|
||||
break;
|
||||
case 6: // Y+Z
|
||||
mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
|
||||
joints[0] = 0.f;
|
||||
break;
|
||||
case 7: // X+Y+Z
|
||||
// equivalent axis
|
||||
joints[0] = (joint_mat[1][2]-joint_mat[2][1])*0.5f;
|
||||
joints[1] = (joint_mat[2][0]-joint_mat[0][2])*0.5f;
|
||||
joints[2] = (joint_mat[0][1]-joint_mat[1][0])*0.5f;
|
||||
sa = len_v3(joints);
|
||||
ca = (joint_mat[0][0]+joint_mat[1][1]+joint_mat[1][1]-1.0f)*0.5f;
|
||||
if (sa > FLT_EPSILON) {
|
||||
norm = atan2(sa,ca)/sa;
|
||||
} else {
|
||||
if (ca < 0.0) {
|
||||
norm = M_PI;
|
||||
mul_v3_fl(joints,0.f);
|
||||
if (joint_mat[0][0] > 0.f) {
|
||||
joints[0] = 1.0f;
|
||||
} else if (joint_mat[1][1] > 0.f) {
|
||||
joints[1] = 1.0f;
|
||||
} else {
|
||||
joints[2] = 1.0f;
|
||||
}
|
||||
} else {
|
||||
norm = 0.0;
|
||||
}
|
||||
}
|
||||
mul_v3_fl(joints,norm);
|
||||
break;
|
||||
}
|
||||
return newVectorObject(joints, 3, Py_NEW, NULL);
|
||||
}
|
||||
|
||||
int BL_ArmatureChannel::py_attr_set_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
|
||||
bPoseChannel* pchan = self->m_posechannel;
|
||||
PyObject *item;
|
||||
float joints[3];
|
||||
float quat[4];
|
||||
|
||||
if (!PySequence_Check(value) || PySequence_Size(value) != 3) {
|
||||
PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
for (int i=0; i<3; i++) {
|
||||
item = PySequence_GetItem(value, i); /* new ref */
|
||||
joints[i] = PyFloat_AsDouble(item);
|
||||
Py_DECREF(item);
|
||||
if (joints[i] == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int flag = 0;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_XDOF))
|
||||
flag |= 1;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_YDOF))
|
||||
flag |= 2;
|
||||
if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
|
||||
flag |= 4;
|
||||
unit_qt(quat);
|
||||
switch (flag) {
|
||||
case 0: // fixed joint
|
||||
break;
|
||||
case 1: // X only
|
||||
joints[1] = joints[2] = 0.f;
|
||||
eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
|
||||
break;
|
||||
case 2: // Y only
|
||||
joints[0] = joints[2] = 0.f;
|
||||
eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
|
||||
break;
|
||||
case 3: // X+Y
|
||||
joints[2] = 0.f;
|
||||
eulO_to_quat( quat,joints, EULER_ORDER_ZYX);
|
||||
break;
|
||||
case 4: // Z only
|
||||
joints[0] = joints[1] = 0.f;
|
||||
eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
|
||||
break;
|
||||
case 5: // X+Z
|
||||
// X and Z are components of an equivalent rotation axis
|
||||
joints[1] = 0;
|
||||
axis_angle_to_quat( quat,joints, len_v3(joints));
|
||||
break;
|
||||
case 6: // Y+Z
|
||||
joints[0] = 0.f;
|
||||
eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
|
||||
break;
|
||||
case 7: // X+Y+Z
|
||||
// equivalent axis
|
||||
axis_angle_to_quat( quat,joints, len_v3(joints));
|
||||
break;
|
||||
}
|
||||
if (pchan->rotmode > 0) {
|
||||
quat_to_eulO( joints, pchan->rotmode,quat);
|
||||
copy_v3_v3(pchan->eul, joints);
|
||||
} else
|
||||
copy_qt_qt(pchan->quat, quat);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
// *************************
|
||||
// BL_ArmatureBone
|
||||
//
|
||||
// Access to Bone structure
|
||||
PyTypeObject BL_ArmatureBone::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ArmatureBone",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_bone_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&CValue::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
// not used since this class is never instantiated
|
||||
PyObject *BL_ArmatureBone::GetProxy()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
PyObject *BL_ArmatureBone::NewProxy(bool py_owns)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *BL_ArmatureBone::py_bone_repr(PyObject *self)
|
||||
{
|
||||
Bone* bone = static_cast<Bone*>BGE_PROXY_PTR(self);
|
||||
return PyUnicode_FromString(bone->name);
|
||||
}
|
||||
|
||||
PyMethodDef BL_ArmatureBone::Methods[] = {
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
/* no attributes on C++ class since it is never instantiated */
|
||||
PyAttributeDef BL_ArmatureBone::Attributes[] = {
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
// attributes that work on proxy ptr (points to a Bone structure)
|
||||
PyAttributeDef BL_ArmatureBone::AttributesPtr[] = {
|
||||
KX_PYATTRIBUTE_CHAR_RO("name",Bone,name),
|
||||
KX_PYATTRIBUTE_FLAG_RO("connected",Bone,flag, BONE_CONNECTED),
|
||||
KX_PYATTRIBUTE_FLAG_RO("hinge",Bone,flag, BONE_HINGE),
|
||||
KX_PYATTRIBUTE_FLAG_NEGATIVE_RO("inherit_scale",Bone,flag, BONE_NO_SCALE),
|
||||
KX_PYATTRIBUTE_SHORT_RO("bbone_segments",Bone,segments),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("roll",Bone,roll),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("head",Bone,head,3),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("tail",Bone,tail,3),
|
||||
KX_PYATTRIBUTE_FLOAT_RO("length",Bone,length),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("arm_head",Bone,arm_head,3),
|
||||
KX_PYATTRIBUTE_FLOAT_VECTOR_RO("arm_tail",Bone,arm_tail,3),
|
||||
KX_PYATTRIBUTE_FLOAT_MATRIX_RO("arm_mat",Bone,arm_mat,4),
|
||||
KX_PYATTRIBUTE_FLOAT_MATRIX_RO("bone_mat",Bone,bone_mat,4),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("parent",BL_ArmatureBone,py_bone_get_parent),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("children",BL_ArmatureBone,py_bone_get_children),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject *BL_ArmatureBone::py_bone_get_parent(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
Bone* bone = reinterpret_cast<Bone*>(self);
|
||||
if (bone->parent) {
|
||||
// create a proxy unconnected to any GE object
|
||||
return NewProxyPlus_Ext(NULL,&Type,bone->parent,false);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *BL_ArmatureBone::py_bone_get_children(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
Bone* bone = reinterpret_cast<Bone*>(self);
|
||||
Bone* child;
|
||||
int count = 0;
|
||||
for (child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next)
|
||||
count++;
|
||||
|
||||
PyObject* childrenlist = PyList_New(count);
|
||||
|
||||
for (count = 0, child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next, ++count)
|
||||
PyList_SET_ITEM(childrenlist,count,NewProxyPlus_Ext(NULL,&Type,child,false));
|
||||
|
||||
return childrenlist;
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureChannel.h 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BL_ARMATURECHANNEL
|
||||
#define __BL_ARMATURECHANNEL
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "PyObjectPlus.h"
|
||||
|
||||
class SCA_IObject;
|
||||
class KX_GameObject;
|
||||
class BL_ArmatureObject;
|
||||
struct bConstraint;
|
||||
struct bPoseChannel;
|
||||
struct Object;
|
||||
struct bPose;
|
||||
|
||||
class BL_ArmatureChannel : public PyObjectPlus
|
||||
{
|
||||
// use Py_HeaderPtr since we use generic pointer in proxy
|
||||
Py_HeaderPtr;
|
||||
|
||||
private:
|
||||
friend class BL_ArmatureObject;
|
||||
struct bPoseChannel* m_posechannel;
|
||||
BL_ArmatureObject* m_armature;
|
||||
|
||||
public:
|
||||
BL_ArmatureChannel(class BL_ArmatureObject *armature,
|
||||
struct bPoseChannel *posechannel);
|
||||
virtual ~BL_ArmatureChannel();
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
// Python access
|
||||
virtual PyObject* py_repr(void);
|
||||
|
||||
static PyObject* py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* py_attr_get_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int py_attr_set_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
#endif // DISABLE_PYTHON
|
||||
};
|
||||
|
||||
/* this is a factory class to access bBone data field in the GE.
|
||||
It's not supposed to be instantiated, we only need it for the Attributes and Method array.
|
||||
The actual proxy object will be manually created using NewProxyPtr */
|
||||
class BL_ArmatureBone : public PyObjectPlus
|
||||
{
|
||||
// use Py_HeaderPtr since we use generic pointer in proxy
|
||||
Py_HeaderPtr;
|
||||
private:
|
||||
// make constructor private to make sure no one tries to instantiate this class
|
||||
BL_ArmatureBone() {}
|
||||
virtual ~BL_ArmatureBone() {}
|
||||
|
||||
public:
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
static PyObject *py_bone_repr(PyObject *self);
|
||||
static PyObject *py_bone_get_parent(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *py_bone_get_children(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //__BL_ARMATURECHANNEL
|
||||
|
||||
@@ -1,450 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureConstraint.cpp 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "BL_ArmatureConstraint.h"
|
||||
#include "BL_ArmatureObject.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
PyTypeObject BL_ArmatureConstraint::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ArmatureConstraint",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&CValue::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyObject* BL_ArmatureConstraint::py_repr(void)
|
||||
{
|
||||
return PyUnicode_FromString(m_name);
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
BL_ArmatureConstraint::BL_ArmatureConstraint(
|
||||
BL_ArmatureObject *armature,
|
||||
bPoseChannel *posechannel,
|
||||
bConstraint *constraint,
|
||||
KX_GameObject* target,
|
||||
KX_GameObject* subtarget)
|
||||
: PyObjectPlus(), m_constraint(constraint), m_posechannel(posechannel), m_armature(armature)
|
||||
{
|
||||
m_target = target;
|
||||
m_blendtarget = (target) ? target->GetBlenderObject() : NULL;
|
||||
m_subtarget = subtarget;
|
||||
m_blendsubtarget = (subtarget) ? subtarget->GetBlenderObject() : NULL;
|
||||
m_pose = m_subpose = NULL;
|
||||
if (m_blendtarget) {
|
||||
copy_m4_m4(m_blendmat, m_blendtarget->obmat);
|
||||
if (m_blendtarget->type == OB_ARMATURE)
|
||||
m_pose = m_blendtarget->pose;
|
||||
}
|
||||
if (m_blendsubtarget) {
|
||||
copy_m4_m4(m_blendsubmat, m_blendsubtarget->obmat);
|
||||
if (m_blendsubtarget->type == OB_ARMATURE)
|
||||
m_subpose = m_blendsubtarget->pose;
|
||||
}
|
||||
if (m_target)
|
||||
m_target->RegisterObject(m_armature);
|
||||
if (m_subtarget)
|
||||
m_subtarget->RegisterObject(m_armature);
|
||||
BLI_snprintf(m_name, sizeof(m_name), "%s:%s", m_posechannel->name, m_constraint->name);
|
||||
}
|
||||
|
||||
BL_ArmatureConstraint::~BL_ArmatureConstraint()
|
||||
{
|
||||
if (m_target)
|
||||
m_target->UnregisterObject(m_armature);
|
||||
if (m_subtarget)
|
||||
m_subtarget->UnregisterObject(m_armature);
|
||||
}
|
||||
|
||||
BL_ArmatureConstraint* BL_ArmatureConstraint::GetReplica() const
|
||||
{
|
||||
BL_ArmatureConstraint* replica = new BL_ArmatureConstraint(*this);
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::ReParent(BL_ArmatureObject* armature)
|
||||
{
|
||||
m_armature = armature;
|
||||
if (m_target)
|
||||
m_target->RegisterObject(armature);
|
||||
if (m_subtarget)
|
||||
m_subtarget->RegisterObject(armature);
|
||||
// find the corresponding constraint in the new armature object
|
||||
if (m_constraint) {
|
||||
bPose* newpose = armature->GetOrigPose();
|
||||
char* constraint = m_constraint->name;
|
||||
char* posechannel = m_posechannel->name;
|
||||
bPoseChannel* pchan;
|
||||
bConstraint* pcon;
|
||||
m_constraint = NULL;
|
||||
m_posechannel = NULL;
|
||||
// and locate the constraint
|
||||
for (pchan = (bPoseChannel*)newpose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
|
||||
if (!strcmp(pchan->name, posechannel)) {
|
||||
// now locate the constraint
|
||||
for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
|
||||
if (!strcmp(pcon->name, constraint)) {
|
||||
m_constraint = pcon;
|
||||
m_posechannel = pchan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
|
||||
{
|
||||
void **h_obj = (*obj_map)[m_target];
|
||||
if (h_obj) {
|
||||
m_target->UnregisterObject(m_armature);
|
||||
m_target = (KX_GameObject*)(*h_obj);
|
||||
m_target->RegisterObject(m_armature);
|
||||
}
|
||||
h_obj = (*obj_map)[m_subtarget];
|
||||
if (h_obj) {
|
||||
m_subtarget->UnregisterObject(m_armature);
|
||||
m_subtarget = (KX_GameObject*)(*h_obj);
|
||||
m_subtarget->RegisterObject(m_armature);
|
||||
}
|
||||
}
|
||||
|
||||
bool BL_ArmatureConstraint::UnlinkObject(SCA_IObject* clientobj)
|
||||
{
|
||||
bool res=false;
|
||||
if (clientobj == m_target) {
|
||||
m_target = NULL;
|
||||
res = true;
|
||||
}
|
||||
if (clientobj == m_subtarget) {
|
||||
m_subtarget = NULL;
|
||||
res = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::UpdateTarget()
|
||||
{
|
||||
if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
|
||||
if (m_blendtarget) {
|
||||
// external target, must be updated
|
||||
m_target->UpdateBlenderObjectMatrix(m_blendtarget);
|
||||
if (m_pose && m_target->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
|
||||
// update the pose in case a bone is specified in the constraint target
|
||||
m_blendtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
|
||||
}
|
||||
if (m_blendsubtarget && m_subtarget) {
|
||||
m_subtarget->UpdateBlenderObjectMatrix(m_blendsubtarget);
|
||||
if (m_subpose && m_subtarget->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
|
||||
m_blendsubtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::RestoreTarget()
|
||||
{
|
||||
if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
|
||||
if (m_blendtarget) {
|
||||
copy_m4_m4(m_blendtarget->obmat, m_blendmat);
|
||||
if (m_pose)
|
||||
m_blendtarget->pose = m_pose;
|
||||
}
|
||||
if (m_blendsubtarget && m_subtarget) {
|
||||
copy_m4_m4(m_blendsubtarget->obmat, m_blendsubmat);
|
||||
if (m_subpose)
|
||||
m_blendsubtarget->pose = m_subpose;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BL_ArmatureConstraint::Match(const char* posechannel, const char* constraint)
|
||||
{
|
||||
return (!strcmp(m_posechannel->name, posechannel) && !strcmp(m_constraint->name, constraint));
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::SetTarget(KX_GameObject* target)
|
||||
{
|
||||
if (m_blendtarget) {
|
||||
if (target != m_target) {
|
||||
m_target->UnregisterObject(m_armature);
|
||||
m_target = target;
|
||||
if (m_target)
|
||||
m_target->RegisterObject(m_armature);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BL_ArmatureConstraint::SetSubtarget(KX_GameObject* subtarget)
|
||||
{
|
||||
if (m_blendsubtarget) {
|
||||
if (subtarget != m_subtarget) {
|
||||
m_subtarget->UnregisterObject(m_armature);
|
||||
m_subtarget = subtarget;
|
||||
if (m_subtarget)
|
||||
m_subtarget->RegisterObject(m_armature);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
// PYTHON
|
||||
|
||||
PyMethodDef BL_ArmatureConstraint::Methods[] = {
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
// order of definition of attributes, must match Attributes[] array
|
||||
#define BCA_TYPE 0
|
||||
#define BCA_NAME 1
|
||||
#define BCA_ENFORCE 2
|
||||
#define BCA_HEADTAIL 3
|
||||
#define BCA_LINERROR 4
|
||||
#define BCA_ROTERROR 5
|
||||
#define BCA_TARGET 6
|
||||
#define BCA_SUBTARGET 7
|
||||
#define BCA_ACTIVE 8
|
||||
#define BCA_IKWEIGHT 9
|
||||
#define BCA_IKTYPE 10
|
||||
#define BCA_IKFLAG 11
|
||||
#define BCA_IKDIST 12
|
||||
#define BCA_IKMODE 13
|
||||
|
||||
PyAttributeDef BL_ArmatureConstraint::Attributes[] = {
|
||||
// Keep these attributes in order of BCA_ defines!!! used by py_attr_getattr and py_attr_setattr
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("type",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("name",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("enforce",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("headtail",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("error_location",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("error_rotation",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("target",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("subtarget",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("active",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("ik_weight",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("ik_type",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("ik_flag",BL_ArmatureConstraint,py_attr_getattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("ik_dist",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("ik_mode",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
|
||||
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
|
||||
PyObject* BL_ArmatureConstraint::py_attr_getattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureConstraint* self= static_cast<BL_ArmatureConstraint*>(self_v);
|
||||
bConstraint* constraint = self->m_constraint;
|
||||
bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
|
||||
int attr_order = attrdef-Attributes;
|
||||
|
||||
if (!constraint) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (attr_order) {
|
||||
case BCA_TYPE:
|
||||
return PyLong_FromLong(constraint->type);
|
||||
case BCA_NAME:
|
||||
return PyUnicode_FromString(constraint->name);
|
||||
case BCA_ENFORCE:
|
||||
return PyFloat_FromDouble(constraint->enforce);
|
||||
case BCA_HEADTAIL:
|
||||
return PyFloat_FromDouble(constraint->headtail);
|
||||
case BCA_LINERROR:
|
||||
return PyFloat_FromDouble(constraint->lin_error);
|
||||
case BCA_ROTERROR:
|
||||
return PyFloat_FromDouble(constraint->rot_error);
|
||||
case BCA_TARGET:
|
||||
if (!self->m_target)
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
return self->m_target->GetProxy();
|
||||
case BCA_SUBTARGET:
|
||||
if (!self->m_subtarget)
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
return self->m_subtarget->GetProxy();
|
||||
case BCA_ACTIVE:
|
||||
return PyBool_FromLong(constraint->flag & CONSTRAINT_OFF);
|
||||
case BCA_IKWEIGHT:
|
||||
case BCA_IKTYPE:
|
||||
case BCA_IKFLAG:
|
||||
case BCA_IKDIST:
|
||||
case BCA_IKMODE:
|
||||
if (!ikconstraint) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
|
||||
return NULL;
|
||||
}
|
||||
switch (attr_order) {
|
||||
case BCA_IKWEIGHT:
|
||||
return PyFloat_FromDouble((ikconstraint)?ikconstraint->weight:0.0);
|
||||
case BCA_IKTYPE:
|
||||
return PyLong_FromLong(ikconstraint->type);
|
||||
case BCA_IKFLAG:
|
||||
return PyLong_FromLong(ikconstraint->flag);
|
||||
case BCA_IKDIST:
|
||||
return PyFloat_FromDouble(ikconstraint->dist);
|
||||
case BCA_IKMODE:
|
||||
return PyLong_FromLong(ikconstraint->mode);
|
||||
}
|
||||
// should not come here
|
||||
break;
|
||||
}
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ArmatureConstraint* self= static_cast<BL_ArmatureConstraint*>(self_v);
|
||||
bConstraint* constraint = self->m_constraint;
|
||||
bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
|
||||
int attr_order = attrdef-Attributes;
|
||||
int ival;
|
||||
double dval;
|
||||
// char* sval;
|
||||
KX_GameObject *oval;
|
||||
|
||||
if (!constraint) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
switch (attr_order) {
|
||||
case BCA_ENFORCE:
|
||||
dval = PyFloat_AsDouble(value);
|
||||
if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.enforce = float: BL_ArmatureConstraint, expected a float between 0 and 1");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
constraint->enforce = dval;
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_HEADTAIL:
|
||||
dval = PyFloat_AsDouble(value);
|
||||
if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.headtail = float: BL_ArmatureConstraint, expected a float between 0 and 1");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
constraint->headtail = dval;
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_TARGET:
|
||||
if (!ConvertPythonToGameObject(value, &oval, true, "constraint.target = value: BL_ArmatureConstraint"))
|
||||
return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
|
||||
self->SetTarget(oval);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_SUBTARGET:
|
||||
if (!ConvertPythonToGameObject(value, &oval, true, "constraint.subtarget = value: BL_ArmatureConstraint"))
|
||||
return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
|
||||
self->SetSubtarget(oval);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_ACTIVE:
|
||||
ival = PyObject_IsTrue( value );
|
||||
if (ival == -1) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.active = bool: BL_ArmatureConstraint, expected True or False");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
self->m_constraint->flag = (self->m_constraint->flag & ~CONSTRAINT_OFF) | ((ival)?0:CONSTRAINT_OFF);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_IKWEIGHT:
|
||||
case BCA_IKDIST:
|
||||
case BCA_IKMODE:
|
||||
if (!ikconstraint) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
switch (attr_order) {
|
||||
case BCA_IKWEIGHT:
|
||||
dval = PyFloat_AsDouble(value);
|
||||
if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.weight = float: BL_ArmatureConstraint, expected a float between 0 and 1");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
ikconstraint->weight = dval;
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_IKDIST:
|
||||
dval = PyFloat_AsDouble(value);
|
||||
if (dval < 0.0f) { /* also accounts for non float */
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.ik_dist = float: BL_ArmatureConstraint, expected a positive float");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
ikconstraint->dist = dval;
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
case BCA_IKMODE:
|
||||
ival = PyLong_AsLong(value);
|
||||
if (ival < 0) {
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint.ik_mode = integer: BL_ArmatureConstraint, expected a positive integer");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
ikconstraint->mode = ival;
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
// should not come here
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* $Id: BL_ArmatureConstraint.h 23562 2009-09-29 21:42:40Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BL_ARMATURECONSTRAINT
|
||||
#define __BL_ARMATURECONSTRAINT
|
||||
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "PyObjectPlus.h"
|
||||
|
||||
class SCA_IObject;
|
||||
class KX_GameObject;
|
||||
class BL_ArmatureObject;
|
||||
struct bConstraint;
|
||||
struct bPoseChannel;
|
||||
struct Object;
|
||||
struct bPose;
|
||||
|
||||
/**
|
||||
* SG_DList : element of controlled constraint list
|
||||
* head = BL_ArmatureObject::m_controlledConstraints
|
||||
* SG_QList : not used
|
||||
*/
|
||||
class BL_ArmatureConstraint : public PyObjectPlus
|
||||
{
|
||||
Py_Header;
|
||||
|
||||
private:
|
||||
struct bConstraint* m_constraint;
|
||||
struct bPoseChannel* m_posechannel;
|
||||
class BL_ArmatureObject* m_armature;
|
||||
char m_name[64];
|
||||
KX_GameObject* m_target;
|
||||
KX_GameObject* m_subtarget;
|
||||
struct Object* m_blendtarget;
|
||||
struct Object* m_blendsubtarget;
|
||||
float m_blendmat[4][4];
|
||||
float m_blendsubmat[4][4];
|
||||
struct bPose* m_pose;
|
||||
struct bPose* m_subpose;
|
||||
|
||||
public:
|
||||
BL_ArmatureConstraint(class BL_ArmatureObject *armature,
|
||||
struct bPoseChannel *posechannel,
|
||||
struct bConstraint *constraint,
|
||||
KX_GameObject* target,
|
||||
KX_GameObject* subtarget);
|
||||
virtual ~BL_ArmatureConstraint();
|
||||
|
||||
BL_ArmatureConstraint* GetReplica() const;
|
||||
void ReParent(BL_ArmatureObject* armature);
|
||||
void Relink(GEN_Map<GEN_HashedPtr, void*> *map);
|
||||
bool UnlinkObject(SCA_IObject* clientobj);
|
||||
|
||||
void UpdateTarget();
|
||||
void RestoreTarget();
|
||||
|
||||
bool Match(const char* posechannel, const char* constraint);
|
||||
const char* GetName() { return m_name; }
|
||||
|
||||
void SetConstraintFlag(int flag)
|
||||
{
|
||||
if (m_constraint)
|
||||
m_constraint->flag |= flag;
|
||||
}
|
||||
void ClrConstraintFlag(int flag)
|
||||
{
|
||||
if (m_constraint)
|
||||
m_constraint->flag &= ~flag;
|
||||
}
|
||||
void SetWeight(float weight)
|
||||
{
|
||||
if (m_constraint && m_constraint->type == CONSTRAINT_TYPE_KINEMATIC && m_constraint->data) {
|
||||
bKinematicConstraint* con = (bKinematicConstraint*)m_constraint->data;
|
||||
con->weight = weight;
|
||||
}
|
||||
}
|
||||
void SetTarget(KX_GameObject* target);
|
||||
void SetSubtarget(KX_GameObject* subtarget);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
// Python access
|
||||
virtual PyObject* py_repr(void);
|
||||
|
||||
static PyObject* py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
#endif // DISABLE_PYTHON
|
||||
};
|
||||
|
||||
#endif //__BL_ARMATURECONSTRAINT
|
||||
|
||||
@@ -1,663 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "BL_ArmatureObject.h"
|
||||
#include "BL_ActionActuator.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BIK_api.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_nla_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "KX_PythonSeq.h"
|
||||
#include "KX_PythonInit.h"
|
||||
#include "KX_KetsjiEngine.h"
|
||||
|
||||
#include "MT_Matrix4x4.h"
|
||||
|
||||
/**
|
||||
* Move here pose function for game engine so that we can mix with GE objects
|
||||
* Principle is as follow:
|
||||
* Use Blender structures so that where_is_pose can be used unchanged
|
||||
* Copy the constraint so that they can be enabled/disabled/added/removed at runtime
|
||||
* Don't copy the constraints for the pose used by the Action actuator, it does not need them.
|
||||
* Scan the constraint structures so that the KX equivalent of target objects are identified and
|
||||
* stored in separate list.
|
||||
* When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
|
||||
* Blender objects and restore after the evaluation.
|
||||
*/
|
||||
void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) {
|
||||
bPose *out;
|
||||
bPoseChannel *pchan, *outpchan;
|
||||
GHash *ghash;
|
||||
|
||||
/* the game engine copies the current armature pose and then swaps
|
||||
* the object pose pointer. this makes it possible to change poses
|
||||
* without affecting the original blender data. */
|
||||
|
||||
if (!src) {
|
||||
*dst=NULL;
|
||||
return;
|
||||
}
|
||||
else if (*dst==src) {
|
||||
printf("copy_pose source and target are the same\n");
|
||||
*dst=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
out= (bPose*)MEM_dupallocN(src);
|
||||
out->chanhash = NULL;
|
||||
out->agroups.first= out->agroups.last= NULL;
|
||||
out->ikdata = NULL;
|
||||
out->ikparam = MEM_dupallocN(out->ikparam);
|
||||
out->flag |= POSE_GAME_ENGINE;
|
||||
BLI_duplicatelist(&out->chanbase, &src->chanbase);
|
||||
|
||||
/* remap pointers */
|
||||
ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "game_copy_pose gh");
|
||||
|
||||
pchan= (bPoseChannel*)src->chanbase.first;
|
||||
outpchan= (bPoseChannel*)out->chanbase.first;
|
||||
for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
|
||||
BLI_ghash_insert(ghash, pchan, outpchan);
|
||||
|
||||
for (pchan=(bPoseChannel*)out->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
|
||||
pchan->parent= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->parent);
|
||||
pchan->child= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->child);
|
||||
pchan->path= NULL;
|
||||
|
||||
if (copy_constraint) {
|
||||
ListBase listb;
|
||||
// copy all constraint for backward compatibility
|
||||
copy_constraints(&listb, &pchan->constraints, FALSE); // copy_constraints NULLs listb, no need to make extern for this operation.
|
||||
pchan->constraints= listb;
|
||||
} else {
|
||||
pchan->constraints.first = NULL;
|
||||
pchan->constraints.last = NULL;
|
||||
}
|
||||
|
||||
// fails to link, props are not used in the BGE yet.
|
||||
/* if(pchan->prop)
|
||||
pchan->prop= IDP_CopyProperty(pchan->prop); */
|
||||
pchan->prop= NULL;
|
||||
}
|
||||
|
||||
BLI_ghash_free(ghash, NULL, NULL);
|
||||
// set acceleration structure for channel lookup
|
||||
make_pose_channels_hash(out);
|
||||
*dst=out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Only allowed for Poses with identical channels */
|
||||
void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
|
||||
{
|
||||
short mode= ACTSTRIPMODE_BLEND;
|
||||
|
||||
bPoseChannel *dchan;
|
||||
const bPoseChannel *schan;
|
||||
bConstraint *dcon, *scon;
|
||||
float dstweight;
|
||||
int i;
|
||||
|
||||
switch (mode){
|
||||
case ACTSTRIPMODE_BLEND:
|
||||
dstweight = 1.0F - srcweight;
|
||||
break;
|
||||
case ACTSTRIPMODE_ADD:
|
||||
dstweight = 1.0F;
|
||||
break;
|
||||
default :
|
||||
dstweight = 1.0F;
|
||||
}
|
||||
|
||||
schan= (bPoseChannel*)src->chanbase.first;
|
||||
for (dchan = (bPoseChannel*)dst->chanbase.first; dchan; dchan=(bPoseChannel*)dchan->next, schan= (bPoseChannel*)schan->next){
|
||||
// always blend on all channels since we don't know which one has been set
|
||||
/* quat interpolation done separate */
|
||||
if (schan->rotmode == ROT_MODE_QUAT) {
|
||||
float dquat[4], squat[4];
|
||||
|
||||
QUATCOPY(dquat, dchan->quat);
|
||||
QUATCOPY(squat, schan->quat);
|
||||
if (mode==ACTSTRIPMODE_BLEND)
|
||||
interp_qt_qtqt(dchan->quat, dquat, squat, srcweight);
|
||||
else {
|
||||
mul_fac_qt_fl(squat, srcweight);
|
||||
mul_qt_qtqt(dchan->quat, dquat, squat);
|
||||
}
|
||||
|
||||
normalize_qt(dchan->quat);
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
/* blending for loc and scale are pretty self-explanatory... */
|
||||
dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
|
||||
dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
|
||||
|
||||
/* euler-rotation interpolation done here instead... */
|
||||
// FIXME: are these results decent?
|
||||
if (schan->rotmode)
|
||||
dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
|
||||
}
|
||||
for(dcon= (bConstraint*)dchan->constraints.first, scon= (bConstraint*)schan->constraints.first; dcon && scon; dcon= (bConstraint*)dcon->next, scon= (bConstraint*)scon->next) {
|
||||
/* no 'add' option for constraint blending */
|
||||
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
/* this pose is now in src time */
|
||||
dst->ctime= src->ctime;
|
||||
}
|
||||
|
||||
void game_free_pose(bPose *pose)
|
||||
{
|
||||
if (pose) {
|
||||
/* free pose-channels and constraints */
|
||||
free_pose_channels(pose);
|
||||
|
||||
/* free IK solver state */
|
||||
BIK_clear_data(pose);
|
||||
|
||||
/* free IK solver param */
|
||||
if (pose->ikparam)
|
||||
MEM_freeN(pose->ikparam);
|
||||
|
||||
MEM_freeN(pose);
|
||||
}
|
||||
}
|
||||
|
||||
BL_ArmatureObject::BL_ArmatureObject(
|
||||
void* sgReplicationInfo,
|
||||
SG_Callbacks callbacks,
|
||||
Object *armature,
|
||||
Scene *scene)
|
||||
|
||||
: KX_GameObject(sgReplicationInfo,callbacks),
|
||||
m_controlledConstraints(),
|
||||
m_poseChannels(),
|
||||
m_objArma(armature),
|
||||
m_framePose(NULL),
|
||||
m_scene(scene), // maybe remove later. needed for where_is_pose
|
||||
m_lastframe(0.0),
|
||||
m_timestep(0.040),
|
||||
m_activeAct(NULL),
|
||||
m_activePriority(999),
|
||||
m_constraintNumber(0),
|
||||
m_channelNumber(0),
|
||||
m_lastapplyframe(0.0)
|
||||
{
|
||||
m_armature = (bArmature *)armature->data;
|
||||
|
||||
/* we make a copy of blender object's pose, and then always swap it with
|
||||
* the original pose before calling into blender functions, to deal with
|
||||
* replica's or other objects using the same blender object */
|
||||
m_pose = NULL;
|
||||
game_copy_pose(&m_pose, m_objArma->pose, 1);
|
||||
// store the original armature object matrix
|
||||
memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
|
||||
}
|
||||
|
||||
BL_ArmatureObject::~BL_ArmatureObject()
|
||||
{
|
||||
BL_ArmatureConstraint* constraint;
|
||||
while ((constraint = m_controlledConstraints.Remove()) != NULL) {
|
||||
delete constraint;
|
||||
}
|
||||
BL_ArmatureChannel* channel;
|
||||
while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
|
||||
delete channel;
|
||||
}
|
||||
if (m_pose)
|
||||
game_free_pose(m_pose);
|
||||
if (m_framePose)
|
||||
game_free_pose(m_framePose);
|
||||
}
|
||||
|
||||
|
||||
void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
|
||||
{
|
||||
// first delete any existing constraint (should not have any)
|
||||
while (!m_controlledConstraints.Empty()) {
|
||||
BL_ArmatureConstraint* constraint = m_controlledConstraints.Remove();
|
||||
delete constraint;
|
||||
}
|
||||
m_constraintNumber = 0;
|
||||
|
||||
// list all the constraint and convert them to BL_ArmatureConstraint
|
||||
// get the persistent pose structure
|
||||
bPoseChannel* pchan;
|
||||
bConstraint* pcon;
|
||||
bConstraintTypeInfo* cti;
|
||||
Object* blendtarget;
|
||||
KX_GameObject* gametarget;
|
||||
KX_GameObject* gamesubtarget;
|
||||
|
||||
// and locate the constraint
|
||||
for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
|
||||
for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
|
||||
if (pcon->flag & CONSTRAINT_DISABLE)
|
||||
continue;
|
||||
// which constraint should we support?
|
||||
switch (pcon->type) {
|
||||
case CONSTRAINT_TYPE_TRACKTO:
|
||||
case CONSTRAINT_TYPE_KINEMATIC:
|
||||
case CONSTRAINT_TYPE_ROTLIKE:
|
||||
case CONSTRAINT_TYPE_LOCLIKE:
|
||||
case CONSTRAINT_TYPE_MINMAX:
|
||||
case CONSTRAINT_TYPE_SIZELIKE:
|
||||
case CONSTRAINT_TYPE_LOCKTRACK:
|
||||
case CONSTRAINT_TYPE_STRETCHTO:
|
||||
case CONSTRAINT_TYPE_CLAMPTO:
|
||||
case CONSTRAINT_TYPE_TRANSFORM:
|
||||
case CONSTRAINT_TYPE_DISTLIMIT:
|
||||
cti = constraint_get_typeinfo(pcon);
|
||||
gametarget = gamesubtarget = NULL;
|
||||
if (cti && cti->get_constraint_targets) {
|
||||
ListBase listb = { NULL, NULL };
|
||||
cti->get_constraint_targets(pcon, &listb);
|
||||
if (listb.first) {
|
||||
bConstraintTarget* target = (bConstraintTarget*)listb.first;
|
||||
if (target->tar && target->tar != m_objArma) {
|
||||
// only remember external objects, self target is handled automatically
|
||||
blendtarget = target->tar;
|
||||
gametarget = converter->FindGameObject(blendtarget);
|
||||
}
|
||||
if (target->next != NULL) {
|
||||
// secondary target
|
||||
target = (bConstraintTarget*)target->next;
|
||||
if (target->tar && target->tar != m_objArma) {
|
||||
// only track external object
|
||||
blendtarget = target->tar;
|
||||
gamesubtarget = converter->FindGameObject(blendtarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cti->flush_constraint_targets)
|
||||
cti->flush_constraint_targets(pcon, &listb, 1);
|
||||
}
|
||||
BL_ArmatureConstraint* constraint = new BL_ArmatureConstraint(this, pchan, pcon, gametarget, gamesubtarget);
|
||||
m_controlledConstraints.AddBack(constraint);
|
||||
m_constraintNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannel, const char* constraintname)
|
||||
{
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
BL_ArmatureConstraint* constraint = *cit;
|
||||
if (constraint->Match(posechannel, constraintname))
|
||||
return constraint;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannelconstraint)
|
||||
{
|
||||
// performance: use hash string instead of plain string compare
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
BL_ArmatureConstraint* constraint = *cit;
|
||||
if (!strcmp(constraint->GetName(), posechannelconstraint))
|
||||
return constraint;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(int index)
|
||||
{
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end() && index; ++cit, --index);
|
||||
return (cit.end()) ? NULL : *cit;
|
||||
}
|
||||
|
||||
/* this function is called to populate the m_poseChannels list */
|
||||
void BL_ArmatureObject::LoadChannels()
|
||||
{
|
||||
if (m_poseChannels.Empty()) {
|
||||
bPoseChannel* pchan;
|
||||
BL_ArmatureChannel* proxy;
|
||||
|
||||
m_channelNumber = 0;
|
||||
for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
|
||||
proxy = new BL_ArmatureChannel(this, pchan);
|
||||
m_poseChannels.AddBack(proxy);
|
||||
m_channelNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BL_ArmatureChannel* BL_ArmatureObject::GetChannel(bPoseChannel* pchan)
|
||||
{
|
||||
LoadChannels();
|
||||
SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
|
||||
for (cit.begin(); !cit.end(); ++cit)
|
||||
{
|
||||
BL_ArmatureChannel* channel = *cit;
|
||||
if (channel->m_posechannel == pchan)
|
||||
return channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BL_ArmatureChannel* BL_ArmatureObject::GetChannel(const char* str)
|
||||
{
|
||||
LoadChannels();
|
||||
SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
|
||||
for (cit.begin(); !cit.end(); ++cit)
|
||||
{
|
||||
BL_ArmatureChannel* channel = *cit;
|
||||
if (!strcmp(channel->m_posechannel->name, str))
|
||||
return channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BL_ArmatureChannel* BL_ArmatureObject::GetChannel(int index)
|
||||
{
|
||||
LoadChannels();
|
||||
if (index < 0 || index >= m_channelNumber)
|
||||
return NULL;
|
||||
SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
|
||||
for (cit.begin(); !cit.end() && index; ++cit, --index);
|
||||
return (cit.end()) ? NULL : *cit;
|
||||
}
|
||||
|
||||
CValue* BL_ArmatureObject::GetReplica()
|
||||
{
|
||||
BL_ArmatureObject* replica = new BL_ArmatureObject(*this);
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::ProcessReplica()
|
||||
{
|
||||
bPose *pose= m_pose;
|
||||
KX_GameObject::ProcessReplica();
|
||||
|
||||
m_pose = NULL;
|
||||
m_framePose = NULL;
|
||||
game_copy_pose(&m_pose, pose, 1);
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::ReParentLogic()
|
||||
{
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
(*cit)->ReParent(this);
|
||||
}
|
||||
KX_GameObject::ReParentLogic();
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
|
||||
{
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
(*cit)->Relink(obj_map);
|
||||
}
|
||||
KX_GameObject::Relink(obj_map);
|
||||
}
|
||||
|
||||
bool BL_ArmatureObject::UnlinkObject(SCA_IObject* clientobj)
|
||||
{
|
||||
// clientobj is being deleted, make sure we don't hold any reference to it
|
||||
bool res = false;
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
res |= (*cit)->UnlinkObject(clientobj);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::ApplyPose()
|
||||
{
|
||||
m_armpose = m_objArma->pose;
|
||||
m_objArma->pose = m_pose;
|
||||
// in the GE, we use ctime to store the timestep
|
||||
m_pose->ctime = (float)m_timestep;
|
||||
//m_scene->r.cfra++;
|
||||
if(m_lastapplyframe != m_lastframe) {
|
||||
// update the constraint if any, first put them all off so that only the active ones will be updated
|
||||
SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
(*cit)->UpdateTarget();
|
||||
}
|
||||
// update ourself
|
||||
UpdateBlenderObjectMatrix(m_objArma);
|
||||
where_is_pose(m_scene, m_objArma); // XXX
|
||||
// restore ourself
|
||||
memcpy(m_objArma->obmat, m_obmat, sizeof(m_obmat));
|
||||
// restore active targets
|
||||
for (cit.begin(); !cit.end(); ++cit) {
|
||||
(*cit)->RestoreTarget();
|
||||
}
|
||||
m_lastapplyframe = m_lastframe;
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::RestorePose()
|
||||
{
|
||||
m_objArma->pose = m_armpose;
|
||||
m_armpose = NULL;
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::SetPose(bPose *pose)
|
||||
{
|
||||
extract_pose_from_pose(m_pose, pose);
|
||||
m_lastapplyframe = -1.0;
|
||||
}
|
||||
|
||||
bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, double curtime)
|
||||
{
|
||||
if (curtime != m_lastframe){
|
||||
m_activePriority = 9999;
|
||||
// compute the timestep for the underlying IK algorithm
|
||||
m_timestep = curtime-m_lastframe;
|
||||
m_lastframe= curtime;
|
||||
m_activeAct = NULL;
|
||||
// remember the pose at the start of the frame
|
||||
GetPose(&m_framePose);
|
||||
}
|
||||
|
||||
if (act)
|
||||
{
|
||||
if (priority<=m_activePriority)
|
||||
{
|
||||
if (priority<m_activePriority) {
|
||||
// this action overwrites the previous ones, start from initial pose to cancel their effects
|
||||
SetPose(m_framePose);
|
||||
if (m_activeAct && (m_activeAct!=act))
|
||||
/* Reset the blend timer since this new action cancels the old one */
|
||||
m_activeAct->SetBlendTime(0.0);
|
||||
}
|
||||
m_activeAct = act;
|
||||
m_activePriority = priority;
|
||||
m_lastframe = curtime;
|
||||
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
act->SetBlendTime(0.0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
|
||||
{
|
||||
return m_activeAct;
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::GetPose(bPose **pose)
|
||||
{
|
||||
/* If the caller supplies a null pose, create a new one. */
|
||||
/* Otherwise, copy the armature's pose channels into the caller-supplied pose */
|
||||
|
||||
if (!*pose) {
|
||||
/* probably not to good of an idea to
|
||||
duplicate everying, but it clears up
|
||||
a crash and memory leakage when
|
||||
&BL_ActionActuator::m_pose is freed
|
||||
*/
|
||||
game_copy_pose(pose, m_pose, 0);
|
||||
}
|
||||
else {
|
||||
if (*pose == m_pose)
|
||||
// no need to copy if the pointers are the same
|
||||
return;
|
||||
|
||||
extract_pose_from_pose(*pose, m_pose);
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ArmatureObject::GetMRDPose(bPose **pose)
|
||||
{
|
||||
/* If the caller supplies a null pose, create a new one. */
|
||||
/* Otherwise, copy the armature's pose channels into the caller-supplied pose */
|
||||
|
||||
if (!*pose)
|
||||
game_copy_pose(pose, m_pose, 0);
|
||||
else
|
||||
extract_pose_from_pose(*pose, m_pose);
|
||||
}
|
||||
|
||||
short BL_ArmatureObject::GetActivePriority()
|
||||
{
|
||||
return m_activePriority;
|
||||
}
|
||||
|
||||
double BL_ArmatureObject::GetLastFrame()
|
||||
{
|
||||
return m_lastframe;
|
||||
}
|
||||
|
||||
bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix)
|
||||
{
|
||||
bPoseChannel *pchan;
|
||||
|
||||
ApplyPose();
|
||||
pchan = get_pose_channel(m_objArma->pose, bone->name);
|
||||
if(pchan)
|
||||
matrix.setValue(&pchan->pose_mat[0][0]);
|
||||
RestorePose();
|
||||
|
||||
return (pchan != NULL);
|
||||
}
|
||||
|
||||
float BL_ArmatureObject::GetBoneLength(Bone* bone) const
|
||||
{
|
||||
return (float)(MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
// PYTHON
|
||||
|
||||
PyTypeObject BL_ArmatureObject::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ArmatureObject",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,
|
||||
&KX_GameObject::Sequence,
|
||||
&KX_GameObject::Mapping,
|
||||
0,0,0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&KX_GameObject::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyMethodDef BL_ArmatureObject::Methods[] = {
|
||||
|
||||
KX_PYMETHODTABLE_NOARGS(BL_ArmatureObject, update),
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef BL_ArmatureObject::Attributes[] = {
|
||||
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("constraints", BL_ArmatureObject, pyattr_get_constraints),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("channels", BL_ArmatureObject, pyattr_get_channels),
|
||||
{NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyObject* BL_ArmatureObject::pyattr_get_constraints(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
return KX_PythonSeq_CreatePyObject((static_cast<BL_ArmatureObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CONSTRAINTS);
|
||||
}
|
||||
|
||||
PyObject* BL_ArmatureObject::pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ArmatureObject* self = static_cast<BL_ArmatureObject*>(self_v);
|
||||
self->LoadChannels(); // make sure we have the channels
|
||||
return KX_PythonSeq_CreatePyObject((static_cast<BL_ArmatureObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CHANNELS);
|
||||
}
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(BL_ArmatureObject, update,
|
||||
"update()\n"
|
||||
"Make sure that the armature will be updated on next graphic frame.\n"
|
||||
"This is automatically done if a KX_ArmatureActuator with mode run is active\n"
|
||||
"or if an action is playing. This function is usefull in other cases.\n")
|
||||
{
|
||||
SetActiveAction(NULL, 0, KX_GetActiveEngine()->GetFrameTime());
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,151 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_ARMATUREOBJECT
|
||||
#define BL_ARMATUREOBJECT
|
||||
|
||||
#include "KX_GameObject.h"
|
||||
#include "BL_ArmatureConstraint.h"
|
||||
#include "BL_ArmatureChannel.h"
|
||||
|
||||
#include "SG_IObject.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
struct bArmature;
|
||||
struct Bone;
|
||||
struct bConstraint;
|
||||
class BL_ActionActuator;
|
||||
class BL_ArmatureActuator;
|
||||
class MT_Matrix4x4;
|
||||
struct Object;
|
||||
class KX_BlenderSceneConverter;
|
||||
|
||||
class BL_ArmatureObject : public KX_GameObject
|
||||
{
|
||||
Py_Header;
|
||||
public:
|
||||
|
||||
double GetLastFrame ();
|
||||
short GetActivePriority();
|
||||
virtual void ProcessReplica();
|
||||
virtual void ReParentLogic();
|
||||
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
|
||||
virtual bool UnlinkObject(SCA_IObject* clientobj);
|
||||
|
||||
class BL_ActionActuator * GetActiveAction();
|
||||
|
||||
BL_ArmatureObject(
|
||||
void* sgReplicationInfo,
|
||||
SG_Callbacks callbacks,
|
||||
Object *armature,
|
||||
Scene *scene
|
||||
);
|
||||
virtual ~BL_ArmatureObject();
|
||||
|
||||
virtual CValue* GetReplica();
|
||||
void GetMRDPose(struct bPose **pose);
|
||||
void GetPose(struct bPose **pose);
|
||||
void SetPose (struct bPose *pose);
|
||||
struct bPose *GetOrigPose() {return m_pose;} // never edit this, only for accessing names
|
||||
|
||||
void ApplyPose();
|
||||
void RestorePose();
|
||||
|
||||
bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
|
||||
|
||||
struct bArmature * GetArmature() { return m_armature; }
|
||||
const struct bArmature * GetArmature() const { return m_armature; }
|
||||
const struct Scene * GetScene() const { return m_scene; }
|
||||
|
||||
Object* GetArmatureObject() {return m_objArma;}
|
||||
|
||||
// for constraint python API
|
||||
void LoadConstraints(KX_BlenderSceneConverter* converter);
|
||||
size_t GetConstraintNumber() const { return m_constraintNumber; }
|
||||
BL_ArmatureConstraint* GetConstraint(const char* posechannel, const char* constraint);
|
||||
BL_ArmatureConstraint* GetConstraint(const char* posechannelconstraint);
|
||||
BL_ArmatureConstraint* GetConstraint(int index);
|
||||
// for pose channel python API
|
||||
void LoadChannels();
|
||||
size_t GetChannelNumber() const { return m_constraintNumber; }
|
||||
BL_ArmatureChannel* GetChannel(bPoseChannel* channel);
|
||||
BL_ArmatureChannel* GetChannel(const char* channel);
|
||||
BL_ArmatureChannel* GetChannel(int index);
|
||||
|
||||
/// Retrieve the pose matrix for the specified bone.
|
||||
/// Returns true on success.
|
||||
bool GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix);
|
||||
|
||||
/// Returns the bone length. The end of the bone is in the local y direction.
|
||||
float GetBoneLength(Bone* bone) const;
|
||||
|
||||
virtual int GetGameObjectType() { return OBJ_ARMATURE; }
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
// PYTHON
|
||||
static PyObject* pyattr_get_constraints(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
KX_PYMETHOD_DOC_NOARGS(BL_ArmatureObject, update);
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
protected:
|
||||
/* list element: BL_ArmatureConstraint. Use SG_DListHead to have automatic list replication */
|
||||
SG_DListHead<BL_ArmatureConstraint> m_controlledConstraints;
|
||||
/* list element: BL_ArmatureChannel. Use SG_DList to avoid list replication */
|
||||
SG_DList m_poseChannels;
|
||||
Object *m_objArma;
|
||||
struct bArmature *m_armature;
|
||||
struct bPose *m_pose;
|
||||
struct bPose *m_armpose;
|
||||
struct bPose *m_framePose;
|
||||
struct Scene *m_scene; // need for where_is_pose
|
||||
double m_lastframe;
|
||||
double m_timestep; // delta since last pose evaluation.
|
||||
class BL_ActionActuator *m_activeAct;
|
||||
short m_activePriority;
|
||||
size_t m_constraintNumber;
|
||||
size_t m_channelNumber;
|
||||
// store the original armature object matrix
|
||||
float m_obmat[4][4];
|
||||
|
||||
double m_lastapplyframe;
|
||||
};
|
||||
|
||||
/* Pose function specific to the game engine */
|
||||
void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
|
||||
//void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
|
||||
void game_copy_pose(struct bPose **dst, struct bPose *src, int copy_con);
|
||||
void game_free_pose(struct bPose *pose);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BLENDER_CONVERT
|
||||
#define __BLENDER_CONVERT
|
||||
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "STR_String.h"
|
||||
#include "KX_Python.h"
|
||||
#include "KX_PhysicsEngineEnums.h"
|
||||
|
||||
class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
|
||||
|
||||
void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
class KX_Scene* kxscene,
|
||||
class KX_KetsjiEngine* ketsjiEngine,
|
||||
e_PhysicsEngine physics_engine,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas,
|
||||
class KX_BlenderSceneConverter* sceneconverter,
|
||||
bool alwaysUseExpandFraming
|
||||
);
|
||||
|
||||
#endif // __BLENDER_CONVERT
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "BL_DeformableGameObject.h"
|
||||
#include "BL_ShapeDeformer.h"
|
||||
#include "BL_ShapeActionActuator.h"
|
||||
#include "RAS_MaterialBucket.h"
|
||||
|
||||
|
||||
BL_DeformableGameObject::~BL_DeformableGameObject()
|
||||
{
|
||||
if (m_pDeformer)
|
||||
delete m_pDeformer; // __NLA : Temporary until we decide where to put this
|
||||
}
|
||||
|
||||
void BL_DeformableGameObject::ProcessReplica()
|
||||
{
|
||||
KX_GameObject::ProcessReplica();
|
||||
|
||||
if (m_pDeformer)
|
||||
m_pDeformer= (BL_MeshDeformer*)m_pDeformer->GetReplica();
|
||||
}
|
||||
|
||||
CValue* BL_DeformableGameObject::GetReplica()
|
||||
{
|
||||
|
||||
BL_DeformableGameObject* replica = new BL_DeformableGameObject(*this);//m_float,GetName());
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
bool BL_DeformableGameObject::SetActiveAction(BL_ShapeActionActuator *act, short priority, double curtime)
|
||||
{
|
||||
if (curtime != m_lastframe){
|
||||
m_activePriority = 9999;
|
||||
m_lastframe= curtime;
|
||||
m_activeAct = NULL;
|
||||
}
|
||||
|
||||
if (priority<=m_activePriority)
|
||||
{
|
||||
if (m_activeAct && (m_activeAct!=act))
|
||||
m_activeAct->SetBlendTime(0.0f); /* Reset the blend timer */
|
||||
m_activeAct = act;
|
||||
m_activePriority = priority;
|
||||
m_lastframe = curtime;
|
||||
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
act->SetBlendTime(0.0f);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BL_DeformableGameObject::GetShape(vector<float> &shape)
|
||||
{
|
||||
shape.clear();
|
||||
if (m_pDeformer)
|
||||
{
|
||||
Mesh* mesh = ((BL_MeshDeformer*)m_pDeformer)->GetMesh();
|
||||
// this check is normally superfluous: a shape deformer can only be created if the mesh
|
||||
// has relative keys
|
||||
if (mesh && mesh->key && mesh->key->type==KEY_RELATIVE)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
for (kb = (KeyBlock*)mesh->key->block.first; kb; kb = (KeyBlock*)kb->next)
|
||||
{
|
||||
shape.push_back(kb->curval);
|
||||
}
|
||||
}
|
||||
}
|
||||
return !shape.empty();
|
||||
}
|
||||
|
||||
void BL_DeformableGameObject::SetDeformer(class RAS_Deformer* deformer)
|
||||
{
|
||||
m_pDeformer = deformer;
|
||||
|
||||
SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
|
||||
for(mit.begin(); !mit.end(); ++mit)
|
||||
{
|
||||
(*mit)->SetDeformer(deformer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_DEFORMABLEGAMEOBJECT
|
||||
#define BL_DEFORMABLEGAMEOBJECT
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "BL_MeshDeformer.h"
|
||||
#include <vector>
|
||||
|
||||
class BL_ShapeActionActuator;
|
||||
struct Key;
|
||||
|
||||
class BL_DeformableGameObject : public KX_GameObject
|
||||
{
|
||||
public:
|
||||
CValue* GetReplica();
|
||||
|
||||
double GetLastFrame ()
|
||||
{
|
||||
return m_lastframe;
|
||||
}
|
||||
Object* GetBlendObject()
|
||||
{
|
||||
return m_blendobj;
|
||||
}
|
||||
virtual void Relink(GEN_Map<GEN_HashedPtr, void*>*map)
|
||||
{
|
||||
if (m_pDeformer)
|
||||
m_pDeformer->Relink (map);
|
||||
KX_GameObject::Relink(map);
|
||||
};
|
||||
void ProcessReplica();
|
||||
|
||||
BL_DeformableGameObject(Object* blendobj, void* sgReplicationInfo, SG_Callbacks callbacks) :
|
||||
KX_GameObject(sgReplicationInfo,callbacks),
|
||||
m_pDeformer(NULL),
|
||||
m_activeAct(NULL),
|
||||
m_lastframe(0.),
|
||||
m_blendobj(blendobj),
|
||||
m_activePriority(9999)
|
||||
{
|
||||
m_isDeformable = true;
|
||||
};
|
||||
virtual ~BL_DeformableGameObject();
|
||||
bool SetActiveAction(class BL_ShapeActionActuator *act, short priority, double curtime);
|
||||
|
||||
bool GetShape(vector<float> &shape);
|
||||
Key* GetKey()
|
||||
{
|
||||
return (m_pDeformer) ? ((BL_MeshDeformer*)m_pDeformer)->GetMesh()->key : NULL;
|
||||
}
|
||||
|
||||
virtual void SetDeformer(class RAS_Deformer* deformer);
|
||||
virtual class RAS_Deformer* GetDeformer()
|
||||
{
|
||||
return m_pDeformer;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
protected:
|
||||
|
||||
RAS_Deformer *m_pDeformer;
|
||||
|
||||
class BL_ShapeActionActuator *m_activeAct;
|
||||
double m_lastframe;
|
||||
Object* m_blendobj;
|
||||
short m_activePriority;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_DeformableGameObject"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* Simple deformation controller that restores a mesh to its rest position
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
// This warning tells us about truncation of __long__ stl-generated names.
|
||||
// It can occasionally cause DevStudio to have internal compiler warnings.
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
#include "BL_DeformableGameObject.h"
|
||||
#include "BL_MeshDeformer.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "GEN_Map.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// only apply once per frame if the mesh is actually modified
|
||||
if(m_pMeshObject->MeshModified() &&
|
||||
m_lastDeformUpdate != m_gameobj->GetLastFrame()) {
|
||||
// For each material
|
||||
for(list<RAS_MeshMaterial>::iterator mit= m_pMeshObject->GetFirstMaterial();
|
||||
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
|
||||
if(!mit->m_slots[(void*)m_gameobj])
|
||||
continue;
|
||||
|
||||
RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj];
|
||||
RAS_MeshSlot::iterator it;
|
||||
|
||||
// for each array
|
||||
for(slot->begin(it); !slot->end(it); slot->next(it)) {
|
||||
// For each vertex
|
||||
for(i=it.startvertex; i<it.endvertex; i++) {
|
||||
RAS_TexVert& v = it.vertex[i];
|
||||
v.SetXYZ(m_bmesh->mvert[v.getOrigIndex()].co);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lastDeformUpdate = m_gameobj->GetLastFrame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BL_MeshDeformer::~BL_MeshDeformer()
|
||||
{
|
||||
if (m_transverts)
|
||||
delete [] m_transverts;
|
||||
if (m_transnors)
|
||||
delete [] m_transnors;
|
||||
}
|
||||
|
||||
void BL_MeshDeformer::ProcessReplica()
|
||||
{
|
||||
m_transverts = NULL;
|
||||
m_transnors = NULL;
|
||||
m_tvtot = 0;
|
||||
m_bDynamic=false;
|
||||
m_lastDeformUpdate = -1;
|
||||
}
|
||||
|
||||
void BL_MeshDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
|
||||
{
|
||||
void **h_obj = (*map)[m_gameobj];
|
||||
|
||||
if (h_obj)
|
||||
m_gameobj = (BL_DeformableGameObject*)(*h_obj);
|
||||
else
|
||||
m_gameobj = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning This function is expensive!
|
||||
*/
|
||||
void BL_MeshDeformer::RecalcNormals()
|
||||
{
|
||||
/* We don't normalize for performance, not doing it for faces normals
|
||||
* gives area-weight normals which often look better anyway, and use
|
||||
* GL_NORMALIZE so we don't have to do per vertex normalization either
|
||||
* since the GPU can do it faster */
|
||||
list<RAS_MeshMaterial>::iterator mit;
|
||||
RAS_MeshSlot::iterator it;
|
||||
size_t i;
|
||||
|
||||
/* set vertex normals to zero */
|
||||
memset(m_transnors, 0, sizeof(float)*3*m_bmesh->totvert);
|
||||
|
||||
/* add face normals to vertices. */
|
||||
for(mit = m_pMeshObject->GetFirstMaterial();
|
||||
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
|
||||
if(!mit->m_slots[(void*)m_gameobj])
|
||||
continue;
|
||||
|
||||
RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj];
|
||||
|
||||
for(slot->begin(it); !slot->end(it); slot->next(it)) {
|
||||
int nvert = (int)it.array->m_type;
|
||||
|
||||
for(i=0; i<it.totindex; i+=nvert) {
|
||||
RAS_TexVert& v1 = it.vertex[it.index[i]];
|
||||
RAS_TexVert& v2 = it.vertex[it.index[i+1]];
|
||||
RAS_TexVert& v3 = it.vertex[it.index[i+2]];
|
||||
RAS_TexVert *v4 = NULL;
|
||||
|
||||
const float *co1 = m_transverts[v1.getOrigIndex()];
|
||||
const float *co2 = m_transverts[v2.getOrigIndex()];
|
||||
const float *co3 = m_transverts[v3.getOrigIndex()];
|
||||
const float *co4 = NULL;
|
||||
|
||||
/* compute face normal */
|
||||
float fnor[3], n1[3], n2[3];
|
||||
|
||||
if(nvert == 4) {
|
||||
v4 = &it.vertex[it.index[i+3]];
|
||||
co4 = m_transverts[v4->getOrigIndex()];
|
||||
|
||||
n1[0]= co1[0]-co3[0];
|
||||
n1[1]= co1[1]-co3[1];
|
||||
n1[2]= co1[2]-co3[2];
|
||||
|
||||
n2[0]= co2[0]-co4[0];
|
||||
n2[1]= co2[1]-co4[1];
|
||||
n2[2]= co2[2]-co4[2];
|
||||
}
|
||||
else {
|
||||
n1[0]= co1[0]-co2[0];
|
||||
n2[0]= co2[0]-co3[0];
|
||||
n1[1]= co1[1]-co2[1];
|
||||
|
||||
n2[1]= co2[1]-co3[1];
|
||||
n1[2]= co1[2]-co2[2];
|
||||
n2[2]= co2[2]-co3[2];
|
||||
}
|
||||
|
||||
fnor[0]= n1[1]*n2[2] - n1[2]*n2[1];
|
||||
fnor[1]= n1[2]*n2[0] - n1[0]*n2[2];
|
||||
fnor[2]= n1[0]*n2[1] - n1[1]*n2[0];
|
||||
normalize_v3(fnor);
|
||||
|
||||
/* add to vertices for smooth normals */
|
||||
float *vn1 = m_transnors[v1.getOrigIndex()];
|
||||
float *vn2 = m_transnors[v2.getOrigIndex()];
|
||||
float *vn3 = m_transnors[v3.getOrigIndex()];
|
||||
|
||||
vn1[0] += fnor[0]; vn1[1] += fnor[1]; vn1[2] += fnor[2];
|
||||
vn2[0] += fnor[0]; vn2[1] += fnor[1]; vn2[2] += fnor[2];
|
||||
vn3[0] += fnor[0]; vn3[1] += fnor[1]; vn3[2] += fnor[2];
|
||||
|
||||
if(v4) {
|
||||
float *vn4 = m_transnors[v4->getOrigIndex()];
|
||||
vn4[0] += fnor[0]; vn4[1] += fnor[1]; vn4[2] += fnor[2];
|
||||
}
|
||||
|
||||
/* in case of flat - just assign, the vertices are split */
|
||||
if(v1.getFlag() & RAS_TexVert::FLAT) {
|
||||
v1.SetNormal(fnor);
|
||||
v2.SetNormal(fnor);
|
||||
v3.SetNormal(fnor);
|
||||
if(v4)
|
||||
v4->SetNormal(fnor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* assign smooth vertex normals */
|
||||
for(mit = m_pMeshObject->GetFirstMaterial();
|
||||
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
|
||||
if(!mit->m_slots[(void*)m_gameobj])
|
||||
continue;
|
||||
|
||||
RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj];
|
||||
|
||||
for(slot->begin(it); !slot->end(it); slot->next(it)) {
|
||||
for(i=it.startvertex; i<it.endvertex; i++) {
|
||||
RAS_TexVert& v = it.vertex[i];
|
||||
|
||||
if(!(v.getFlag() & RAS_TexVert::FLAT))
|
||||
v.SetNormal(m_transnors[v.getOrigIndex()]); //.safe_normalized()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BL_MeshDeformer::VerifyStorage()
|
||||
{
|
||||
/* Ensure that we have the right number of verts assigned */
|
||||
if (m_tvtot!=m_bmesh->totvert){
|
||||
if (m_transverts)
|
||||
delete [] m_transverts;
|
||||
if (m_transnors)
|
||||
delete [] m_transnors;
|
||||
|
||||
m_transverts=new float[m_bmesh->totvert][3];
|
||||
m_transnors=new float[m_bmesh->totvert][3];
|
||||
m_tvtot = m_bmesh->totvert;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_MESHDEFORMER
|
||||
#define BL_MESHDEFORMER
|
||||
|
||||
#include "RAS_Deformer.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "MT_Point3.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
class BL_DeformableGameObject;
|
||||
|
||||
class BL_MeshDeformer : public RAS_Deformer
|
||||
{
|
||||
public:
|
||||
void VerifyStorage();
|
||||
void RecalcNormals();
|
||||
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map);
|
||||
BL_MeshDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Object* obj,
|
||||
class RAS_MeshObject *meshobj ):
|
||||
m_pMeshObject(meshobj),
|
||||
m_bmesh((struct Mesh*)(obj->data)),
|
||||
m_transverts(0),
|
||||
m_transnors(0),
|
||||
m_objMesh(obj),
|
||||
m_tvtot(0),
|
||||
m_gameobj(gameobj),
|
||||
m_lastDeformUpdate(-1)
|
||||
{};
|
||||
virtual ~BL_MeshDeformer();
|
||||
virtual void SetSimulatedTime(double time){};
|
||||
virtual bool Apply(class RAS_IPolyMaterial *mat);
|
||||
virtual bool Update(void){ return false; };
|
||||
virtual bool UpdateBuckets(void){ return false; };
|
||||
virtual RAS_Deformer* GetReplica(){return NULL;};
|
||||
virtual void ProcessReplica();
|
||||
struct Mesh* GetMesh() { return m_bmesh; };
|
||||
virtual class RAS_MeshObject* GetRasMesh() { return (RAS_MeshObject*)m_pMeshObject; };
|
||||
virtual float (* GetTransVerts(int *tot))[3] { *tot= m_tvtot; return m_transverts; }
|
||||
// virtual void InitDeform(double time){};
|
||||
|
||||
protected:
|
||||
class RAS_MeshObject* m_pMeshObject;
|
||||
struct Mesh* m_bmesh;
|
||||
|
||||
// this is so m_transverts doesn't need to be converted
|
||||
// before deformation
|
||||
float (*m_transverts)[3];
|
||||
float (*m_transnors)[3];
|
||||
struct Object* m_objMesh;
|
||||
// --
|
||||
int m_tvtot;
|
||||
BL_DeformableGameObject* m_gameobj;
|
||||
double m_lastDeformUpdate;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_MeshDeformer"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BL_ModifierDeformer.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
#include "PHY_IGraphicController.h"
|
||||
|
||||
//#include "BL_ArmatureController.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "MT_Point3.h"
|
||||
|
||||
extern "C"{
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_modifier.h"
|
||||
}
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#define __NLA_DEFNORMALS
|
||||
//#undef __NLA_DEFNORMALS
|
||||
|
||||
|
||||
BL_ModifierDeformer::~BL_ModifierDeformer()
|
||||
{
|
||||
if (m_dm) {
|
||||
// deformedOnly is used as a user counter
|
||||
if (--m_dm->deformedOnly == 0) {
|
||||
m_dm->needsFree = 1;
|
||||
m_dm->release(m_dm);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RAS_Deformer *BL_ModifierDeformer::GetReplica()
|
||||
{
|
||||
BL_ModifierDeformer *result;
|
||||
|
||||
result = new BL_ModifierDeformer(*this);
|
||||
result->ProcessReplica();
|
||||
return result;
|
||||
}
|
||||
|
||||
void BL_ModifierDeformer::ProcessReplica()
|
||||
{
|
||||
/* Note! - This is not inherited from PyObjectPlus */
|
||||
BL_ShapeDeformer::ProcessReplica();
|
||||
if (m_dm)
|
||||
// by default try to reuse mesh, deformedOnly is used as a user count
|
||||
m_dm->deformedOnly++;
|
||||
// this will force an update and if the mesh cannot be reused, a new one will be created
|
||||
m_lastModifierUpdate = -1;
|
||||
}
|
||||
|
||||
bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob)
|
||||
{
|
||||
if (!ob->modifiers.first)
|
||||
return false;
|
||||
// soft body cannot use mesh modifiers
|
||||
if ((ob->gameflag & OB_SOFT_BODY) != 0)
|
||||
return false;
|
||||
ModifierData* md;
|
||||
for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) {
|
||||
if (modifier_dependsOnTime(md))
|
||||
continue;
|
||||
if (!(md->mode & eModifierMode_Realtime))
|
||||
continue;
|
||||
/* armature modifier are handled by SkinDeformer, not ModifierDeformer */
|
||||
if (md->type == eModifierType_Armature )
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BL_ModifierDeformer::HasArmatureDeformer(Object *ob)
|
||||
{
|
||||
if (!ob->modifiers.first)
|
||||
return false;
|
||||
|
||||
ModifierData* md;
|
||||
for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) {
|
||||
if (md->type == eModifierType_Armature )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BL_ModifierDeformer::Update(void)
|
||||
{
|
||||
bool bShapeUpdate = BL_ShapeDeformer::Update();
|
||||
|
||||
if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) {
|
||||
// static derived mesh are not updated
|
||||
if (m_dm == NULL || m_bDynamic) {
|
||||
/* execute the modifiers */
|
||||
Object* blendobj = m_gameobj->GetBlendObject();
|
||||
/* hack: the modifiers require that the mesh is attached to the object
|
||||
It may not be the case here because of replace mesh actuator */
|
||||
Mesh *oldmesh = (Mesh*)blendobj->data;
|
||||
blendobj->data = m_bmesh;
|
||||
/* execute the modifiers */
|
||||
DerivedMesh *dm = mesh_create_derived_no_virtual(m_scene, blendobj, m_transverts, CD_MASK_MESH);
|
||||
/* restore object data */
|
||||
blendobj->data = oldmesh;
|
||||
/* free the current derived mesh and replace, (dm should never be NULL) */
|
||||
if (m_dm != NULL) {
|
||||
// HACK! use deformedOnly as a user counter
|
||||
if (--m_dm->deformedOnly == 0) {
|
||||
m_dm->needsFree = 1;
|
||||
m_dm->release(m_dm);
|
||||
}
|
||||
}
|
||||
m_dm = dm;
|
||||
// get rid of temporary data
|
||||
m_dm->needsFree = 0;
|
||||
m_dm->release(m_dm);
|
||||
// HACK! use deformedOnly as a user counter
|
||||
m_dm->deformedOnly = 1;
|
||||
/* update the graphic controller */
|
||||
PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
|
||||
if (ctrl) {
|
||||
float min_r[3], max_r[3];
|
||||
INIT_MINMAX(min_r, max_r);
|
||||
m_dm->getMinMax(m_dm, min_r, max_r);
|
||||
ctrl->setLocalAabb(min_r, max_r);
|
||||
}
|
||||
}
|
||||
m_lastModifierUpdate=m_gameobj->GetLastFrame();
|
||||
bShapeUpdate = true;
|
||||
}
|
||||
return bShapeUpdate;
|
||||
}
|
||||
|
||||
bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat)
|
||||
{
|
||||
if (!Update())
|
||||
return false;
|
||||
|
||||
// drawing is based on derived mesh, must set it in the mesh slots
|
||||
int nmat = m_pMeshObject->NumMaterials();
|
||||
for (int imat=0; imat<nmat; imat++) {
|
||||
RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
|
||||
RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj];
|
||||
if(!slot || !*slot)
|
||||
continue;
|
||||
(*slot)->m_pDerivedMesh = m_dm;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_MODIFIERDEFORMER
|
||||
#define BL_MODIFIERDEFORMER
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
#include "BL_ShapeDeformer.h"
|
||||
#include "BL_DeformableGameObject.h"
|
||||
#include <vector>
|
||||
|
||||
struct DerivedMesh;
|
||||
struct Object;
|
||||
|
||||
class BL_ModifierDeformer : public BL_ShapeDeformer
|
||||
{
|
||||
public:
|
||||
static bool HasCompatibleDeformer(Object *ob);
|
||||
static bool HasArmatureDeformer(Object *ob);
|
||||
|
||||
|
||||
BL_ModifierDeformer(BL_DeformableGameObject *gameobj,
|
||||
Scene *scene,
|
||||
Object *bmeshobj,
|
||||
RAS_MeshObject *mesh)
|
||||
:
|
||||
BL_ShapeDeformer(gameobj,bmeshobj, mesh),
|
||||
m_lastModifierUpdate(-1),
|
||||
m_scene(scene),
|
||||
m_dm(NULL)
|
||||
{
|
||||
m_recalcNormal = false;
|
||||
};
|
||||
|
||||
/* this second constructor is needed for making a mesh deformable on the fly. */
|
||||
BL_ModifierDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Scene *scene,
|
||||
struct Object *bmeshobj_old,
|
||||
struct Object *bmeshobj_new,
|
||||
class RAS_MeshObject *mesh,
|
||||
bool release_object,
|
||||
BL_ArmatureObject* arma = NULL)
|
||||
:
|
||||
BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma),
|
||||
m_lastModifierUpdate(-1),
|
||||
m_scene(scene),
|
||||
m_dm(NULL)
|
||||
{
|
||||
};
|
||||
|
||||
virtual void ProcessReplica();
|
||||
virtual RAS_Deformer *GetReplica();
|
||||
virtual ~BL_ModifierDeformer();
|
||||
virtual bool UseVertexArray()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Update (void);
|
||||
bool Apply(RAS_IPolyMaterial *mat);
|
||||
void ForceUpdate()
|
||||
{
|
||||
m_lastModifierUpdate = -1.0;
|
||||
};
|
||||
virtual struct DerivedMesh* GetFinalMesh()
|
||||
{
|
||||
return m_dm;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
double m_lastModifierUpdate;
|
||||
Scene *m_scene;
|
||||
DerivedMesh *m_dm;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ModifierDeformer"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,494 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#if defined (__sgi)
|
||||
#include <math.h>
|
||||
#else
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include "SCA_LogicManager.h"
|
||||
#include "BL_ShapeActionActuator.h"
|
||||
#include "BL_ShapeDeformer.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "DNA_nla_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "BKE_action.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "MT_Matrix4x4.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "FloatValue.h"
|
||||
#include "PyObjectPlus.h"
|
||||
|
||||
extern "C" {
|
||||
#include "BKE_animsys.h"
|
||||
}
|
||||
|
||||
BL_ShapeActionActuator::~BL_ShapeActionActuator()
|
||||
{
|
||||
}
|
||||
|
||||
void BL_ShapeActionActuator::ProcessReplica()
|
||||
{
|
||||
SCA_IActuator::ProcessReplica();
|
||||
m_localtime=m_startframe;
|
||||
m_lastUpdate=-1;
|
||||
}
|
||||
|
||||
void BL_ShapeActionActuator::SetBlendTime (float newtime)
|
||||
{
|
||||
m_blendframe = newtime;
|
||||
}
|
||||
|
||||
CValue* BL_ShapeActionActuator::GetReplica()
|
||||
{
|
||||
BL_ShapeActionActuator* replica = new BL_ShapeActionActuator(*this);//m_float,GetName());
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
bool BL_ShapeActionActuator::ClampLocalTime()
|
||||
{
|
||||
if (m_startframe < m_endframe) {
|
||||
if (m_localtime < m_startframe)
|
||||
{
|
||||
m_localtime = m_startframe;
|
||||
return true;
|
||||
}
|
||||
else if (m_localtime > m_endframe)
|
||||
{
|
||||
m_localtime = m_endframe;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (m_localtime > m_startframe)
|
||||
{
|
||||
m_localtime = m_startframe;
|
||||
return true;
|
||||
}
|
||||
else if (m_localtime < m_endframe)
|
||||
{
|
||||
m_localtime = m_endframe;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BL_ShapeActionActuator::SetStartTime(float curtime)
|
||||
{
|
||||
float direction = m_startframe < m_endframe ? 1.0 : -1.0;
|
||||
|
||||
if (!(m_flag & ACT_FLAG_REVERSE))
|
||||
m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate();
|
||||
else
|
||||
m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate();
|
||||
}
|
||||
|
||||
void BL_ShapeActionActuator::SetLocalTime(float curtime)
|
||||
{
|
||||
float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
|
||||
if (m_endframe < m_startframe)
|
||||
delta_time = -delta_time;
|
||||
|
||||
if (!(m_flag & ACT_FLAG_REVERSE))
|
||||
m_localtime = m_startframe + delta_time;
|
||||
else
|
||||
m_localtime = m_endframe - delta_time;
|
||||
}
|
||||
|
||||
void BL_ShapeActionActuator::BlendShape(Key* key, float srcweight)
|
||||
{
|
||||
vector<float>::const_iterator it;
|
||||
float dstweight;
|
||||
KeyBlock *kb;
|
||||
|
||||
dstweight = 1.0F - srcweight;
|
||||
|
||||
for (it=m_blendshape.begin(), kb = (KeyBlock*)key->block.first;
|
||||
kb && it != m_blendshape.end();
|
||||
kb = (KeyBlock*)kb->next, it++) {
|
||||
kb->curval = kb->curval * dstweight + (*it) * srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
bool BL_ShapeActionActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
bool bNegativeEvent = false;
|
||||
bool bPositiveEvent = false;
|
||||
bool keepgoing = true;
|
||||
bool wrap = false;
|
||||
bool apply=true;
|
||||
int priority;
|
||||
float newweight;
|
||||
|
||||
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
|
||||
|
||||
// result = true if animation has to be continued, false if animation stops
|
||||
// maybe there are events for us in the queue !
|
||||
if (frame)
|
||||
{
|
||||
bNegativeEvent = m_negevent;
|
||||
bPositiveEvent = m_posevent;
|
||||
RemoveAllEvents();
|
||||
|
||||
if (bPositiveEvent)
|
||||
m_flag |= ACT_FLAG_ACTIVE;
|
||||
|
||||
if (bNegativeEvent)
|
||||
{
|
||||
if (!(m_flag & ACT_FLAG_ACTIVE))
|
||||
return false;
|
||||
m_flag &= ~ACT_FLAG_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This action can only be attached to a deform object */
|
||||
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)GetParent();
|
||||
float length = m_endframe - m_startframe;
|
||||
|
||||
priority = m_priority;
|
||||
|
||||
/* Determine pre-incrementation behaviour and set appropriate flags */
|
||||
switch (m_playtype){
|
||||
case ACT_ACTION_MOTION:
|
||||
if (bNegativeEvent){
|
||||
keepgoing=false;
|
||||
apply=false;
|
||||
};
|
||||
break;
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
if (bNegativeEvent){
|
||||
apply=false;
|
||||
keepgoing=false;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_END:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_KEYUP;
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
m_localtime = m_startframe;
|
||||
m_starttime = curtime;
|
||||
}
|
||||
}
|
||||
if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_KEYUP;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag &= ~ACT_FLAG_KEYUP;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
}
|
||||
if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_KEYUP;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
keepgoing=false;
|
||||
apply=false;
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_FLIPPER:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
}
|
||||
else if (bNegativeEvent){
|
||||
m_flag |= ACT_FLAG_REVERSE;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_PLAY:
|
||||
if (bPositiveEvent){
|
||||
if (!(m_flag & ACT_FLAG_LOCKINPUT)){
|
||||
m_flag &= ~ACT_FLAG_REVERSE;
|
||||
m_localtime = m_starttime;
|
||||
m_starttime = curtime;
|
||||
m_flag |= ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Perform increment */
|
||||
if (keepgoing){
|
||||
if (m_playtype == ACT_ACTION_MOTION){
|
||||
MT_Point3 newpos;
|
||||
MT_Point3 deltapos;
|
||||
|
||||
newpos = obj->NodeGetWorldPosition();
|
||||
|
||||
/* Find displacement */
|
||||
deltapos = newpos-m_lastpos;
|
||||
m_localtime += (length/m_stridelength) * deltapos.length();
|
||||
m_lastpos = newpos;
|
||||
}
|
||||
else{
|
||||
SetLocalTime(curtime);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if a wrapping response is needed */
|
||||
if (length){
|
||||
if (m_localtime < m_startframe || m_localtime > m_endframe)
|
||||
{
|
||||
m_localtime = m_startframe + fmod(m_localtime, length);
|
||||
wrap = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_localtime = m_startframe;
|
||||
|
||||
/* Perform post-increment tasks */
|
||||
switch (m_playtype){
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
{
|
||||
CValue* propval = GetParent()->GetProperty(m_propname);
|
||||
if (propval)
|
||||
m_localtime = propval->GetNumber();
|
||||
|
||||
if (bNegativeEvent){
|
||||
keepgoing=false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_MOTION:
|
||||
break;
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
break;
|
||||
case ACT_ACTION_FLIPPER:
|
||||
if (wrap){
|
||||
if (!(m_flag & ACT_FLAG_REVERSE)){
|
||||
m_localtime=m_endframe;
|
||||
//keepgoing = false;
|
||||
}
|
||||
else {
|
||||
m_localtime=m_startframe;
|
||||
keepgoing = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_LOOP_END:
|
||||
if (wrap){
|
||||
if (m_flag & ACT_FLAG_KEYUP){
|
||||
keepgoing = false;
|
||||
m_localtime = m_endframe;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
SetStartTime(curtime);
|
||||
}
|
||||
break;
|
||||
case ACT_ACTION_PLAY:
|
||||
if (wrap){
|
||||
m_localtime = m_endframe;
|
||||
keepgoing = false;
|
||||
m_flag &= ~ACT_FLAG_LOCKINPUT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
keepgoing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the property if its defined */
|
||||
if (m_framepropname[0] != '\0') {
|
||||
CValue* propowner = GetParent();
|
||||
CValue* oldprop = propowner->GetProperty(m_framepropname);
|
||||
CValue* newval = new CFloatValue(m_localtime);
|
||||
if (oldprop) {
|
||||
oldprop->SetValue(newval);
|
||||
} else {
|
||||
propowner->SetProperty(m_framepropname, newval);
|
||||
}
|
||||
newval->Release();
|
||||
}
|
||||
|
||||
if (bNegativeEvent)
|
||||
m_blendframe=0.0f;
|
||||
|
||||
/* Apply the pose if necessary*/
|
||||
if (apply) {
|
||||
|
||||
/* Priority test */
|
||||
if (obj->SetActiveAction(this, priority, curtime)){
|
||||
Key *key = obj->GetKey();
|
||||
|
||||
if (!key) {
|
||||
// this could happen if the mesh was changed in the middle of an action
|
||||
// and the new mesh has no key, stop the action
|
||||
keepgoing = false;
|
||||
}
|
||||
else {
|
||||
ListBase tchanbase= {NULL, NULL};
|
||||
|
||||
if (m_blendin && m_blendframe==0.0f){
|
||||
// this is the start of the blending, remember the startup shape
|
||||
obj->GetShape(m_blendshape);
|
||||
m_blendstart = curtime;
|
||||
}
|
||||
// only interested in shape channel
|
||||
|
||||
// in 2.4x was // extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime);
|
||||
BKE_animsys_evaluate_animdata(&key->id, key->adt, m_localtime, ADT_RECALC_ANIM);
|
||||
|
||||
// XXX - in 2.5 theres no way to do this. possibly not that important to support - Campbell
|
||||
if (0) { // XXX !execute_ipochannels(&tchanbase)) {
|
||||
// no update, this is possible if action does not match the keys, stop the action
|
||||
keepgoing = false;
|
||||
}
|
||||
else {
|
||||
// the key have changed, apply blending if needed
|
||||
if (m_blendin && (m_blendframe<m_blendin)){
|
||||
newweight = (m_blendframe/(float)m_blendin);
|
||||
|
||||
BlendShape(key, 1.0f - newweight);
|
||||
|
||||
/* Increment current blending percentage */
|
||||
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
if (m_blendframe>m_blendin)
|
||||
m_blendframe = m_blendin;
|
||||
}
|
||||
m_lastUpdate = m_localtime;
|
||||
}
|
||||
BLI_freelistN(&tchanbase);
|
||||
}
|
||||
}
|
||||
else{
|
||||
m_blendframe = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!keepgoing){
|
||||
m_blendframe = 0.0f;
|
||||
}
|
||||
return keepgoing;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Integration hooks ------------------------------------------------------- */
|
||||
|
||||
PyTypeObject BL_ShapeActionActuator::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BL_ShapeActionActuator",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&SCA_IActuator::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
|
||||
PyMethodDef BL_ShapeActionActuator::Methods[] = {
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef BL_ShapeActionActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ShapeActionActuator, m_startframe),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ShapeActionActuator, m_endframe),
|
||||
KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendin),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ShapeActionActuator, pyattr_get_action, pyattr_set_action),
|
||||
KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ShapeActionActuator, m_priority),
|
||||
KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ShapeActionActuator, m_localtime, CheckFrame),
|
||||
KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ShapeActionActuator, m_propname),
|
||||
KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ShapeActionActuator, m_framepropname),
|
||||
KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendframe, CheckBlendTime),
|
||||
KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* BL_ShapeActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
|
||||
return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : "");
|
||||
}
|
||||
|
||||
int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
|
||||
/* exact copy of BL_ActionActuator's function from here down */
|
||||
if (!PyUnicode_Check(value))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
bAction *action= NULL;
|
||||
STR_String val = _PyUnicode_AsString(value);
|
||||
|
||||
if (val != "")
|
||||
{
|
||||
action= (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(val);
|
||||
if (action==NULL)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, action not found!");
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
self->SetAction(action);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_SHAPEACTIONACTUATOR
|
||||
#define BL_SHAPEACTIONACTUATOR
|
||||
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "SCA_IActuator.h"
|
||||
#include "BL_ActionActuator.h"
|
||||
#include "MT_Point3.h"
|
||||
#include <vector>
|
||||
|
||||
struct Key;
|
||||
class BL_ShapeActionActuator : public SCA_IActuator
|
||||
{
|
||||
public:
|
||||
Py_Header;
|
||||
BL_ShapeActionActuator(SCA_IObject* gameobj,
|
||||
const STR_String& propname,
|
||||
const STR_String& framepropname,
|
||||
float starttime,
|
||||
float endtime,
|
||||
struct bAction *action,
|
||||
short playtype,
|
||||
short blendin,
|
||||
short priority,
|
||||
float stride)
|
||||
: SCA_IActuator(gameobj, KX_ACT_SHAPEACTION),
|
||||
|
||||
m_lastpos(0, 0, 0),
|
||||
m_blendframe(0),
|
||||
m_flag(0),
|
||||
m_startframe (starttime),
|
||||
m_endframe(endtime) ,
|
||||
m_starttime(0),
|
||||
m_localtime(starttime),
|
||||
m_lastUpdate(-1),
|
||||
m_blendin(blendin),
|
||||
m_blendstart(0),
|
||||
m_stridelength(stride),
|
||||
m_playtype(playtype),
|
||||
m_priority(priority),
|
||||
m_action(action),
|
||||
m_framepropname(framepropname),
|
||||
m_propname(propname)
|
||||
{
|
||||
};
|
||||
virtual ~BL_ShapeActionActuator();
|
||||
virtual bool Update(double curtime, bool frame);
|
||||
virtual CValue* GetReplica();
|
||||
virtual void ProcessReplica();
|
||||
|
||||
void SetBlendTime (float newtime);
|
||||
void BlendShape(struct Key* key, float weigth);
|
||||
|
||||
bAction* GetAction() { return m_action; }
|
||||
void SetAction(bAction* act) { m_action= act; }
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
static int CheckBlendTime(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ShapeActionActuator* act = reinterpret_cast<BL_ShapeActionActuator*>(self);
|
||||
|
||||
if (act->m_blendframe > act->m_blendin)
|
||||
act->m_blendframe = act->m_blendin;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int CheckFrame(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ShapeActionActuator* act = reinterpret_cast<BL_ShapeActionActuator*>(self);
|
||||
|
||||
if (act->m_localtime < act->m_startframe)
|
||||
act->m_localtime = act->m_startframe;
|
||||
else if (act->m_localtime > act->m_endframe)
|
||||
act->m_localtime = act->m_endframe;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int CheckType(void *self, const PyAttributeDef*)
|
||||
{
|
||||
BL_ShapeActionActuator* act = reinterpret_cast<BL_ShapeActionActuator*>(self);
|
||||
|
||||
switch (act->m_playtype) {
|
||||
case ACT_ACTION_PLAY:
|
||||
case ACT_ACTION_FLIPPER:
|
||||
case ACT_ACTION_LOOP_STOP:
|
||||
case ACT_ACTION_LOOP_END:
|
||||
case ACT_ACTION_FROM_PROP:
|
||||
return 0;
|
||||
default:
|
||||
PyErr_SetString(PyExc_ValueError, "Shape Action Actuator, invalid play type supplied");
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
protected:
|
||||
|
||||
void SetStartTime(float curtime);
|
||||
void SetLocalTime(float curtime);
|
||||
bool ClampLocalTime();
|
||||
|
||||
MT_Point3 m_lastpos;
|
||||
float m_blendframe;
|
||||
int m_flag;
|
||||
/** The frame this action starts */
|
||||
float m_startframe;
|
||||
/** The frame this action ends */
|
||||
float m_endframe;
|
||||
/** The time this action started */
|
||||
float m_starttime;
|
||||
/** The current time of the action */
|
||||
float m_localtime;
|
||||
|
||||
float m_lastUpdate;
|
||||
float m_blendin;
|
||||
float m_blendstart;
|
||||
float m_stridelength;
|
||||
short m_playtype;
|
||||
short m_priority;
|
||||
struct bAction *m_action;
|
||||
STR_String m_framepropname;
|
||||
STR_String m_propname;
|
||||
vector<float> m_blendshape;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BL_ShapeDeformer.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
|
||||
//#include "BL_ArmatureController.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "MT_Point3.h"
|
||||
|
||||
extern "C"{
|
||||
#include "BKE_lattice.h"
|
||||
}
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#define __NLA_DEFNORMALS
|
||||
//#undef __NLA_DEFNORMALS
|
||||
|
||||
|
||||
BL_ShapeDeformer::~BL_ShapeDeformer()
|
||||
{
|
||||
};
|
||||
|
||||
RAS_Deformer *BL_ShapeDeformer::GetReplica()
|
||||
{
|
||||
BL_ShapeDeformer *result;
|
||||
|
||||
result = new BL_ShapeDeformer(*this);
|
||||
result->ProcessReplica();
|
||||
return result;
|
||||
}
|
||||
|
||||
void BL_ShapeDeformer::ProcessReplica()
|
||||
{
|
||||
BL_SkinDeformer::ProcessReplica();
|
||||
m_lastShapeUpdate = -1;
|
||||
}
|
||||
|
||||
bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
|
||||
m_shapeDrivers.clear();
|
||||
// check if this mesh has armature driven shape keys
|
||||
if (m_bmesh->key && m_bmesh->key->ipo) {
|
||||
for(icu= (IpoCurve*)m_bmesh->key->ipo->curve.first; icu; icu= (IpoCurve*)icu->next) {
|
||||
if(icu->driver &&
|
||||
(icu->flag & IPO_MUTE) == 0 &&
|
||||
icu->driver->type == IPO_DRIVER_TYPE_NORMAL &&
|
||||
icu->driver->ob == arma &&
|
||||
icu->driver->blocktype == ID_AR) {
|
||||
// this shape key ipo curve has a driver on the parent armature
|
||||
// record this curve in the shape deformer so that the corresponding
|
||||
m_shapeDrivers.push_back(icu);
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_shapeDrivers.empty();
|
||||
}
|
||||
|
||||
bool BL_ShapeDeformer::ExecuteShapeDrivers(void)
|
||||
{
|
||||
if (!m_shapeDrivers.empty() && PoseUpdated()) {
|
||||
vector<IpoCurve*>::iterator it;
|
||||
// void *poin;
|
||||
// int type;
|
||||
|
||||
// the shape drivers use the bone matrix as input. Must
|
||||
// update the matrix now
|
||||
m_armobj->ApplyPose();
|
||||
|
||||
for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) {
|
||||
// no need to set a specific time: this curve has a driver
|
||||
// XXX IpoCurve *icu = *it;
|
||||
//calc_icu(icu, 1.0f);
|
||||
//poin = get_ipo_poin((ID*)m_bmesh->key, icu, &type);
|
||||
//if (poin)
|
||||
// write_ipo_poin(poin, type, icu->curval);
|
||||
}
|
||||
|
||||
ForceUpdate();
|
||||
m_armobj->RestorePose();
|
||||
m_bDynamic = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BL_ShapeDeformer::Update(void)
|
||||
{
|
||||
bool bShapeUpdate = false;
|
||||
bool bSkinUpdate = false;
|
||||
|
||||
ExecuteShapeDrivers();
|
||||
|
||||
/* See if the object shape has changed */
|
||||
if (m_lastShapeUpdate != m_gameobj->GetLastFrame()) {
|
||||
/* the key coefficient have been set already, we just need to blend the keys */
|
||||
Object* blendobj = m_gameobj->GetBlendObject();
|
||||
|
||||
// make sure the vertex weight cache is in line with this object
|
||||
m_pMeshObject->CheckWeightCache(blendobj);
|
||||
|
||||
/* we will blend the key directly in m_transverts array: it is used by armature as the start position */
|
||||
/* m_bmesh->key can be NULL in case of Modifier deformer */
|
||||
if (m_bmesh->key) {
|
||||
/* store verts locally */
|
||||
VerifyStorage();
|
||||
|
||||
do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, NULL, 0);
|
||||
m_bDynamic = true;
|
||||
}
|
||||
|
||||
// Don't release the weight array as in Blender, it will most likely be reusable on next frame
|
||||
// The weight array are ultimately deleted when the skin mesh is destroyed
|
||||
|
||||
/* Update the current frame */
|
||||
m_lastShapeUpdate=m_gameobj->GetLastFrame();
|
||||
|
||||
// As we have changed, the mesh, the skin deformer must update as well.
|
||||
// This will force the update
|
||||
BL_SkinDeformer::ForceUpdate();
|
||||
bShapeUpdate = true;
|
||||
}
|
||||
// check for armature deform
|
||||
bSkinUpdate = BL_SkinDeformer::UpdateInternal(bShapeUpdate && m_bDynamic);
|
||||
|
||||
// non dynamic deformer = Modifer without armature and shape keys, no need to create storage
|
||||
if (!bSkinUpdate && bShapeUpdate && m_bDynamic) {
|
||||
// this means that there is no armature, we still need to
|
||||
// update the normal (was not done after shape key calculation)
|
||||
|
||||
#ifdef __NLA_DEFNORMALS
|
||||
if (m_recalcNormal)
|
||||
RecalcNormals();
|
||||
#endif
|
||||
bSkinUpdate = true;
|
||||
}
|
||||
return bSkinUpdate;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_SHAPEDEFORMER
|
||||
#define BL_SHAPEDEFORMER
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
#include "BL_SkinDeformer.h"
|
||||
#include "BL_DeformableGameObject.h"
|
||||
#include <vector>
|
||||
|
||||
struct IpoCurve;
|
||||
|
||||
class BL_ShapeDeformer : public BL_SkinDeformer
|
||||
{
|
||||
public:
|
||||
BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
|
||||
Object *bmeshobj,
|
||||
RAS_MeshObject *mesh)
|
||||
:
|
||||
BL_SkinDeformer(gameobj,bmeshobj, mesh),
|
||||
m_lastShapeUpdate(-1)
|
||||
{
|
||||
};
|
||||
|
||||
/* this second constructor is needed for making a mesh deformable on the fly. */
|
||||
BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Object *bmeshobj_old,
|
||||
struct Object *bmeshobj_new,
|
||||
class RAS_MeshObject *mesh,
|
||||
bool release_object,
|
||||
bool recalc_normal,
|
||||
BL_ArmatureObject* arma = NULL)
|
||||
:
|
||||
BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, recalc_normal, arma),
|
||||
m_lastShapeUpdate(-1)
|
||||
{
|
||||
};
|
||||
|
||||
virtual RAS_Deformer *GetReplica();
|
||||
virtual void ProcessReplica();
|
||||
virtual ~BL_ShapeDeformer();
|
||||
|
||||
bool Update (void);
|
||||
bool LoadShapeDrivers(Object* arma);
|
||||
bool ExecuteShapeDrivers(void);
|
||||
|
||||
void ForceUpdate()
|
||||
{
|
||||
m_lastShapeUpdate = -1.0;
|
||||
};
|
||||
|
||||
protected:
|
||||
vector<IpoCurve*> m_shapeDrivers;
|
||||
double m_lastShapeUpdate;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ShapeDeformer"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
#include "BL_SkinDeformer.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "STR_HashedString.h"
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
|
||||
//#include "BL_ArmatureController.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_action.h"
|
||||
#include "MT_Point3.h"
|
||||
|
||||
extern "C"{
|
||||
#include "BKE_lattice.h"
|
||||
}
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#define __NLA_DEFNORMALS
|
||||
//#undef __NLA_DEFNORMALS
|
||||
|
||||
BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Object *bmeshobj,
|
||||
class RAS_MeshObject *mesh,
|
||||
BL_ArmatureObject* arma)
|
||||
: //
|
||||
BL_MeshDeformer(gameobj, bmeshobj, mesh),
|
||||
m_armobj(arma),
|
||||
m_lastArmaUpdate(-1),
|
||||
//m_defbase(&bmeshobj->defbase),
|
||||
m_releaseobject(false),
|
||||
m_poseApplied(false),
|
||||
m_recalcNormal(true)
|
||||
{
|
||||
copy_m4_m4(m_obmat, bmeshobj->obmat);
|
||||
};
|
||||
|
||||
BL_SkinDeformer::BL_SkinDeformer(
|
||||
BL_DeformableGameObject *gameobj,
|
||||
struct Object *bmeshobj_old, // Blender object that owns the new mesh
|
||||
struct Object *bmeshobj_new, // Blender object that owns the original mesh
|
||||
class RAS_MeshObject *mesh,
|
||||
bool release_object,
|
||||
bool recalc_normal,
|
||||
BL_ArmatureObject* arma) :
|
||||
BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
|
||||
m_armobj(arma),
|
||||
m_lastArmaUpdate(-1),
|
||||
//m_defbase(&bmeshobj_old->defbase),
|
||||
m_releaseobject(release_object),
|
||||
m_recalcNormal(recalc_normal)
|
||||
{
|
||||
// this is needed to ensure correct deformation of mesh:
|
||||
// the deformation is done with Blender's armature_deform_verts() function
|
||||
// that takes an object as parameter and not a mesh. The object matrice is used
|
||||
// in the calculation, so we must use the matrix of the original object to
|
||||
// simulate a pure replacement of the mesh.
|
||||
copy_m4_m4(m_obmat, bmeshobj_new->obmat);
|
||||
}
|
||||
|
||||
BL_SkinDeformer::~BL_SkinDeformer()
|
||||
{
|
||||
if(m_releaseobject && m_armobj)
|
||||
m_armobj->Release();
|
||||
}
|
||||
|
||||
void BL_SkinDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
|
||||
{
|
||||
if (m_armobj) {
|
||||
void **h_obj = (*map)[m_armobj];
|
||||
|
||||
if (h_obj)
|
||||
m_armobj = (BL_ArmatureObject*)(*h_obj);
|
||||
else
|
||||
m_armobj=NULL;
|
||||
}
|
||||
|
||||
BL_MeshDeformer::Relink(map);
|
||||
}
|
||||
|
||||
bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
|
||||
{
|
||||
RAS_MeshSlot::iterator it;
|
||||
RAS_MeshMaterial *mmat;
|
||||
RAS_MeshSlot *slot;
|
||||
size_t i, nmat, imat;
|
||||
|
||||
// update the vertex in m_transverts
|
||||
if (!Update())
|
||||
return false;
|
||||
|
||||
if (m_transverts) {
|
||||
// the vertex cache is unique to this deformer, no need to update it
|
||||
// if it wasn't updated! We must update all the materials at once
|
||||
// because we will not get here again for the other material
|
||||
nmat = m_pMeshObject->NumMaterials();
|
||||
for (imat=0; imat<nmat; imat++) {
|
||||
mmat = m_pMeshObject->GetMeshMaterial(imat);
|
||||
if(!mmat->m_slots[(void*)m_gameobj])
|
||||
continue;
|
||||
|
||||
slot = *mmat->m_slots[(void*)m_gameobj];
|
||||
|
||||
// for each array
|
||||
for(slot->begin(it); !slot->end(it); slot->next(it)) {
|
||||
// for each vertex
|
||||
// copy the untransformed data from the original mvert
|
||||
for(i=it.startvertex; i<it.endvertex; i++) {
|
||||
RAS_TexVert& v = it.vertex[i];
|
||||
v.SetXYZ(m_transverts[v.getOrigIndex()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RAS_Deformer *BL_SkinDeformer::GetReplica()
|
||||
{
|
||||
BL_SkinDeformer *result;
|
||||
|
||||
result = new BL_SkinDeformer(*this);
|
||||
/* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */
|
||||
result->ProcessReplica();
|
||||
return result;
|
||||
}
|
||||
|
||||
void BL_SkinDeformer::ProcessReplica()
|
||||
{
|
||||
BL_MeshDeformer::ProcessReplica();
|
||||
m_lastArmaUpdate = -1;
|
||||
m_releaseobject = false;
|
||||
}
|
||||
|
||||
//void where_is_pose (Object *ob);
|
||||
//void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag);
|
||||
bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
|
||||
{
|
||||
/* See if the armature has been updated for this frame */
|
||||
if (PoseUpdated()){
|
||||
float obmat[4][4]; // the original object matrice
|
||||
|
||||
/* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
|
||||
/* but it requires the blender object pointer... */
|
||||
Object* par_arma = m_armobj->GetArmatureObject();
|
||||
|
||||
if(!shape_applied) {
|
||||
/* store verts locally */
|
||||
VerifyStorage();
|
||||
|
||||
/* duplicate */
|
||||
for (int v =0; v<m_bmesh->totvert; v++)
|
||||
VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
|
||||
}
|
||||
|
||||
m_armobj->ApplyPose();
|
||||
|
||||
// save matrix first
|
||||
copy_m4_m4(obmat, m_objMesh->obmat);
|
||||
// set reference matrix
|
||||
copy_m4_m4(m_objMesh->obmat, m_obmat);
|
||||
|
||||
armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
|
||||
|
||||
// restore matrix
|
||||
copy_m4_m4(m_objMesh->obmat, obmat);
|
||||
|
||||
#ifdef __NLA_DEFNORMALS
|
||||
if (m_recalcNormal)
|
||||
RecalcNormals();
|
||||
#endif
|
||||
|
||||
/* Update the current frame */
|
||||
m_lastArmaUpdate=m_armobj->GetLastFrame();
|
||||
|
||||
m_armobj->RestorePose();
|
||||
/* dynamic vertex, cannot use display list */
|
||||
m_bDynamic = true;
|
||||
/* indicate that the m_transverts and normals are up to date */
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BL_SkinDeformer::Update(void)
|
||||
{
|
||||
return UpdateInternal(false);
|
||||
}
|
||||
|
||||
/* XXX note: I propose to drop this function */
|
||||
void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
|
||||
{
|
||||
// only used to set the object now
|
||||
m_armobj = armobj;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BL_SKINDEFORMER
|
||||
#define BL_SKINDEFORMER
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
#include "GEN_HashedPtr.h"
|
||||
#include "BL_MeshDeformer.h"
|
||||
#include "BL_ArmatureObject.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "BKE_armature.h"
|
||||
|
||||
#include "RAS_Deformer.h"
|
||||
|
||||
|
||||
class BL_SkinDeformer : public BL_MeshDeformer
|
||||
{
|
||||
public:
|
||||
// void SetArmatureController (BL_ArmatureController *cont);
|
||||
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map);
|
||||
void SetArmature (class BL_ArmatureObject *armobj);
|
||||
|
||||
BL_SkinDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Object *bmeshobj,
|
||||
class RAS_MeshObject *mesh,
|
||||
BL_ArmatureObject* arma = NULL);
|
||||
|
||||
/* this second constructor is needed for making a mesh deformable on the fly. */
|
||||
BL_SkinDeformer(BL_DeformableGameObject *gameobj,
|
||||
struct Object *bmeshobj_old,
|
||||
struct Object *bmeshobj_new,
|
||||
class RAS_MeshObject *mesh,
|
||||
bool release_object,
|
||||
bool recalc_normal,
|
||||
BL_ArmatureObject* arma = NULL);
|
||||
|
||||
virtual RAS_Deformer *GetReplica();
|
||||
virtual void ProcessReplica();
|
||||
|
||||
virtual ~BL_SkinDeformer();
|
||||
bool Update (void);
|
||||
bool UpdateInternal (bool shape_applied);
|
||||
bool Apply (class RAS_IPolyMaterial *polymat);
|
||||
bool UpdateBuckets(void)
|
||||
{
|
||||
// update the deformer and all the mesh slots; Apply() does it well, so just call it.
|
||||
return Apply(NULL);
|
||||
}
|
||||
bool PoseUpdated(void)
|
||||
{
|
||||
if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ForceUpdate()
|
||||
{
|
||||
m_lastArmaUpdate = -1.0;
|
||||
};
|
||||
virtual bool ShareVertexArray()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
BL_ArmatureObject* m_armobj; // Our parent object
|
||||
float m_time;
|
||||
double m_lastArmaUpdate;
|
||||
//ListBase* m_defbase;
|
||||
float m_obmat[4][4]; // the reference matrix for skeleton deform
|
||||
bool m_releaseobject;
|
||||
bool m_poseApplied;
|
||||
bool m_recalcNormal;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_SkinDeformer"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h> // printf()
|
||||
|
||||
#include "BlenderWorldInfo.h"
|
||||
#include "KX_BlenderGL.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
/* This list includes only data type definitions */
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_property_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
#include "DNA_sensor_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
/* end of blender include block */
|
||||
|
||||
|
||||
BlenderWorldInfo::BlenderWorldInfo(struct World* blenderworld)
|
||||
{
|
||||
if (blenderworld)
|
||||
{
|
||||
m_hasworld = true;
|
||||
|
||||
// do we have mist?
|
||||
if ((blenderworld->mode) & WO_MIST)
|
||||
{
|
||||
m_hasmist = true;
|
||||
m_miststart = blenderworld->miststa;
|
||||
m_mistdistance = blenderworld->mistdist;
|
||||
m_mistred = blenderworld->horr;
|
||||
m_mistgreen = blenderworld->horg;
|
||||
m_mistblue = blenderworld->horb;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasmist = false;
|
||||
m_miststart = 0.0;
|
||||
m_mistdistance = 0.0;
|
||||
m_mistred = 0.0;
|
||||
m_mistgreen = 0.0;
|
||||
m_mistblue = 0.0;
|
||||
}
|
||||
|
||||
m_backgroundred = blenderworld->horr;
|
||||
m_backgroundgreen = blenderworld->horg;
|
||||
m_backgroundblue = blenderworld->horb;
|
||||
|
||||
m_ambientred = blenderworld->ambr;
|
||||
m_ambientgreen = blenderworld->ambg;
|
||||
m_ambientblue = blenderworld->ambb;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasworld = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BlenderWorldInfo::~BlenderWorldInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool BlenderWorldInfo::hasWorld()
|
||||
{
|
||||
return m_hasworld;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool BlenderWorldInfo::hasMist()
|
||||
{
|
||||
return m_hasmist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getBackColorRed()
|
||||
{
|
||||
return m_backgroundred;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getBackColorGreen()
|
||||
{
|
||||
return m_backgroundgreen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getBackColorBlue()
|
||||
{
|
||||
return m_backgroundblue;
|
||||
}
|
||||
|
||||
|
||||
float BlenderWorldInfo::getAmbientColorRed()
|
||||
{
|
||||
return m_ambientred;
|
||||
}
|
||||
|
||||
float BlenderWorldInfo::getAmbientColorGreen()
|
||||
{
|
||||
return m_ambientgreen;
|
||||
}
|
||||
|
||||
float BlenderWorldInfo::getAmbientColorBlue()
|
||||
{
|
||||
return m_ambientblue;
|
||||
}
|
||||
|
||||
float BlenderWorldInfo::getMistStart()
|
||||
{
|
||||
return m_miststart;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getMistDistance()
|
||||
{
|
||||
return m_mistdistance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getMistColorRed()
|
||||
{
|
||||
return m_mistred;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getMistColorGreen()
|
||||
{
|
||||
return m_mistgreen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float BlenderWorldInfo::getMistColorBlue()
|
||||
{
|
||||
return m_mistblue;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlenderWorldInfo::setMistStart(
|
||||
float d
|
||||
) {
|
||||
m_miststart = d;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlenderWorldInfo::setMistDistance(
|
||||
float d
|
||||
) {
|
||||
m_mistdistance = d;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlenderWorldInfo::setMistColorRed(
|
||||
float d
|
||||
) {
|
||||
m_mistred = d;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlenderWorldInfo::setMistColorGreen(
|
||||
float d
|
||||
) {
|
||||
m_mistgreen = d;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlenderWorldInfo::setMistColorBlue(
|
||||
float d
|
||||
) {
|
||||
m_mistblue = d;
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BLENDERWORLDINFO_H
|
||||
#define __BLENDERWORLDINFO_H
|
||||
#include "MT_CmMatrix4x4.h"
|
||||
#include "KX_WorldInfo.h"
|
||||
#include "KX_BlenderGL.h"
|
||||
|
||||
class BlenderWorldInfo : public KX_WorldInfo
|
||||
{
|
||||
bool m_hasworld;
|
||||
float m_backgroundred;
|
||||
float m_backgroundgreen;
|
||||
float m_backgroundblue;
|
||||
|
||||
bool m_hasmist;
|
||||
float m_miststart;
|
||||
float m_mistdistance;
|
||||
float m_mistred;
|
||||
float m_mistgreen;
|
||||
float m_mistblue;
|
||||
|
||||
float m_ambientred;
|
||||
float m_ambientgreen;
|
||||
float m_ambientblue;
|
||||
|
||||
public:
|
||||
BlenderWorldInfo(struct World* blenderworld);
|
||||
~BlenderWorldInfo();
|
||||
|
||||
bool hasWorld();
|
||||
bool hasMist();
|
||||
float getBackColorRed();
|
||||
float getBackColorGreen();
|
||||
float getBackColorBlue();
|
||||
|
||||
float getAmbientColorRed();
|
||||
float getAmbientColorGreen();
|
||||
float getAmbientColorBlue();
|
||||
|
||||
float getMistStart();
|
||||
float getMistDistance();
|
||||
float getMistColorRed();
|
||||
float getMistColorGreen();
|
||||
float getMistColorBlue();
|
||||
|
||||
void
|
||||
setMistStart(
|
||||
float d
|
||||
);
|
||||
|
||||
void
|
||||
setMistDistance(
|
||||
float d
|
||||
);
|
||||
|
||||
void
|
||||
setMistColorRed(
|
||||
float d
|
||||
);
|
||||
|
||||
void
|
||||
setMistColorGreen(
|
||||
float d
|
||||
);
|
||||
|
||||
void
|
||||
setMistColorBlue(
|
||||
float d
|
||||
);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BlenderWorldInfo"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__BLENDERWORLDINFO_H
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
SET(INC
|
||||
.
|
||||
../../../source/kernel/gen_system
|
||||
../../../intern/string
|
||||
../../../intern/guardedalloc
|
||||
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
|
||||
../../../intern/audaspace/intern
|
||||
../../../source/gameengine/Converter
|
||||
../../../source/gameengine/BlenderRoutines
|
||||
../../../source/blender/imbuf
|
||||
../../../intern/moto/include
|
||||
../../../source/gameengine/Ketsji
|
||||
../../../source/gameengine/Ketsji/KXNetwork
|
||||
../../../source/blender/blenlib
|
||||
../../../source/blender/blenkernel
|
||||
../../../source/blender/windowmanager
|
||||
../../../source/blender
|
||||
../../../source/blender/include
|
||||
../../../source/blender/makesdna
|
||||
../../../source/blender/makesrna
|
||||
../../../source/gameengine/Rasterizer
|
||||
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
|
||||
../../../source/gameengine/GameLogic
|
||||
../../../source/gameengine/Expressions
|
||||
../../../source/gameengine/Network
|
||||
../../../source/gameengine/SceneGraph
|
||||
../../../source/gameengine/Physics/common
|
||||
../../../source/gameengine/Physics/Bullet
|
||||
../../../source/gameengine/Physics/Dummy
|
||||
../../../source/gameengine/Network/LoopBackNetwork
|
||||
../../../source/blender/misc
|
||||
../../../source/blender/blenloader
|
||||
../../../source/blender/gpu
|
||||
../../../source/blender/ikplugin
|
||||
../../../extern/bullet2/src
|
||||
)
|
||||
|
||||
IF(WITH_PYTHON)
|
||||
SET(INC ${INC} ${PYTHON_INC})
|
||||
ELSE(WITH_PYTHON)
|
||||
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
||||
ENDIF(WITH_PYTHON)
|
||||
|
||||
BLENDERLIB(bf_converter "${SRC}" "${INC}")
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_BlenderScalarInterpolator.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
extern "C" {
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "BKE_fcurve.h"
|
||||
}
|
||||
|
||||
float BL_ScalarInterpolator::GetValue(float currentTime) const {
|
||||
// XXX 2.4x IPO_GetFloatValue(m_blender_adt, m_channel, currentTime);
|
||||
return evaluate_fcurve(m_fcu, currentTime);
|
||||
}
|
||||
|
||||
BL_InterpolatorList::BL_InterpolatorList(struct AnimData *adt) {
|
||||
if(adt->action==NULL)
|
||||
return;
|
||||
|
||||
for(FCurve *fcu= (FCurve *)adt->action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
|
||||
if(fcu->rna_path) {
|
||||
BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu);
|
||||
//assert(new_ipo);
|
||||
push_back(new_ipo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BL_InterpolatorList::~BL_InterpolatorList() {
|
||||
BL_InterpolatorList::iterator i;
|
||||
for (i = begin(); !(i == end()); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
KX_IScalarInterpolator *BL_InterpolatorList::GetScalarInterpolator(const char *rna_path, int array_index) {
|
||||
for(BL_InterpolatorList::iterator i = begin(); (i != end()) ; i++ )
|
||||
{
|
||||
FCurve *fcu= (static_cast<BL_ScalarInterpolator *>(*i))->GetFCurve();
|
||||
if(array_index==fcu->array_index && strcmp(rna_path, fcu->rna_path)==0)
|
||||
return *i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_SCALARINTERPOLATOR_H
|
||||
#define __KX_SCALARINTERPOLATOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "KX_IScalarInterpolator.h"
|
||||
|
||||
typedef unsigned short BL_IpoChannel;
|
||||
|
||||
class BL_ScalarInterpolator : public KX_IScalarInterpolator {
|
||||
public:
|
||||
BL_ScalarInterpolator() {} // required for use in STL list
|
||||
BL_ScalarInterpolator(struct FCurve* fcu) :
|
||||
m_fcu(fcu)
|
||||
{}
|
||||
|
||||
virtual ~BL_ScalarInterpolator() {}
|
||||
|
||||
virtual float GetValue(float currentTime) const;
|
||||
struct FCurve *GetFCurve() { return m_fcu;};
|
||||
|
||||
private:
|
||||
struct FCurve *m_fcu;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ScalarInterpolator"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class BL_InterpolatorList : public std::vector<KX_IScalarInterpolator *> {
|
||||
public:
|
||||
BL_InterpolatorList(struct AnimData *adt);
|
||||
~BL_InterpolatorList();
|
||||
|
||||
KX_IScalarInterpolator *GetScalarInterpolator(const char *rna_path, int array_index);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_InterpolatorList"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_SCALARINTERPOLATOR_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_BLENDERSCENECONVERTER_H
|
||||
#define __KX_BLENDERSCENECONVERTER_H
|
||||
|
||||
#include "KX_HashedPtr.h"
|
||||
#include "GEN_Map.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "KX_ISceneConverter.h"
|
||||
#include "KX_IpoConvert.h"
|
||||
|
||||
class KX_WorldInfo;
|
||||
class SCA_IActuator;
|
||||
class SCA_IController;
|
||||
class RAS_MeshObject;
|
||||
class RAS_IPolyMaterial;
|
||||
class BL_InterpolatorList;
|
||||
class BL_Material;
|
||||
struct Main;
|
||||
struct Scene;
|
||||
|
||||
class KX_BlenderSceneConverter : public KX_ISceneConverter
|
||||
{
|
||||
// Use vector of pairs to allow removal of entities between scene switch
|
||||
vector<pair<KX_Scene*,KX_WorldInfo*> > m_worldinfos;
|
||||
vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
|
||||
vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
|
||||
vector<pair<KX_Scene*,BL_Material *> > m_materials;
|
||||
// Should also have a list of collision shapes.
|
||||
// For the time being this is held in KX_Scene::m_shapes
|
||||
|
||||
GEN_Map<CHashedPtr,KX_GameObject*> m_map_blender_to_gameobject; /* cleared after conversion */
|
||||
GEN_Map<CHashedPtr,RAS_MeshObject*> m_map_mesh_to_gamemesh; /* cleared after conversion */
|
||||
GEN_Map<CHashedPtr,SCA_IActuator*> m_map_blender_to_gameactuator; /* cleared after conversion */
|
||||
GEN_Map<CHashedPtr,SCA_IController*>m_map_blender_to_gamecontroller; /* cleared after conversion */
|
||||
|
||||
GEN_Map<CHashedPtr,BL_InterpolatorList*> m_map_blender_to_gameAdtList;
|
||||
|
||||
Main* m_maggie;
|
||||
vector<struct Main*> m_DynamicMaggie;
|
||||
|
||||
STR_String m_newfilename;
|
||||
class KX_KetsjiEngine* m_ketsjiEngine;
|
||||
class KX_Scene* m_currentScene; // Scene being converted
|
||||
bool m_alwaysUseExpandFraming;
|
||||
bool m_usemat;
|
||||
bool m_useglslmat;
|
||||
|
||||
public:
|
||||
KX_BlenderSceneConverter(
|
||||
Main* maggie,
|
||||
class KX_KetsjiEngine* engine
|
||||
);
|
||||
|
||||
virtual ~KX_BlenderSceneConverter();
|
||||
|
||||
/* Scenename: name of the scene to be converted.
|
||||
* destinationscene: pass an empty scene, everything goes into this
|
||||
* dictobj: python dictionary (for pythoncontrollers)
|
||||
*/
|
||||
virtual void ConvertScene(
|
||||
class KX_Scene* destinationscene,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas
|
||||
);
|
||||
virtual void RemoveScene(class KX_Scene *scene);
|
||||
|
||||
void SetNewFileName(const STR_String& filename);
|
||||
bool TryAndLoadNewFile();
|
||||
|
||||
void SetAlwaysUseExpandFraming(bool to_what);
|
||||
|
||||
void RegisterGameObject(KX_GameObject *gameobject, struct Object *for_blenderobject);
|
||||
void UnregisterGameObject(KX_GameObject *gameobject);
|
||||
KX_GameObject *FindGameObject(struct Object *for_blenderobject);
|
||||
|
||||
void RegisterGameMesh(RAS_MeshObject *gamemesh, struct Mesh *for_blendermesh);
|
||||
RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/);
|
||||
|
||||
void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
|
||||
|
||||
void RegisterBlenderMaterial(BL_Material *mat);
|
||||
|
||||
void RegisterInterpolatorList(BL_InterpolatorList *adtList, struct AnimData *for_adt);
|
||||
BL_InterpolatorList *FindInterpolatorList(struct AnimData *for_adt);
|
||||
|
||||
void RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator);
|
||||
SCA_IActuator *FindGameActuator(struct bActuator *for_actuator);
|
||||
|
||||
void RegisterGameController(SCA_IController *cont, struct bController *for_controller);
|
||||
SCA_IController *FindGameController(struct bController *for_controller);
|
||||
|
||||
void RegisterWorldInfo(KX_WorldInfo *worldinfo);
|
||||
|
||||
virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo);
|
||||
|
||||
///this is for reseting the position,rotation and scale of the gameobjet that is not dynamic
|
||||
virtual void resetNoneDynamicObjectToIpo();
|
||||
|
||||
///this generates ipo curves for position, rotation, allowing to use game physics in animation
|
||||
virtual void WritePhysicsObjectToAnimationIpo(int frameNumber);
|
||||
virtual void TestHandlesPhysicsObjectToAnimationIpo();
|
||||
|
||||
// use blender materials
|
||||
virtual void SetMaterials(bool val);
|
||||
virtual bool GetMaterials();
|
||||
|
||||
// use blender glsl materials
|
||||
virtual void SetGLSLMaterials(bool val);
|
||||
virtual bool GetGLSLMaterials();
|
||||
|
||||
struct Scene* GetBlenderSceneForName(const STR_String& name);
|
||||
|
||||
// struct Main* GetMain() { return m_maggie; };
|
||||
struct Main* GetMainDynamicPath(const char *path);
|
||||
vector<struct Main*> &GetMainDynamic();
|
||||
|
||||
bool LinkBlendFile(const char *path, char *group, KX_Scene *scene_merge, char **err_str);
|
||||
bool MergeScene(KX_Scene *to, KX_Scene *from);
|
||||
RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name);
|
||||
bool FreeBlendFile(struct Main *maggie);
|
||||
bool FreeBlendFile(const char *path);
|
||||
|
||||
void PrintStats() {
|
||||
printf("BGE STATS!\n");
|
||||
|
||||
printf("\nAssets...\n");
|
||||
printf("\t m_worldinfos: %d\n", (int)m_worldinfos.size());
|
||||
printf("\t m_polymaterials: %d\n", (int)m_polymaterials.size());
|
||||
printf("\t m_meshobjects: %d\n", (int)m_meshobjects.size());
|
||||
printf("\t m_materials: %d\n", (int)m_materials.size());
|
||||
|
||||
printf("\nMappings...\n");
|
||||
printf("\t m_map_blender_to_gameobject: %d\n", (int)m_map_blender_to_gameobject.size());
|
||||
printf("\t m_map_mesh_to_gamemesh: %d\n", (int)m_map_mesh_to_gamemesh.size());
|
||||
printf("\t m_map_blender_to_gameactuator: %d\n", (int)m_map_blender_to_gameactuator.size());
|
||||
printf("\t m_map_blender_to_gamecontroller: %d\n", (int)m_map_blender_to_gamecontroller.size());
|
||||
printf("\t m_map_blender_to_gameAdtList: %d\n", (int)m_map_blender_to_gameAdtList.size());
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_printmemlist_pydict();
|
||||
#endif
|
||||
// /printf("\t m_ketsjiEngine->m_scenes: %d\n", m_ketsjiEngine->CurrentScenes()->size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject *GetPyNamespace();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_BlenderSceneConverter"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_BLENDERSCENECONVERTER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_CONVERTACTUATORS_H
|
||||
#define __KX_CONVERTACTUATORS_H
|
||||
|
||||
void BL_ConvertActuators(char* maggiename,
|
||||
struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
class SCA_LogicManager* logicmgr,
|
||||
class KX_Scene* scene,
|
||||
class KX_KetsjiEngine* ketsjiEngine,
|
||||
int activeLayerBitInfo,
|
||||
bool isInActiveLayer,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class KX_BlenderSceneConverter* converter);
|
||||
|
||||
|
||||
#endif //__KX_CONVERTACTUATORS_H
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
#include "KX_ConvertControllers.h"
|
||||
#include "KX_Python.h"
|
||||
|
||||
// Controller
|
||||
#include "SCA_ANDController.h"
|
||||
#include "SCA_ORController.h"
|
||||
#include "SCA_NANDController.h"
|
||||
#include "SCA_NORController.h"
|
||||
#include "SCA_XORController.h"
|
||||
#include "SCA_XNORController.h"
|
||||
#include "SCA_PythonController.h"
|
||||
#include "SCA_ExpressionController.h"
|
||||
|
||||
#include "SCA_LogicManager.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "IntValue.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
#include "BKE_text.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
/* end of blender include block */
|
||||
|
||||
|
||||
static void
|
||||
LinkControllerToActuators(
|
||||
SCA_IController *game_controller,
|
||||
bController* bcontr,
|
||||
SCA_LogicManager* logicmgr,
|
||||
KX_BlenderSceneConverter* converter
|
||||
) {
|
||||
// Iterate through the actuators of the game blender
|
||||
// controller and find the corresponding ketsji actuator.
|
||||
|
||||
game_controller->ReserveActuator(bcontr->totlinks);
|
||||
for (int i=0;i<bcontr->totlinks;i++)
|
||||
{
|
||||
bActuator* bact = (bActuator*) bcontr->links[i];
|
||||
SCA_IActuator *game_actuator = converter->FindGameActuator(bact);
|
||||
if (game_actuator) {
|
||||
logicmgr->RegisterToActuator(game_controller, game_actuator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BL_ConvertControllers(
|
||||
struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
SCA_LogicManager* logicmgr,
|
||||
int activeLayerBitInfo,
|
||||
bool isInActiveLayer,
|
||||
KX_BlenderSceneConverter* converter
|
||||
) {
|
||||
int uniqueint=0;
|
||||
int count = 0;
|
||||
int executePriority=0;
|
||||
bController* bcontr = (bController*)blenderobject->controllers.first;
|
||||
while (bcontr)
|
||||
{
|
||||
bcontr = bcontr->next;
|
||||
count++;
|
||||
}
|
||||
gameobj->ReserveController(count);
|
||||
bcontr = (bController*)blenderobject->controllers.first;
|
||||
while (bcontr)
|
||||
{
|
||||
SCA_IController* gamecontroller = NULL;
|
||||
switch(bcontr->type)
|
||||
{
|
||||
case CONT_LOGIC_AND:
|
||||
{
|
||||
gamecontroller = new SCA_ANDController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_LOGIC_OR:
|
||||
{
|
||||
gamecontroller = new SCA_ORController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_LOGIC_NAND:
|
||||
{
|
||||
gamecontroller = new SCA_NANDController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_LOGIC_NOR:
|
||||
{
|
||||
gamecontroller = new SCA_NORController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_LOGIC_XOR:
|
||||
{
|
||||
gamecontroller = new SCA_XORController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_LOGIC_XNOR:
|
||||
{
|
||||
gamecontroller = new SCA_XNORController(gameobj);
|
||||
break;
|
||||
}
|
||||
case CONT_EXPRESSION:
|
||||
{
|
||||
bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
|
||||
STR_String expressiontext = STR_String(bexpcont->str);
|
||||
if (expressiontext.Length() > 0)
|
||||
{
|
||||
gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONT_PYTHON:
|
||||
{
|
||||
bPythonCont* pycont = (bPythonCont*) bcontr->data;
|
||||
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
|
||||
gamecontroller = pyctrl;
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
pyctrl->SetNamespace(converter->GetPyNamespace());
|
||||
|
||||
if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
|
||||
if (pycont->text)
|
||||
{
|
||||
char *buf;
|
||||
// this is some blender specific code
|
||||
buf= txt_to_buf(pycont->text);
|
||||
if (buf)
|
||||
{
|
||||
pyctrl->SetScriptText(STR_String(buf));
|
||||
pyctrl->SetScriptName(pycont->text->id.name+2);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* let the controller print any warnings here when importing */
|
||||
pyctrl->SetScriptText(STR_String(pycont->module));
|
||||
pyctrl->SetScriptName(pycont->module); /* will be something like module.func so using it as the name is OK */
|
||||
|
||||
if(pycont->flag & CONT_PY_DEBUG) {
|
||||
printf("\nDebuging \"%s\", module for object %s\n\texpect worse performance.\n", pycont->module, blenderobject->id.name+2);
|
||||
pyctrl->SetDebug(true);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (gamecontroller)
|
||||
{
|
||||
LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
|
||||
gamecontroller->SetExecutePriority(executePriority++);
|
||||
gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0);
|
||||
gamecontroller->SetState(bcontr->state_mask);
|
||||
STR_String uniquename = bcontr->name;
|
||||
uniquename += "#CONTR#";
|
||||
uniqueint++;
|
||||
CIntValue* uniqueval = new CIntValue(uniqueint);
|
||||
uniquename += uniqueval->GetText();
|
||||
uniqueval->Release();
|
||||
gamecontroller->SetName(uniquename);
|
||||
gameobj->AddController(gamecontroller);
|
||||
|
||||
converter->RegisterGameController(gamecontroller, bcontr);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
if (bcontr->type==CONT_PYTHON) {
|
||||
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
|
||||
/* not strictly needed but gives syntax errors early on and
|
||||
* gives more pradictable performance for larger scripts */
|
||||
if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
|
||||
pyctrl->Compile();
|
||||
else {
|
||||
/* We cant do this because importing runs the script which could end up accessing
|
||||
* internal BGE functions, this is unstable while we're converting the scene.
|
||||
* This is a pitty because its useful to see errors at startup but cant help it */
|
||||
|
||||
// pyctrl->Import();
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
//done with gamecontroller
|
||||
gamecontroller->Release();
|
||||
}
|
||||
|
||||
bcontr = bcontr->next;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_CONVERTCONTROLLERS_H
|
||||
#define __KX_CONVERTCONTROLLERS_H
|
||||
|
||||
#include "KX_Python.h"
|
||||
|
||||
void BL_ConvertControllers(
|
||||
struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
class SCA_LogicManager* logicmgr,
|
||||
int activeLayerBitInfo,
|
||||
bool isInActiveLayer,
|
||||
class KX_BlenderSceneConverter* converter
|
||||
);
|
||||
|
||||
|
||||
#endif //__KX_CONVERTCONTROLLERS_H
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_ConvertProperties.h"
|
||||
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_property_types.h"
|
||||
/* end of blender include block */
|
||||
|
||||
|
||||
#include "Value.h"
|
||||
#include "VectorValue.h"
|
||||
#include "BoolValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "FloatValue.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "IntValue.h"
|
||||
#include "SCA_TimeEventManager.h"
|
||||
#include "SCA_IScene.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer)
|
||||
{
|
||||
|
||||
bProperty* prop = (bProperty*)object->prop.first;
|
||||
CValue* propval;
|
||||
bool show_debug_info;
|
||||
while(prop)
|
||||
{
|
||||
|
||||
propval = NULL;
|
||||
show_debug_info = bool (prop->flag & PROP_DEBUG);
|
||||
|
||||
switch(prop->type) {
|
||||
case GPROP_BOOL:
|
||||
{
|
||||
propval = new CBoolValue((bool)(prop->data != 0));
|
||||
gameobj->SetProperty(prop->name,propval);
|
||||
//promp->poin= &prop->data;
|
||||
break;
|
||||
}
|
||||
case GPROP_INT:
|
||||
{
|
||||
propval = new CIntValue((int)prop->data);
|
||||
gameobj->SetProperty(prop->name,propval);
|
||||
break;
|
||||
}
|
||||
case GPROP_FLOAT:
|
||||
{
|
||||
//prop->poin= &prop->data;
|
||||
float floatprop = *((float*)&prop->data);
|
||||
propval = new CFloatValue(floatprop);
|
||||
gameobj->SetProperty(prop->name,propval);
|
||||
}
|
||||
break;
|
||||
case GPROP_STRING:
|
||||
{
|
||||
//prop->poin= callocN(MAX_PROPSTRING, "property string");
|
||||
propval = new CStringValue((char*)prop->poin,"");
|
||||
gameobj->SetProperty(prop->name,propval);
|
||||
break;
|
||||
}
|
||||
case GPROP_TIME:
|
||||
{
|
||||
float floatprop = *((float*)&prop->data);
|
||||
|
||||
CValue* timeval = new CFloatValue(floatprop);
|
||||
// set a subproperty called 'timer' so that
|
||||
// we can register the replica of this property
|
||||
// at the time a game object is replicated (AddObjectActuator triggers this)
|
||||
CValue *bval = new CBoolValue(true);
|
||||
timeval->SetProperty("timer",bval);
|
||||
bval->Release();
|
||||
if (isInActiveLayer)
|
||||
{
|
||||
timemgr->AddTimeProperty(timeval);
|
||||
}
|
||||
|
||||
propval = timeval;
|
||||
gameobj->SetProperty(prop->name,timeval);
|
||||
|
||||
}
|
||||
default:
|
||||
{
|
||||
// todo make an assert etc.
|
||||
}
|
||||
}
|
||||
|
||||
if (propval)
|
||||
{
|
||||
if (show_debug_info)
|
||||
{
|
||||
scene->AddDebugProperty(gameobj,STR_String(prop->name));
|
||||
}
|
||||
// done with propval, release it
|
||||
propval->Release();
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
/* Warn if we double up on attributes, this isnt quite right since it wont find inherited attributes however there arnt many */
|
||||
for(PyAttributeDef *attrdef = KX_GameObject::Attributes; attrdef->m_name; attrdef++) {
|
||||
if(strcmp(prop->name, attrdef->m_name)==0) {
|
||||
printf("Warning! user defined property name \"%s\" is also a python attribute for object \"%s\"\n\tUse ob[\"%s\"] syntax to avoid conflict\n", prop->name, object->id.name+2, prop->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(PyMethodDef *methdef = KX_GameObject::Methods; methdef->ml_name; methdef++) {
|
||||
if(strcmp(prop->name, methdef->ml_name)==0) {
|
||||
printf("Warning! user defined property name \"%s\" is also a python method for object \"%s\"\n\tUse ob[\"%s\"] syntax to avoid conflict\n", prop->name, object->id.name+2, prop->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* end warning check */
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
// check if state needs to be debugged
|
||||
if (object->scaflag & OB_DEBUGSTATE)
|
||||
{
|
||||
// reserve name for object state
|
||||
scene->AddDebugProperty(gameobj,STR_String("__state__"));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_CONVERTPROPERTIES
|
||||
#define __KX_CONVERTPROPERTIES
|
||||
|
||||
void BL_ConvertProperties(struct Object* object,
|
||||
class KX_GameObject* gameobj,
|
||||
class SCA_TimeEventManager* timemgr,
|
||||
class SCA_IScene* scene,
|
||||
bool isInActiveLayer);
|
||||
|
||||
#endif //__KX_CONVERTPROPERTIES
|
||||
|
||||
@@ -1,859 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* Conversion of Blender data blocks to KX sensor system
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
#include "wm_event_types.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
#include "KX_ConvertSensors.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_sensor_types.h"
|
||||
#include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
|
||||
probably misplaced */
|
||||
/* end of blender include block */
|
||||
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
// Sensors
|
||||
#include "KX_GameObject.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
#include "SCA_KeyboardSensor.h"
|
||||
#include "SCA_MouseSensor.h"
|
||||
#include "SCA_AlwaysSensor.h"
|
||||
#include "KX_TouchSensor.h"
|
||||
#include "KX_NearSensor.h"
|
||||
#include "KX_RadarSensor.h"
|
||||
#include "KX_MouseFocusSensor.h"
|
||||
#include "KX_ArmatureSensor.h"
|
||||
#include "SCA_JoystickSensor.h"
|
||||
#include "KX_NetworkMessageSensor.h"
|
||||
#include "SCA_ActuatorSensor.h"
|
||||
#include "SCA_DelaySensor.h"
|
||||
|
||||
|
||||
#include "SCA_PropertySensor.h"
|
||||
#include "SCA_RandomSensor.h"
|
||||
#include "KX_RaySensor.h"
|
||||
#include "SCA_EventManager.h"
|
||||
#include "SCA_LogicManager.h"
|
||||
#include "KX_BlenderInputDevice.h"
|
||||
#include "KX_Scene.h"
|
||||
#include "IntValue.h"
|
||||
#include "KX_BlenderKeyboardDevice.h"
|
||||
#include "KX_BlenderGL.h"
|
||||
#include "RAS_ICanvas.h"
|
||||
#include "PHY_IPhysicsEnvironment.h"
|
||||
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
|
||||
// this map is Blender specific: a conversion between blender and ketsji enums
|
||||
std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
|
||||
|
||||
|
||||
void BL_ConvertSensors(struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
SCA_LogicManager* logicmgr,
|
||||
KX_Scene* kxscene,
|
||||
KX_KetsjiEngine* kxengine,
|
||||
int activeLayerBitInfo,
|
||||
bool isInActiveLayer,
|
||||
RAS_ICanvas* canvas,
|
||||
KX_BlenderSceneConverter* converter
|
||||
)
|
||||
{
|
||||
static bool reverseTableConverted = false;
|
||||
|
||||
if (!reverseTableConverted)
|
||||
{
|
||||
reverseTableConverted = true;
|
||||
|
||||
/* The reverse table. In order to not confuse ourselves, we */
|
||||
/* immediately convert all events that come in to KX codes. */
|
||||
gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
|
||||
gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
|
||||
gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
|
||||
gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE;
|
||||
gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
|
||||
gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
|
||||
gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
|
||||
|
||||
// TIMERS
|
||||
|
||||
gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
|
||||
gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
|
||||
gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
|
||||
|
||||
// SYSTEM
|
||||
|
||||
#if 0
|
||||
/* **** XXX **** */
|
||||
gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
|
||||
gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
|
||||
gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
|
||||
gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
|
||||
gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL;
|
||||
gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
|
||||
gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
|
||||
gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
|
||||
gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
|
||||
gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
|
||||
/* **** XXX **** */
|
||||
#endif
|
||||
|
||||
// standard keyboard
|
||||
|
||||
gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY;
|
||||
gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY;
|
||||
gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY;
|
||||
gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY;
|
||||
gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY;
|
||||
gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY;
|
||||
gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY;
|
||||
|
||||
//XXX clean up
|
||||
#ifdef WIN32
|
||||
#define HKEY 'h'
|
||||
#endif
|
||||
gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY;
|
||||
//XXX clean up
|
||||
#ifdef WIN32
|
||||
#undef HKEY
|
||||
#endif
|
||||
|
||||
gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY;
|
||||
gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY;
|
||||
gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY;
|
||||
gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY;
|
||||
gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY;
|
||||
gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY;
|
||||
gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY;
|
||||
gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY;
|
||||
gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY;
|
||||
gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY;
|
||||
gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY;
|
||||
gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY;
|
||||
gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY;
|
||||
gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY;
|
||||
gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY;
|
||||
gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY;
|
||||
gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY;
|
||||
gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
|
||||
|
||||
gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
|
||||
gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
|
||||
gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
|
||||
gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
|
||||
gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
|
||||
gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
|
||||
gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
|
||||
gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
|
||||
gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
|
||||
gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
|
||||
|
||||
gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
|
||||
|
||||
gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
|
||||
gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
|
||||
gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
|
||||
gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
|
||||
gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
|
||||
gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
|
||||
|
||||
gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
|
||||
gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
|
||||
gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
|
||||
gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
|
||||
gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
|
||||
gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
|
||||
gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
|
||||
gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
|
||||
gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
|
||||
gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
|
||||
gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
|
||||
gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
|
||||
gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
|
||||
gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
|
||||
gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
|
||||
gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
|
||||
gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
|
||||
gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
|
||||
|
||||
gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
|
||||
gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
|
||||
gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
|
||||
gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
|
||||
|
||||
gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2;
|
||||
gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4;
|
||||
gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6;
|
||||
gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8;
|
||||
|
||||
gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1;
|
||||
gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3;
|
||||
gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5;
|
||||
gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7;
|
||||
gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9;
|
||||
|
||||
gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
|
||||
gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
|
||||
gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
|
||||
|
||||
gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0;
|
||||
gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
|
||||
gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
|
||||
gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
|
||||
|
||||
|
||||
gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
|
||||
gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
|
||||
gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
|
||||
gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
|
||||
gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
|
||||
gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
|
||||
gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
|
||||
gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
|
||||
gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
|
||||
gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
|
||||
gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
|
||||
gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
|
||||
gReverseKeyTranslateTable[F13KEY ] = SCA_IInputDevice::KX_F13KEY;
|
||||
gReverseKeyTranslateTable[F14KEY ] = SCA_IInputDevice::KX_F14KEY;
|
||||
gReverseKeyTranslateTable[F15KEY ] = SCA_IInputDevice::KX_F15KEY;
|
||||
gReverseKeyTranslateTable[F16KEY ] = SCA_IInputDevice::KX_F16KEY;
|
||||
gReverseKeyTranslateTable[F17KEY ] = SCA_IInputDevice::KX_F17KEY;
|
||||
gReverseKeyTranslateTable[F18KEY ] = SCA_IInputDevice::KX_F18KEY;
|
||||
gReverseKeyTranslateTable[F19KEY ] = SCA_IInputDevice::KX_F19KEY;
|
||||
|
||||
|
||||
gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
|
||||
gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
|
||||
gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
|
||||
gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
|
||||
gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
|
||||
gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
|
||||
}
|
||||
|
||||
int executePriority = 0;
|
||||
int uniqueint = 0;
|
||||
int count = 0;
|
||||
bSensor* sens = (bSensor*)blenderobject->sensors.first;
|
||||
bool pos_pulsemode = false;
|
||||
bool neg_pulsemode = false;
|
||||
int frequency = 0;
|
||||
bool invert = false;
|
||||
bool level = false;
|
||||
bool tap = false;
|
||||
|
||||
while (sens)
|
||||
{
|
||||
sens = sens->next;
|
||||
count++;
|
||||
}
|
||||
gameobj->ReserveSensor(count);
|
||||
sens = (bSensor*)blenderobject->sensors.first;
|
||||
while(sens)
|
||||
{
|
||||
SCA_ISensor* gamesensor=NULL;
|
||||
/* All sensors have a pulse toggle, frequency, and invert field. */
|
||||
/* These are extracted here, and set when the sensor is added to the */
|
||||
/* list. */
|
||||
pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
|
||||
neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
|
||||
|
||||
frequency = sens->freq;
|
||||
invert = !(sens->invert == 0);
|
||||
level = !(sens->level == 0);
|
||||
tap = !(sens->tap == 0);
|
||||
|
||||
switch (sens->type)
|
||||
{
|
||||
case SENS_ALWAYS:
|
||||
{
|
||||
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SENS_DELAY:
|
||||
{
|
||||
// we can reuse the Always event manager for the delay sensor
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
|
||||
gamesensor = new SCA_DelaySensor(eventmgr,
|
||||
gameobj,
|
||||
delaysensor->delay,
|
||||
delaysensor->duration,
|
||||
(delaysensor->flag & SENS_DELAY_REPEAT) != 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SENS_COLLISION:
|
||||
{
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
// collision sensor can sense both materials and properties.
|
||||
|
||||
bool bFindMaterial = false, bTouchPulse = false;
|
||||
|
||||
bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
|
||||
|
||||
bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
|
||||
bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
|
||||
|
||||
|
||||
STR_String touchPropOrMatName = ( bFindMaterial ?
|
||||
blendertouchsensor->materialName:
|
||||
(blendertouchsensor->name ? blendertouchsensor->name: ""));
|
||||
|
||||
|
||||
if (gameobj->GetPhysicsController())
|
||||
{
|
||||
gamesensor = new KX_TouchSensor(eventmgr,
|
||||
gameobj,
|
||||
bFindMaterial,
|
||||
bTouchPulse,
|
||||
touchPropOrMatName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SENS_TOUCH:
|
||||
{
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String touchpropertyname;
|
||||
bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
|
||||
|
||||
if (blendertouchsensor->ma)
|
||||
{
|
||||
touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
|
||||
}
|
||||
bool bFindMaterial = true;
|
||||
if (gameobj->GetPhysicsController())
|
||||
{
|
||||
gamesensor = new KX_TouchSensor(eventmgr,
|
||||
gameobj,
|
||||
bFindMaterial,
|
||||
false,
|
||||
touchpropertyname);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SENS_MESSAGE:
|
||||
{
|
||||
KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
|
||||
logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
|
||||
if (eventmgr) {
|
||||
bMessageSensor* msgSens = (bMessageSensor*) sens->data;
|
||||
|
||||
/* Get our NetworkScene */
|
||||
NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
|
||||
/* filter on the incoming subjects, might be empty */
|
||||
STR_String subject = (msgSens->subject
|
||||
? (char*)msgSens->subject
|
||||
: "");
|
||||
|
||||
gamesensor = new KX_NetworkMessageSensor(
|
||||
eventmgr, // our eventmanager
|
||||
NetworkScene, // our NetworkScene
|
||||
gameobj, // the sensor controlling object
|
||||
subject); // subject to filter on
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SENS_NEAR:
|
||||
{
|
||||
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String nearpropertyname;
|
||||
bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
|
||||
if (blendernearsensor->name)
|
||||
{
|
||||
// only objects that own this property will be taken into account
|
||||
nearpropertyname = (char*) blendernearsensor->name;
|
||||
}
|
||||
|
||||
//DT_ShapeHandle shape = DT_Sphere(0.0);
|
||||
|
||||
// this sumoObject is not deleted by a gameobj, so delete it ourself
|
||||
// later (memleaks)!
|
||||
float radius = blendernearsensor->dist;
|
||||
PHY__Vector3 pos;
|
||||
const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
|
||||
pos[0] = wpos[0];
|
||||
pos[1] = wpos[1];
|
||||
pos[2] = wpos[2];
|
||||
pos[3] = 0.f;
|
||||
bool bFindMaterial = false;
|
||||
PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
|
||||
|
||||
//will be done in KX_TouchEventManager::RegisterSensor()
|
||||
//if (isInActiveLayer)
|
||||
// kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
|
||||
|
||||
|
||||
|
||||
gamesensor = new KX_NearSensor(eventmgr,gameobj,
|
||||
blendernearsensor->dist,
|
||||
blendernearsensor->resetdist,
|
||||
bFindMaterial,
|
||||
nearpropertyname,
|
||||
physCtrl);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SENS_KEYBOARD:
|
||||
{
|
||||
/* temporary input device, for converting the code for the keyboard sensor */
|
||||
|
||||
bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
|
||||
SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
gamesensor = new SCA_KeyboardSensor(eventmgr,
|
||||
gReverseKeyTranslateTable[blenderkeybdsensor->key],
|
||||
gReverseKeyTranslateTable[blenderkeybdsensor->qual],
|
||||
gReverseKeyTranslateTable[blenderkeybdsensor->qual2],
|
||||
(blenderkeybdsensor->type == SENS_ALL_KEYS),
|
||||
blenderkeybdsensor->targetName,
|
||||
blenderkeybdsensor->toggleName,
|
||||
gameobj); // blenderkeybdsensor->pad);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SENS_MOUSE:
|
||||
{
|
||||
int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
|
||||
int trackfocus = 0;
|
||||
bMouseSensor *bmouse = (bMouseSensor *)sens->data;
|
||||
|
||||
/* There are two main types of mouse sensors. If there is
|
||||
* no focus-related behaviour requested, we can make do
|
||||
* with a basic sensor. This cuts down memory usage and
|
||||
* gives a slight performance gain. */
|
||||
|
||||
SCA_MouseManager *eventmgr
|
||||
= (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
|
||||
if (eventmgr) {
|
||||
|
||||
/* Determine key mode. There is at most one active mode. */
|
||||
switch (bmouse->type) {
|
||||
case BL_SENS_MOUSE_LEFT_BUTTON:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
|
||||
break;
|
||||
case BL_SENS_MOUSE_MIDDLE_BUTTON:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
|
||||
break;
|
||||
case BL_SENS_MOUSE_RIGHT_BUTTON:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
|
||||
break;
|
||||
case BL_SENS_MOUSE_WHEEL_UP:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
|
||||
break;
|
||||
case BL_SENS_MOUSE_WHEEL_DOWN:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
|
||||
break;
|
||||
case BL_SENS_MOUSE_MOVEMENT:
|
||||
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
|
||||
break;
|
||||
case BL_SENS_MOUSE_MOUSEOVER:
|
||||
trackfocus = 1;
|
||||
break;
|
||||
case BL_SENS_MOUSE_MOUSEOVER_ANY:
|
||||
trackfocus = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
; /* error */
|
||||
}
|
||||
|
||||
/* initial mouse position */
|
||||
int startx = canvas->GetWidth()/2;
|
||||
int starty = canvas->GetHeight()/2;
|
||||
|
||||
if (!trackfocus) {
|
||||
/* plain, simple mouse sensor */
|
||||
gamesensor = new SCA_MouseSensor(eventmgr,
|
||||
startx,starty,
|
||||
keytype,
|
||||
gameobj);
|
||||
} else {
|
||||
/* give us a focus-aware sensor */
|
||||
gamesensor = new KX_MouseFocusSensor(eventmgr,
|
||||
startx,
|
||||
starty,
|
||||
keytype,
|
||||
trackfocus,
|
||||
(bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
|
||||
kxscene,
|
||||
kxengine,
|
||||
gameobj);
|
||||
}
|
||||
} else {
|
||||
// cout << "\n Could't find mouse event manager..."; - should throw an error here...
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SENS_PROPERTY:
|
||||
{
|
||||
bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
|
||||
SCA_EventManager* eventmgr
|
||||
= logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String propname=blenderpropsensor->name;
|
||||
STR_String propval=blenderpropsensor->value;
|
||||
STR_String propmaxval=blenderpropsensor->maxvalue;
|
||||
|
||||
SCA_PropertySensor::KX_PROPSENSOR_TYPE
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
|
||||
|
||||
/* Better do an explicit conversion here! (was implicit */
|
||||
/* before...) */
|
||||
switch(blenderpropsensor->type) {
|
||||
case SENS_PROP_EQUAL:
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
|
||||
break;
|
||||
case SENS_PROP_NEQUAL:
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
|
||||
break;
|
||||
case SENS_PROP_INTERVAL:
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
|
||||
break;
|
||||
case SENS_PROP_CHANGED:
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
|
||||
break;
|
||||
case SENS_PROP_EXPRESSION:
|
||||
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
|
||||
/* error */
|
||||
break;
|
||||
default:
|
||||
; /* error */
|
||||
}
|
||||
gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SENS_ACTUATOR:
|
||||
{
|
||||
bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
|
||||
// we will reuse the property event manager, there is nothing special with this sensor
|
||||
SCA_EventManager* eventmgr
|
||||
= logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String propname=blenderactsensor->name;
|
||||
gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SENS_ARMATURE:
|
||||
{
|
||||
bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
|
||||
// we will reuse the property event manager, there is nothing special with this sensor
|
||||
SCA_EventManager* eventmgr
|
||||
= logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String bonename=blenderarmsensor->posechannel;
|
||||
STR_String constraintname=blenderarmsensor->constraint;
|
||||
gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SENS_RADAR:
|
||||
{
|
||||
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
STR_String radarpropertyname;
|
||||
STR_String touchpropertyname;
|
||||
bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
|
||||
|
||||
int radaraxis = blenderradarsensor->axis;
|
||||
|
||||
if (blenderradarsensor->name)
|
||||
{
|
||||
// only objects that own this property will be taken into account
|
||||
radarpropertyname = (char*) blenderradarsensor->name;
|
||||
}
|
||||
|
||||
MT_Scalar coneheight = blenderradarsensor->range;
|
||||
|
||||
// janco: the angle was doubled, so should I divide the factor in 2
|
||||
// or the blenderradarsensor->angle?
|
||||
// nzc: the angle is the opening angle. We need to init with
|
||||
// the axis-hull angle,so /2.0.
|
||||
MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
|
||||
//MT_Scalar coneradius = coneheight * (factor / 2);
|
||||
MT_Scalar coneradius = coneheight * factor;
|
||||
|
||||
|
||||
// this sumoObject is not deleted by a gameobj, so delete it ourself
|
||||
// later (memleaks)!
|
||||
MT_Scalar smallmargin = 0.0;
|
||||
MT_Scalar largemargin = 0.0;
|
||||
|
||||
bool bFindMaterial = false;
|
||||
PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController(coneradius,coneheight);
|
||||
|
||||
gamesensor = new KX_RadarSensor(
|
||||
eventmgr,
|
||||
gameobj,
|
||||
ctrl,
|
||||
coneradius,
|
||||
coneheight,
|
||||
radaraxis,
|
||||
smallmargin,
|
||||
largemargin,
|
||||
bFindMaterial,
|
||||
radarpropertyname);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SENS_RAY:
|
||||
{
|
||||
bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
|
||||
|
||||
//blenderradarsensor->angle;
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
|
||||
bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
|
||||
|
||||
STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
|
||||
|
||||
// don't want to get rays of length 0.0 or so
|
||||
double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
|
||||
int axis = blenderraysensor->axisflag;
|
||||
|
||||
|
||||
gamesensor = new KX_RaySensor(eventmgr,
|
||||
gameobj,
|
||||
checkname,
|
||||
bFindMaterial,
|
||||
bXRay,
|
||||
distance,
|
||||
axis,
|
||||
kxscene);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SENS_RANDOM:
|
||||
{
|
||||
bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
|
||||
// some files didn't write randomsensor, avoid crash now for NULL ptr's
|
||||
if (blenderrndsensor)
|
||||
{
|
||||
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
int randomSeed = blenderrndsensor->seed;
|
||||
if (randomSeed == 0)
|
||||
{
|
||||
randomSeed = (int)(kxengine->GetRealTime()*100000.0);
|
||||
randomSeed ^= (intptr_t)blenderrndsensor;
|
||||
}
|
||||
gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SENS_JOYSTICK:
|
||||
{
|
||||
int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
|
||||
|
||||
bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
|
||||
|
||||
SCA_JoystickManager *eventmgr
|
||||
= (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
|
||||
if (eventmgr)
|
||||
{
|
||||
int axis =0;
|
||||
int axisf =0;
|
||||
int button =0;
|
||||
int hat =0;
|
||||
int hatf =0;
|
||||
int prec =0;
|
||||
|
||||
switch(bjoy->type)
|
||||
{
|
||||
case SENS_JOY_AXIS:
|
||||
axis = bjoy->axis;
|
||||
axisf = bjoy->axisf;
|
||||
prec = bjoy->precision;
|
||||
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
|
||||
break;
|
||||
case SENS_JOY_BUTTON:
|
||||
button = bjoy->button;
|
||||
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
|
||||
break;
|
||||
case SENS_JOY_HAT:
|
||||
hat = bjoy->hat;
|
||||
hatf = bjoy->hatf;
|
||||
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
|
||||
break;
|
||||
case SENS_JOY_AXIS_SINGLE:
|
||||
axis = bjoy->axis_single;
|
||||
prec = bjoy->precision;
|
||||
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
|
||||
break;
|
||||
default:
|
||||
printf("Error: bad case statement\n");
|
||||
break;
|
||||
}
|
||||
gamesensor = new SCA_JoystickSensor(
|
||||
eventmgr,
|
||||
gameobj,
|
||||
bjoy->joyindex,
|
||||
joysticktype,
|
||||
axis,axisf,
|
||||
prec,
|
||||
button,
|
||||
hat,hatf,
|
||||
(bjoy->flag & SENS_JOY_ANY_EVENT));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error there was a problem finding the event manager\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (gamesensor)
|
||||
{
|
||||
gamesensor->SetExecutePriority(executePriority++);
|
||||
STR_String uniquename = sens->name;
|
||||
uniquename += "#SENS#";
|
||||
uniqueint++;
|
||||
CIntValue* uniqueval = new CIntValue(uniqueint);
|
||||
uniquename += uniqueval->GetText();
|
||||
uniqueval->Release();
|
||||
|
||||
/* Conversion succeeded, so we can set the generic props here. */
|
||||
gamesensor->SetPulseMode(pos_pulsemode,
|
||||
neg_pulsemode,
|
||||
frequency);
|
||||
gamesensor->SetInvert(invert);
|
||||
gamesensor->SetLevel(level);
|
||||
gamesensor->SetTap(tap);
|
||||
gamesensor->SetName(sens->name);
|
||||
|
||||
gameobj->AddSensor(gamesensor);
|
||||
|
||||
// only register to manager if it's in an active layer
|
||||
// Make registration dynamic: only when sensor is activated
|
||||
//if (isInActiveLayer)
|
||||
// gamesensor->RegisterToManager();
|
||||
|
||||
gamesensor->ReserveController(sens->totlinks);
|
||||
for (int i=0;i<sens->totlinks;i++)
|
||||
{
|
||||
bController* linkedcont = (bController*) sens->links[i];
|
||||
if (linkedcont) {
|
||||
SCA_IController* gamecont = converter->FindGameController(linkedcont);
|
||||
|
||||
if (gamecont) {
|
||||
logicmgr->RegisterToSensor(gamecont,gamesensor);
|
||||
} else {
|
||||
printf(
|
||||
"Warning, sensor \"%s\" could not find its controller "
|
||||
"(link %d of %d) from object \"%s\"\n"
|
||||
"\tthere has been an error converting the blender controller for the game engine,"
|
||||
"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
|
||||
}
|
||||
} else {
|
||||
printf(
|
||||
"Warning, sensor \"%s\" has lost a link to a controller "
|
||||
"(link %d of %d) from object \"%s\"\n"
|
||||
"\tpossible causes are partially appended objects or an error reading the file,"
|
||||
"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
|
||||
}
|
||||
}
|
||||
// special case: Keyboard sensor with no link
|
||||
// this combination is usually used for key logging.
|
||||
if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
|
||||
// Force the registration so that the sensor runs
|
||||
gamesensor->IncLink();
|
||||
}
|
||||
|
||||
// done with gamesensor
|
||||
gamesensor->Release();
|
||||
|
||||
}
|
||||
sens=sens->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_CONVERTSENSOR_H
|
||||
#define __KX_CONVERTSENSOR_H
|
||||
|
||||
void BL_ConvertSensors(struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
class SCA_LogicManager* logicmgr,
|
||||
class KX_Scene* kxscene,
|
||||
class KX_KetsjiEngine* kxengine,
|
||||
int activeLayerBitInfo,
|
||||
bool isInActiveLayer,
|
||||
class RAS_ICanvas* canvas,
|
||||
class KX_BlenderSceneConverter* converter);
|
||||
|
||||
#endif //__KX_CONVERTSENSOR_H
|
||||
|
||||
@@ -1,480 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// don't show stl-warnings
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include "BKE_material.h" /* give_current_material */
|
||||
|
||||
#include "KX_GameObject.h"
|
||||
#include "KX_IpoConvert.h"
|
||||
#include "KX_IInterpolator.h"
|
||||
#include "KX_ScalarInterpolator.h"
|
||||
|
||||
#include "KX_BlenderScalarInterpolator.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
/* end of blender include block */
|
||||
|
||||
#include "KX_IPO_SGController.h"
|
||||
#include "KX_LightIpoSGController.h"
|
||||
#include "KX_CameraIpoSGController.h"
|
||||
#include "KX_WorldIpoController.h"
|
||||
#include "KX_ObColorIpoSGController.h"
|
||||
#include "KX_MaterialIpoController.h"
|
||||
|
||||
#include "SG_Node.h"
|
||||
|
||||
#include "STR_HashedString.h"
|
||||
|
||||
static BL_InterpolatorList *GetAdtList(struct AnimData *for_adt, KX_BlenderSceneConverter *converter) {
|
||||
BL_InterpolatorList *adtList= converter->FindInterpolatorList(for_adt);
|
||||
|
||||
if (!adtList) {
|
||||
adtList = new BL_InterpolatorList(for_adt);
|
||||
converter->RegisterInterpolatorList(adtList, for_adt);
|
||||
}
|
||||
|
||||
return adtList;
|
||||
}
|
||||
|
||||
void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
|
||||
{
|
||||
if (blenderobject->adt) {
|
||||
|
||||
KX_IpoSGController* ipocontr = new KX_IpoSGController();
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
|
||||
// For ipo_as_force, we need to know which SM object and Scene the
|
||||
// object associated with this ipo is in. Is this already known here?
|
||||
// I think not.... then it must be done later :(
|
||||
// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
|
||||
// gameobj->GetSumoObject());
|
||||
|
||||
ipocontr->SetGameObject(gameobj);
|
||||
|
||||
ipocontr->GetIPOTransform().SetPosition(
|
||||
MT_Point3(
|
||||
blenderobject->loc[0]/*+blenderobject->dloc[0]*/,
|
||||
blenderobject->loc[1]/*+blenderobject->dloc[1]*/,
|
||||
blenderobject->loc[2]/*+blenderobject->dloc[2]*/
|
||||
)
|
||||
);
|
||||
ipocontr->GetIPOTransform().SetEulerAngles(
|
||||
MT_Vector3(
|
||||
blenderobject->rot[0],
|
||||
blenderobject->rot[1],
|
||||
blenderobject->rot[2]
|
||||
)
|
||||
);
|
||||
ipocontr->GetIPOTransform().SetScaling(
|
||||
MT_Vector3(
|
||||
blenderobject->size[0],
|
||||
blenderobject->size[1],
|
||||
blenderobject->size[2]
|
||||
)
|
||||
);
|
||||
|
||||
const char *rotmode, *drotmode;
|
||||
|
||||
switch(blenderobject->rotmode)
|
||||
{
|
||||
case ROT_MODE_AXISANGLE:
|
||||
rotmode = "rotation_axis_angle";
|
||||
drotmode = "delta_rotation_axis_angle";
|
||||
case ROT_MODE_QUAT:
|
||||
rotmode = "rotation_quaternion";
|
||||
drotmode = "delta_rotation_quaternion";
|
||||
default:
|
||||
rotmode = "rotation_euler";
|
||||
drotmode = "delta_rotation_euler";
|
||||
}
|
||||
|
||||
BL_InterpolatorList *adtList= GetAdtList(blenderobject->adt, converter);
|
||||
|
||||
// For each active channel in the adtList add an
|
||||
// interpolator to the game object.
|
||||
|
||||
KX_IInterpolator *interpolator;
|
||||
KX_IScalarInterpolator *interp;
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("location", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetPosition()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_LOC_X+i, true);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("delta_location", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaPosition()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_DLOC_X+i, true);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator(rotmode, i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetEulerAngles()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_ROT_X+i, true);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator(drotmode, i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_DROT_X+i, true);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("scale", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetScaling()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_SIZE_X+i, true);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("delta_scale", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaScaling()[i]), interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetIPOChannelActive(OB_DSIZE_X+i, true);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
KX_ObColorIpoSGController* ipocontr_obcol=NULL;
|
||||
|
||||
for(int i=0; i<4; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("color", i))) {
|
||||
if (!ipocontr_obcol) {
|
||||
ipocontr_obcol = new KX_ObColorIpoSGController();
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
|
||||
ipocontr_obcol->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
|
||||
ipocontr_obcol->AddInterpolator(interpolator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
|
||||
{
|
||||
|
||||
if (blenderlamp->adt) {
|
||||
|
||||
KX_LightIpoSGController* ipocontr = new KX_LightIpoSGController();
|
||||
lightobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(lightobj->GetSGNode());
|
||||
|
||||
ipocontr->m_energy = blenderlamp->energy;
|
||||
ipocontr->m_col_rgb[0] = blenderlamp->r;
|
||||
ipocontr->m_col_rgb[1] = blenderlamp->g;
|
||||
ipocontr->m_col_rgb[2] = blenderlamp->b;
|
||||
ipocontr->m_dist = blenderlamp->dist;
|
||||
|
||||
BL_InterpolatorList *adtList= GetAdtList(blenderlamp->adt, converter);
|
||||
|
||||
// For each active channel in the adtList add an
|
||||
// interpolator to the game object.
|
||||
|
||||
KX_IInterpolator *interpolator;
|
||||
KX_IScalarInterpolator *interp;
|
||||
|
||||
if ((interp= adtList->GetScalarInterpolator("energy", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_energy, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyEnergy(true);
|
||||
}
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("distance", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_dist, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyDist(true);
|
||||
}
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("color", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_col_rgb[i], interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyColor(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BL_ConvertCameraIpos(struct Camera* blendercamera, KX_GameObject *cameraobj,KX_BlenderSceneConverter *converter)
|
||||
{
|
||||
|
||||
if (blendercamera->adt) {
|
||||
|
||||
KX_CameraIpoSGController* ipocontr = new KX_CameraIpoSGController();
|
||||
cameraobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(cameraobj->GetSGNode());
|
||||
|
||||
ipocontr->m_lens = blendercamera->lens;
|
||||
ipocontr->m_clipstart = blendercamera->clipsta;
|
||||
ipocontr->m_clipend = blendercamera->clipend;
|
||||
|
||||
BL_InterpolatorList *adtList= GetAdtList(blendercamera->adt, converter);
|
||||
|
||||
// For each active channel in the adtList add an
|
||||
// interpolator to the game object.
|
||||
|
||||
KX_IInterpolator *interpolator;
|
||||
KX_IScalarInterpolator *interp;
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("lens", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_lens, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyLens(true);
|
||||
}
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("clip_start", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_clipstart, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyClipStart(true);
|
||||
}
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("clip_end", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_clipend, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyClipEnd(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
|
||||
{
|
||||
|
||||
if (blenderworld->adt) {
|
||||
|
||||
KX_WorldIpoController* ipocontr = new KX_WorldIpoController();
|
||||
|
||||
// Erwin, hook up the world ipo controller here
|
||||
// Gino: hook it up to what ?
|
||||
// is there a userinterface element for that ?
|
||||
// for now, we have some new python hooks to access the data, for a work-around
|
||||
|
||||
ipocontr->m_mist_start = blenderworld->miststa;
|
||||
ipocontr->m_mist_dist = blenderworld->mistdist;
|
||||
ipocontr->m_mist_rgb[0] = blenderworld->horr;
|
||||
ipocontr->m_mist_rgb[1] = blenderworld->horg;
|
||||
ipocontr->m_mist_rgb[2] = blenderworld->horb;
|
||||
|
||||
BL_InterpolatorList *adtList= GetAdtList(blenderworld->adt, converter);
|
||||
|
||||
// For each active channel in the adtList add an
|
||||
// interpolator to the game object.
|
||||
|
||||
KX_IInterpolator *interpolator;
|
||||
KX_IScalarInterpolator *interp;
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((interp = adtList->GetScalarInterpolator("horizon_color", i))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[i], interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyMistColor(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("mist.depth", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_dist, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyMistDist(true);
|
||||
}
|
||||
|
||||
if ((interp = adtList->GetScalarInterpolator("mist.start", 0))) {
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_start, interp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
ipocontr->SetModifyMistStart(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertMaterialIpos(
|
||||
Material* blendermaterial,
|
||||
dword matname_hash,
|
||||
KX_GameObject* gameobj,
|
||||
KX_BlenderSceneConverter *converter
|
||||
)
|
||||
{
|
||||
if (blendermaterial->adt) {
|
||||
KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
|
||||
BL_InterpolatorList *adtList= GetAdtList(blendermaterial->adt, converter);
|
||||
|
||||
|
||||
ipocontr->m_rgba[0] = blendermaterial->r;
|
||||
ipocontr->m_rgba[1] = blendermaterial->g;
|
||||
ipocontr->m_rgba[2] = blendermaterial->b;
|
||||
ipocontr->m_rgba[3] = blendermaterial->alpha;
|
||||
|
||||
ipocontr->m_specrgb[0] = blendermaterial->specr;
|
||||
ipocontr->m_specrgb[1] = blendermaterial->specg;
|
||||
ipocontr->m_specrgb[2] = blendermaterial->specb;
|
||||
|
||||
ipocontr->m_hard = blendermaterial->har;
|
||||
ipocontr->m_spec = blendermaterial->spec;
|
||||
ipocontr->m_ref = blendermaterial->ref;
|
||||
ipocontr->m_emit = blendermaterial->emit;
|
||||
ipocontr->m_alpha = blendermaterial->alpha;
|
||||
|
||||
KX_IInterpolator *interpolator;
|
||||
KX_IScalarInterpolator *sinterp;
|
||||
|
||||
// --
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((sinterp = adtList->GetScalarInterpolator("diffuse_color", i))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[i], sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sinterp = adtList->GetScalarInterpolator("alpha", 0))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[3], sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
if ((sinterp = adtList->GetScalarInterpolator("specular_color", i))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_specrgb[i], sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sinterp = adtList->GetScalarInterpolator("specular_hardness", 0))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_hard, sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
|
||||
if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_spec, sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
|
||||
if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_ref, sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
|
||||
if ((sinterp = adtList->GetScalarInterpolator("emit", 0))) {
|
||||
if (!ipocontr) {
|
||||
ipocontr = new KX_MaterialIpoController(matname_hash);
|
||||
gameobj->GetSGNode()->AddSGController(ipocontr);
|
||||
ipocontr->SetObject(gameobj->GetSGNode());
|
||||
}
|
||||
interpolator= new KX_ScalarInterpolator(&ipocontr->m_emit, sinterp);
|
||||
ipocontr->AddInterpolator(interpolator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BL_ConvertMaterialIpos(
|
||||
struct Object* blenderobject,
|
||||
KX_GameObject* gameobj,
|
||||
KX_BlenderSceneConverter *converter
|
||||
)
|
||||
{
|
||||
if (blenderobject->totcol==1)
|
||||
{
|
||||
Material *mat = give_current_material(blenderobject, 1);
|
||||
// if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
|
||||
// --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
|
||||
// because this yields a better performance as not all the vertex colors need to be edited
|
||||
if(mat) ConvertMaterialIpos(mat, 0, gameobj, converter);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
|
||||
{
|
||||
Material *mat = give_current_material(blenderobject, material_index);
|
||||
STR_HashedString matname;
|
||||
if(mat) {
|
||||
matname= mat->id.name; // who is using this name? can we remove the MA here?
|
||||
ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_IPOCONVERT_H
|
||||
#define __KX_IPOCONVERT_H
|
||||
|
||||
struct Object;
|
||||
|
||||
void BL_ConvertIpos(struct Object* blenderobject,
|
||||
class KX_GameObject* gameobj,
|
||||
class KX_BlenderSceneConverter *converter);
|
||||
|
||||
void BL_ConvertLampIpos(struct Lamp* blenderlight,
|
||||
class KX_GameObject* lightobj,
|
||||
class KX_BlenderSceneConverter *converter);
|
||||
|
||||
void BL_ConvertWorldIpos(struct World* blenderworld,
|
||||
class KX_BlenderSceneConverter *converter);
|
||||
|
||||
void BL_ConvertCameraIpos(struct Camera* blendercamera,
|
||||
class KX_GameObject* cameraobj,
|
||||
class KX_BlenderSceneConverter *converter);
|
||||
|
||||
void BL_ConvertMaterialIpos(struct Object* blenderobject,
|
||||
class KX_GameObject* materialobj,
|
||||
class KX_BlenderSceneConverter *converter);
|
||||
|
||||
|
||||
#endif //__KX_IPOCONVERT_H
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
#include "MT_assert.h"
|
||||
|
||||
#include "KX_ConvertPhysicsObject.h"
|
||||
#include "KX_SoftBodyDeformer.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
#include "GEN_Map.h"
|
||||
#include "GEN_HashedPtr.h"
|
||||
|
||||
#ifdef USE_BULLET
|
||||
|
||||
#include "CcdPhysicsEnvironment.h"
|
||||
#include "CcdPhysicsController.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
#include "KX_BulletPhysicsController.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
void KX_SoftBodyDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
|
||||
{
|
||||
void **h_obj = (*map)[m_gameobj];
|
||||
|
||||
if (h_obj) {
|
||||
m_gameobj = (BL_DeformableGameObject*)(*h_obj);
|
||||
m_pMeshObject = m_gameobj->GetMesh(0);
|
||||
} else {
|
||||
m_gameobj = NULL;
|
||||
m_pMeshObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool KX_SoftBodyDeformer::Apply(class RAS_IPolyMaterial *polymat)
|
||||
{
|
||||
KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController();
|
||||
if (!ctrl)
|
||||
return false;
|
||||
|
||||
btSoftBody* softBody= ctrl->GetSoftBody();
|
||||
if (!softBody)
|
||||
return false;
|
||||
|
||||
//printf("apply\n");
|
||||
RAS_MeshSlot::iterator it;
|
||||
RAS_MeshMaterial *mmat;
|
||||
RAS_MeshSlot *slot;
|
||||
size_t i;
|
||||
|
||||
// update the vertex in m_transverts
|
||||
Update();
|
||||
|
||||
// The vertex cache can only be updated for this deformer:
|
||||
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
|
||||
// share the same mesh (=the same cache). As the rendering is done per polymaterial
|
||||
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
|
||||
mmat = m_pMeshObject->GetMeshMaterial(polymat);
|
||||
if(!mmat->m_slots[(void*)m_gameobj])
|
||||
return true;
|
||||
|
||||
slot = *mmat->m_slots[(void*)m_gameobj];
|
||||
|
||||
// for each array
|
||||
for(slot->begin(it); !slot->end(it); slot->next(it))
|
||||
{
|
||||
btSoftBody::tNodeArray& nodes(softBody->m_nodes);
|
||||
|
||||
int index = 0;
|
||||
for(i=it.startvertex; i<it.endvertex; i++,index++) {
|
||||
RAS_TexVert& v = it.vertex[i];
|
||||
btAssert(v.getSoftBodyIndex() >= 0);
|
||||
|
||||
MT_Point3 pt (
|
||||
nodes[v.getSoftBodyIndex()].m_x.getX(),
|
||||
nodes[v.getSoftBodyIndex()].m_x.getY(),
|
||||
nodes[v.getSoftBodyIndex()].m_x.getZ());
|
||||
v.SetXYZ(pt);
|
||||
|
||||
MT_Vector3 normal (
|
||||
nodes[v.getSoftBodyIndex()].m_n.getX(),
|
||||
nodes[v.getSoftBodyIndex()].m_n.getY(),
|
||||
nodes[v.getSoftBodyIndex()].m_n.getZ());
|
||||
v.SetNormal(normal);
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef KX_SOFTBODYDEFORMER
|
||||
#define KX_SOFTBODYDEFORMER
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
|
||||
#endif //WIN32
|
||||
|
||||
#include "RAS_Deformer.h"
|
||||
#include "BL_DeformableGameObject.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
class KX_SoftBodyDeformer : public RAS_Deformer
|
||||
{
|
||||
class RAS_MeshObject* m_pMeshObject;
|
||||
class BL_DeformableGameObject* m_gameobj;
|
||||
|
||||
public:
|
||||
KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
|
||||
:m_pMeshObject(pMeshObject),
|
||||
m_gameobj(gameobj)
|
||||
{
|
||||
//printf("KX_SoftBodyDeformer\n");
|
||||
};
|
||||
|
||||
virtual ~KX_SoftBodyDeformer()
|
||||
{
|
||||
//printf("~KX_SoftBodyDeformer\n");
|
||||
};
|
||||
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map);
|
||||
virtual bool Apply(class RAS_IPolyMaterial *polymat);
|
||||
virtual bool Update(void)
|
||||
{
|
||||
//printf("update\n");
|
||||
m_bDynamic = true;
|
||||
return true;//??
|
||||
}
|
||||
virtual bool UpdateBuckets(void)
|
||||
{
|
||||
// this is to update the mesh slots outside the rasterizer,
|
||||
// no need to do it for this deformer, it's done in any case in Apply()
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual RAS_Deformer *GetReplica()
|
||||
{
|
||||
KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
|
||||
deformer->ProcessReplica();
|
||||
return deformer;
|
||||
}
|
||||
virtual void ProcessReplica()
|
||||
{
|
||||
// we have two pointers to deal with but we cannot do it now, will be done in Relink
|
||||
m_bDynamic = false;
|
||||
}
|
||||
virtual bool SkipVertexTransform()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
//class RAS_MeshObject *m_pMesh;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ShapeDeformer"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = blconverter
|
||||
DIR = $(OCGDIR)/gameengine/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
CPPFLAGS += -I$(NAN_STRING)/include
|
||||
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
|
||||
CPPFLAGS += -I$(NAN_MOTO)/include
|
||||
CPPFLAGS += -I$(NAN_BULLET2)/include
|
||||
CPPFLAGS += -I$(NAN_AUDASPACE)/include
|
||||
|
||||
CPPFLAGS += -I../../blender
|
||||
# these two needed because of blenkernel
|
||||
CPPFLAGS += -I../../blender/windowmanager
|
||||
CPPFLAGS += -I../../blender/imbuf
|
||||
CPPFLAGS += -I../../blender/makesdna
|
||||
CPPFLAGS += -I../../blender/makesrna
|
||||
CPPFLAGS += -I../../blender/editors/include
|
||||
CPPFLAGS += -I../../blender/blenlib
|
||||
CPPFLAGS += -I../../blender/blenkernel
|
||||
CPPFLAGS += -I../../blender/blenloader
|
||||
CPPFLAGS += -I../../blender/render/extern/include
|
||||
CPPFLAGS += -I../../blender/gpu
|
||||
CPPFLAGS += -I../../blender/ikplugin
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
CPPFLAGS += -I../Expressions -I../Rasterizer -I../GameLogic
|
||||
CPPFLAGS += -I../Ketsji -I../BlenderRoutines -I../SceneGraph
|
||||
CPPFLAGS += -I../../kernel/gen_system
|
||||
CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
|
||||
CPPFLAGS += -I../Network -I../Ketsji/KXNetwork
|
||||
CPPFLAGS += -I../Physics/common -I../Physics/Dummy
|
||||
CPPFLAGS += -I../Physics/BlOde
|
||||
CPPFLAGS += -I../Physics/Bullet
|
||||
CPPFLAGS += -I.
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('*.cpp')
|
||||
defs = []
|
||||
|
||||
incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
|
||||
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
|
||||
incs += ' #intern/audaspace/intern #source/gameengine/Converter'
|
||||
incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf'
|
||||
incs += ' #intern/moto/include #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork'
|
||||
incs += ' #source/blender/blenlib #source/blender/blenkernel #source/blender'
|
||||
incs += ' #source/blender/editors/include #source/blender/makesdna #source/gameengine/Rasterizer'
|
||||
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #source/gameengine/GameLogic'
|
||||
incs += ' #source/gameengine/Expressions #source/gameengine/Network #source/gameengine/SceneGraph'
|
||||
incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet'
|
||||
incs += ' #source/gameengine/Physics/Dummy'
|
||||
incs += ' #source/gameengine/Network/LoopBackNetwork'
|
||||
incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu'
|
||||
incs += ' #source/blender/windowmanager'
|
||||
incs += ' #source/blender/makesrna'
|
||||
incs += ' #source/blender/ikplugin'
|
||||
incs += ' #source/blender/bmesh'
|
||||
|
||||
incs += ' ' + env['BF_BULLET_INC']
|
||||
|
||||
if env['BF_DEBUG']:
|
||||
if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc', 'win64-vc'):
|
||||
defs.append('_DEBUG')
|
||||
|
||||
if env['WITH_BF_PYTHON']:
|
||||
incs += ' ' + env['BF_PYTHON_INC']
|
||||
else:
|
||||
defs.append('DISABLE_PYTHON')
|
||||
|
||||
env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS'])
|
||||
@@ -1,209 +0,0 @@
|
||||
|
||||
// BoolValue.cpp: implementation of the CBoolValue class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BoolValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "VoidValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const STR_String CBoolValue::sTrueString = "TRUE";
|
||||
const STR_String CBoolValue::sFalseString = "FALSE";
|
||||
|
||||
CBoolValue::CBoolValue()
|
||||
/*
|
||||
pre: false
|
||||
effect: constructs a new CBoolValue
|
||||
*/
|
||||
{
|
||||
trace("Bool constructor error");
|
||||
}
|
||||
|
||||
|
||||
|
||||
CBoolValue::CBoolValue(bool inBool)
|
||||
: m_bool(inBool)
|
||||
{
|
||||
} // Constructs a new CBoolValue containing <inBool>
|
||||
|
||||
|
||||
|
||||
CBoolValue::CBoolValue(bool innie,const char *name,AllocationTYPE alloctype)
|
||||
{
|
||||
m_bool = innie;
|
||||
SetName(name);
|
||||
|
||||
if (alloctype == CValue::STACKVALUE)
|
||||
CValue::DisableRefCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CBoolValue::SetValue(CValue* newval)
|
||||
{
|
||||
m_bool = (newval->GetNumber() != 0);
|
||||
SetModified(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CBoolValue::Calc(VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator op to this
|
||||
object and val
|
||||
*/
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case VALUE_POS_OPERATOR:
|
||||
case VALUE_NEG_OPERATOR:
|
||||
{
|
||||
return new CErrorValue (op2str(op) + GetText());
|
||||
break;
|
||||
}
|
||||
case VALUE_NOT_OPERATOR:
|
||||
{
|
||||
return new CBoolValue (!m_bool);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return val->CalcFinal(VALUE_BOOL_TYPE, op, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CBoolValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre: the type of val is dtype
|
||||
ret: a new object containing the result of applying operator op to val and
|
||||
this object
|
||||
*/
|
||||
{
|
||||
CValue *ret;
|
||||
|
||||
switch(dtype)
|
||||
{
|
||||
case VALUE_EMPTY_TYPE:
|
||||
case VALUE_BOOL_TYPE:
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case VALUE_AND_OPERATOR:
|
||||
{
|
||||
ret = new CBoolValue (((CBoolValue *) val)->GetBool() && m_bool);
|
||||
break;
|
||||
}
|
||||
case VALUE_OR_OPERATOR:
|
||||
{
|
||||
ret = new CBoolValue (((CBoolValue *) val)->GetBool() || m_bool);
|
||||
break;
|
||||
}
|
||||
case VALUE_EQL_OPERATOR:
|
||||
{
|
||||
ret = new CBoolValue (((CBoolValue *) val)->GetBool() == m_bool);
|
||||
break;
|
||||
}
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
{
|
||||
ret = new CBoolValue (((CBoolValue *) val)->GetBool() != m_bool);
|
||||
break;
|
||||
}
|
||||
case VALUE_NOT_OPERATOR:
|
||||
{
|
||||
return new CBoolValue (!m_bool);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ret = new CErrorValue(val->GetText() + op2str(op) +
|
||||
"[operator not allowed on booleans]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_STRING_TYPE:
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case VALUE_ADD_OPERATOR:
|
||||
{
|
||||
ret = new CStringValue(val->GetText() + GetText(),"");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ret = new CErrorValue(val->GetText() + op2str(op) + "[Only + allowed on boolean and string]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = new CErrorValue("[type mismatch]" + op2str(op) + GetText());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CBoolValue::GetBool()
|
||||
/*
|
||||
pre:
|
||||
ret: the bool stored in the object
|
||||
*/
|
||||
{
|
||||
return m_bool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CBoolValue::GetNumber()
|
||||
{
|
||||
return (double)m_bool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const STR_String& CBoolValue::GetText()
|
||||
{
|
||||
return m_bool ? sTrueString : sFalseString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CBoolValue::GetReplica()
|
||||
{
|
||||
CBoolValue* replica = new CBoolValue(*this);
|
||||
replica->ProcessReplica();
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject* CBoolValue::ConvertValueToPython()
|
||||
{
|
||||
return PyBool_FromLong(m_bool != 0);
|
||||
}
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* BoolValue.h: interface for the CBoolValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#if !defined _BOOLVALUE_H
|
||||
#define _BOOLVALUE_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
/**
|
||||
* Smart Boolean Value class.
|
||||
* Is used by parser when an expression tree is build containing booleans.
|
||||
*/
|
||||
|
||||
class CBoolValue : public CPropValue
|
||||
{
|
||||
|
||||
//PLUGIN_DECLARE_SERIAL(CBoolValue,CValue)
|
||||
|
||||
public:
|
||||
static const STR_String sTrueString;
|
||||
static const STR_String sFalseString;
|
||||
|
||||
CBoolValue();
|
||||
CBoolValue(bool inBool);
|
||||
CBoolValue(bool innie, const char *name, AllocationTYPE alloctype = CValue::HEAPVALUE);
|
||||
|
||||
virtual const STR_String& GetText();
|
||||
virtual double GetNumber();
|
||||
bool GetBool();
|
||||
virtual void SetValue(CValue* newval);
|
||||
|
||||
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
|
||||
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
|
||||
|
||||
void Configure(CValue* menuvalue);
|
||||
virtual CValue* GetReplica();
|
||||
#ifndef DISABLE_PYTHON
|
||||
virtual PyObject* ConvertValueToPython();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_bool;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CBoolValue"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _BOOLVALUE_H
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
SET(INC
|
||||
.
|
||||
../../../source/kernel/gen_system
|
||||
../../../intern/string
|
||||
../../../intern/guardedalloc
|
||||
../../../intern/moto/include
|
||||
../../../source/gameengine/SceneGraph
|
||||
../../../source/blender/blenloader
|
||||
)
|
||||
|
||||
IF(WITH_PYTHON)
|
||||
SET(INC ${INC} ${PYTHON_INC})
|
||||
ELSE(WITH_PYTHON)
|
||||
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
||||
ENDIF(WITH_PYTHON)
|
||||
|
||||
BLENDERLIB(bf_expressions "${SRC}" "${INC}")
|
||||
@@ -1,128 +0,0 @@
|
||||
// ConstExpr.cpp: implementation of the CConstExpr class.
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Value.h" // for precompiled header
|
||||
#include "ConstExpr.h"
|
||||
#include "VectorValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CConstExpr::CConstExpr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
CConstExpr::CConstExpr(CValue* constval)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a CConstExpr cointing the value constval
|
||||
*/
|
||||
{
|
||||
m_value = constval;
|
||||
// m_bModified=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CConstExpr::~CConstExpr()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
if (m_value)
|
||||
m_value->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char CConstExpr::GetExpressionID()
|
||||
{
|
||||
return CCONSTEXPRESSIONID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CConstExpr::Calculate()
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the value of the stored CValue
|
||||
*/
|
||||
{
|
||||
return m_value->AddRef();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CConstExpr::ClearModified()
|
||||
{
|
||||
if (m_value)
|
||||
{
|
||||
m_value->SetModified(false);
|
||||
m_value->SetAffected(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CConstExpr::GetNumber()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CConstExpr::NeedsRecalculated()
|
||||
{
|
||||
return m_value->IsAffected(); // IsAffected is m_bModified OR m_bAffected !!!
|
||||
}
|
||||
|
||||
|
||||
|
||||
CExpression* CConstExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
|
||||
{
|
||||
// parent checks if child is still usefull.
|
||||
// When for example it's value it's deleted flag set
|
||||
// then release Value, and return NULL in case of constexpression
|
||||
// else return this...
|
||||
|
||||
assertd(m_value);
|
||||
if (m_value->IsReleaseRequested())
|
||||
{
|
||||
AddRef(); //numchanges++;
|
||||
return Release();
|
||||
}
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CConstExpr::BroadcastOperators(VALUE_OPERATOR op)
|
||||
{
|
||||
assertd(m_value);
|
||||
m_value->SetColorOperator(op);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CConstExpr::MergeExpression(CExpression *otherexpr)
|
||||
{
|
||||
assertd(false);
|
||||
return false;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* ConstExpr.h: interface for the CConstExpr class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONSTEXPR_H__
|
||||
#define __CONSTEXPR_H__
|
||||
|
||||
#include "Expression.h"
|
||||
#include "Value.h" // Added by ClassView
|
||||
|
||||
class CConstExpr : public CExpression
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL_EXPRESSION (CConstExpr,CExpression)
|
||||
public:
|
||||
virtual bool MergeExpression(CExpression* otherexpr);
|
||||
|
||||
void BroadcastOperators(VALUE_OPERATOR op);
|
||||
|
||||
virtual unsigned char GetExpressionID();
|
||||
CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
|
||||
//bool IsInside(float x,float y,float z,bool bBorderInclude=true);
|
||||
bool NeedsRecalculated();
|
||||
void ClearModified();
|
||||
virtual double GetNumber();
|
||||
virtual CValue* Calculate();
|
||||
CConstExpr(CValue* constval);
|
||||
CConstExpr();
|
||||
virtual ~CConstExpr();
|
||||
|
||||
|
||||
private:
|
||||
CValue* m_value;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CConstExpr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_CONSTEXPR_H__061ECFC3_BE87_11D1_A51C_00A02472FC58__INCLUDED_)
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#include "EXP_C-Api.h"
|
||||
#include "IntValue.h"
|
||||
#include "BoolValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "InputParser.h"
|
||||
|
||||
EXP_ValueHandle EXP_CreateInt(int innie)
|
||||
{
|
||||
return (EXP_ValueHandle) new CIntValue(innie);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXP_ValueHandle EXP_CreateBool(int innie)
|
||||
{
|
||||
return (EXP_ValueHandle) new CBoolValue(innie!=0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXP_ValueHandle EXP_CreateString(const char* str)
|
||||
{
|
||||
|
||||
return (EXP_ValueHandle) new CStringValue(str,"");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EXP_SetName(EXP_ValueHandle inval,const char* newname)
|
||||
{
|
||||
((CValue*) inval)->SetName(newname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* calculate expression from inputtext */
|
||||
EXP_ValueHandle EXP_ParseInput(const char* inputtext)
|
||||
{
|
||||
CValue* resultval=NULL;
|
||||
CParser parser;
|
||||
CExpression* expr = parser.ProcessText(inputtext);
|
||||
if (expr)
|
||||
{
|
||||
resultval = expr->Calculate();
|
||||
expr->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
resultval = new CErrorValue("couldn't parsetext");
|
||||
}
|
||||
|
||||
return (EXP_ValueHandle) resultval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EXP_ReleaseValue(EXP_ValueHandle inval)
|
||||
{
|
||||
((CValue*) inval)->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int EXP_IsValid(EXP_ValueHandle inval)
|
||||
{
|
||||
return !((CValue*) inval)->IsError();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* assign property 'propval' to 'destinationval' */
|
||||
void EXP_SetProperty(EXP_ValueHandle destinationval,
|
||||
const char* propname,
|
||||
EXP_ValueHandle propval)
|
||||
{
|
||||
((CValue*) destinationval)->SetProperty(propname,(CValue*)propval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* EXP_GetText(EXP_ValueHandle inval)
|
||||
{
|
||||
return ((CValue*) inval)->GetText();
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname)
|
||||
{
|
||||
return (EXP_ValueHandle) ((CValue*)inval)->GetProperty(propname);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __EXPRESSION_INCLUDE
|
||||
#define __EXPRESSION_INCLUDE
|
||||
|
||||
#define EXP_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
EXP_DECLARE_HANDLE(EXP_ValueHandle);
|
||||
EXP_DECLARE_HANDLE(EXP_ExpressionHandle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern EXP_ValueHandle EXP_CreateInt(int innie);
|
||||
extern EXP_ValueHandle EXP_CreateBool(int innie);
|
||||
extern EXP_ValueHandle EXP_CreateString(const char* str);
|
||||
extern void EXP_SetName(EXP_ValueHandle,const char* newname);
|
||||
|
||||
/* calculate expression from inputtext */
|
||||
extern EXP_ValueHandle EXP_ParseInput(const char* inputtext);
|
||||
extern void EXP_ReleaseValue(EXP_ValueHandle);
|
||||
extern int EXP_IsValid(EXP_ValueHandle);
|
||||
|
||||
/* assign property 'propval' to 'destinationval' */
|
||||
extern void EXP_SetProperty(EXP_ValueHandle propval,EXP_ValueHandle destinationval);
|
||||
|
||||
/* returns NULL if property doesn't exist */
|
||||
extern EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname);
|
||||
|
||||
const char* EXP_GetText(EXP_ValueHandle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__EXPRESSION_INCLUDE
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
|
||||
// EmptyValue.cpp: implementation of the CEmptyValue class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EmptyValue.h"
|
||||
#include "IntValue.h"
|
||||
#include "FloatValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "ListValue.h"
|
||||
#include "VoidValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CEmptyValue::CEmptyValue()
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CEmptyValue
|
||||
*/
|
||||
{
|
||||
SetModified(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CEmptyValue::~CEmptyValue()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue * CEmptyValue::Calc(VALUE_OPERATOR op, CValue * val)
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator op to this
|
||||
object and val
|
||||
*/
|
||||
{
|
||||
return val->CalcFinal(VALUE_EMPTY_TYPE, op, this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue * CEmptyValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue * val)
|
||||
/*
|
||||
pre: the type of val is dtype
|
||||
ret: a new object containing the result of applying operator op to val and
|
||||
this object
|
||||
*/
|
||||
{
|
||||
return val->AddRef();
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CEmptyValue::GetNumber()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CListValue* CEmptyValue::GetPolySoup()
|
||||
{
|
||||
CListValue* soup = new CListValue();
|
||||
//don't add any poly, while it's an empty value
|
||||
return soup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CEmptyValue::IsInside(CValue* testpoint,bool bBorderInclude)
|
||||
{
|
||||
// empty space is solid, so always inside
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double* CEmptyValue::GetVector3(bool bGetTransformedVec)
|
||||
{
|
||||
assertd(false); // don't get vector from me
|
||||
return ZeroVector();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static STR_String emptyString = STR_String("");
|
||||
|
||||
|
||||
const STR_String & CEmptyValue::GetText()
|
||||
{
|
||||
return emptyString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CEmptyValue::GetReplica()
|
||||
{
|
||||
CEmptyValue* replica = new CEmptyValue(*this);
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* EmptyValue.h: interface for the CEmptyValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#if !defined _EMPTYVALUE_H
|
||||
#define _EMPTYVALUE_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
class CListValue;
|
||||
|
||||
class CEmptyValue : public CPropValue
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL (CEmptyValue,CValue)
|
||||
public:
|
||||
CEmptyValue();
|
||||
virtual ~CEmptyValue();
|
||||
|
||||
virtual const STR_String & GetText();
|
||||
virtual double GetNumber();
|
||||
CListValue* GetPolySoup();
|
||||
virtual double* GetVector3(bool bGetTransformedVec=false);
|
||||
bool IsInside(CValue* testpoint,bool bBorderInclude=true);
|
||||
CValue * Calc(VALUE_OPERATOR op, CValue *val);
|
||||
CValue * CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
|
||||
virtual CValue* GetReplica();
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CEmptyValue"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _EMPTYVALUE_H
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// ErrorValue.cpp: implementation of the CErrorValue class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ErrorValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CErrorValue::CErrorValue()
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CErrorValue containing errormessage "Error"
|
||||
*/
|
||||
{
|
||||
m_strErrorText = "Error";
|
||||
SetError(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CErrorValue::CErrorValue(const char *errmsg)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CErrorValue containing errormessage errmsg
|
||||
*/
|
||||
{
|
||||
m_strErrorText = "[";
|
||||
m_strErrorText += errmsg;
|
||||
m_strErrorText += "]";
|
||||
SetError(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CErrorValue::~CErrorValue()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CErrorValue::Calc(VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator op to this
|
||||
object and val
|
||||
*/
|
||||
{
|
||||
CValue* errorval;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case VALUE_POS_OPERATOR:
|
||||
case VALUE_NEG_OPERATOR:
|
||||
case VALUE_NOT_OPERATOR:
|
||||
{
|
||||
errorval = new CErrorValue (op2str(op) + GetText());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
errorval = val->CalcFinal(VALUE_ERROR_TYPE, op, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return errorval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CErrorValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre: the type of val is dtype
|
||||
ret: a new object containing the result of applying operator op to val and
|
||||
this object
|
||||
*/
|
||||
{
|
||||
return new CErrorValue (val->GetText() + op2str(op) + GetText());
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CErrorValue::GetNumber()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const STR_String & CErrorValue::GetText()
|
||||
{
|
||||
return m_strErrorText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CErrorValue::GetReplica()
|
||||
{
|
||||
// who would want a copy of an error ?
|
||||
trace ("Error: ErrorValue::GetReplica() not implemented yet");
|
||||
assertd(false);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* ErrorValue.h: interface for the CErrorValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined _ERRORVALUE_H
|
||||
#define _ERRORVALUE_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
class CErrorValue : public CPropValue
|
||||
{
|
||||
|
||||
public:
|
||||
virtual const STR_String & GetText();
|
||||
virtual double GetNumber();
|
||||
CErrorValue();
|
||||
CErrorValue(const char *errmsg);
|
||||
virtual ~CErrorValue();
|
||||
virtual CValue* Calc(VALUE_OPERATOR op, CValue* val);
|
||||
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
|
||||
virtual CValue* GetReplica();
|
||||
|
||||
private:
|
||||
STR_String m_strErrorText;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CErrorValue"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _ERRORVALUE_H
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// Expression.cpp: implementation of the CExpression class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expression.h"
|
||||
#include "ErrorValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#ifdef _DEBUG
|
||||
//int gRefCountExpr;
|
||||
#endif
|
||||
CExpression::CExpression()// : m_cached_calculate(NULL)
|
||||
{
|
||||
m_refcount = 1;
|
||||
#ifdef _DEBUG
|
||||
//gRefCountExpr++;
|
||||
#endif
|
||||
}
|
||||
|
||||
CExpression::~CExpression()
|
||||
{
|
||||
assert (m_refcount == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// destuctor for CBrokenLinkInfo
|
||||
CBrokenLinkInfo::~CBrokenLinkInfo()
|
||||
{
|
||||
if (m_pExpr && !m_bRestored)
|
||||
m_pExpr->Release();
|
||||
}
|
||||
|
||||
|
||||
void CBrokenLinkInfo::RestoreLink()
|
||||
{
|
||||
|
||||
|
||||
assertd(m_pExpr);
|
||||
|
||||
if (m_pExpr)
|
||||
{
|
||||
if (!m_bRestored){
|
||||
m_bRestored=true;
|
||||
|
||||
}
|
||||
if (*m_pmemExpr)
|
||||
{
|
||||
(*m_pmemExpr)->Release();
|
||||
}
|
||||
*m_pmemExpr = m_pExpr;
|
||||
|
||||
// m_pExpr=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CBrokenLinkInfo::BreakLink()
|
||||
{
|
||||
m_bRestored=false;
|
||||
m_pExpr->AddRef();
|
||||
}
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Expression.h: interface for the CExpression class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined _EXPRESSION_H
|
||||
#define _EXPRESSION_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
//extern int gRefCountExpr; // only for debugging purposes (detect mem.leaks)
|
||||
|
||||
|
||||
#define PLUGIN_DECLARE_SERIAL_EXPRESSION(class_name,base_class_name) \
|
||||
public: \
|
||||
virtual base_class_name * Copy() { return new class_name; } \
|
||||
virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \
|
||||
virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \
|
||||
{ \
|
||||
if (bIsStoring) \
|
||||
{ \
|
||||
unsigned char exprID = GetExpressionID(); \
|
||||
arch << exprID; \
|
||||
} \
|
||||
return true; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
class CExpression;
|
||||
|
||||
|
||||
// for undo/redo system the deletion in the expressiontree can be restored by replacing broken links 'inplace'
|
||||
class CBrokenLinkInfo
|
||||
{
|
||||
public:
|
||||
CBrokenLinkInfo(CExpression** pmemexpr,CExpression* expr)
|
||||
:m_pmemExpr(pmemexpr),
|
||||
m_pExpr(expr)
|
||||
{
|
||||
assertd(pmemexpr);
|
||||
m_bRestored=false;
|
||||
};
|
||||
|
||||
virtual ~CBrokenLinkInfo();
|
||||
void RestoreLink();
|
||||
void BreakLink();
|
||||
|
||||
|
||||
// members vars
|
||||
private:
|
||||
CExpression** m_pmemExpr;
|
||||
CExpression* m_pExpr;
|
||||
bool m_bRestored;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CBrokenLinkInfo"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CExpression
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
COPERATOR1EXPRESSIONID = 1,
|
||||
COPERATOR2EXPRESSIONID = 2,
|
||||
CCONSTEXPRESSIONID = 3,
|
||||
CIFEXPRESSIONID = 4,
|
||||
COPERATORVAREXPRESSIONID = 5,
|
||||
CIDENTIFIEREXPRESSIONID = 6
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~CExpression() = 0; //pure virtual
|
||||
public:
|
||||
virtual bool MergeExpression(CExpression* otherexpr) = 0;
|
||||
CExpression();
|
||||
|
||||
|
||||
virtual CValue* Calculate() = 0; //pure virtual
|
||||
virtual unsigned char GetExpressionID() = 0;
|
||||
//virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true) = 0; //pure virtual
|
||||
virtual bool NeedsRecalculated() = 0; // another pure one
|
||||
virtual CExpression * CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) =0; // another pure one
|
||||
virtual void ClearModified() = 0; // another pure one
|
||||
//virtual CExpression * Copy() =0;
|
||||
virtual void BroadcastOperators(VALUE_OPERATOR op) =0;
|
||||
|
||||
virtual CExpression * AddRef() { // please leave multiline, for debugger !!!
|
||||
|
||||
#ifdef _DEBUG
|
||||
//gRefCountExpr++;
|
||||
assertd(m_refcount < 255);
|
||||
#endif
|
||||
m_refcount++;
|
||||
return this;
|
||||
};
|
||||
virtual CExpression* Release(CExpression* complicatedtrick=NULL) {
|
||||
#ifdef _DEBUG
|
||||
//gRefCountExpr--;
|
||||
#endif
|
||||
if (--m_refcount < 1)
|
||||
{
|
||||
delete this;
|
||||
} //else
|
||||
// return this;
|
||||
return complicatedtrick;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
int m_refcount;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CExpression"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _EXPRESSION_H
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
// FloatValue.cpp: implementation of the CFloatValue class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FloatValue.h"
|
||||
#include "IntValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "BoolValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "VoidValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CFloatValue::CFloatValue()
|
||||
/*
|
||||
pre: false
|
||||
effect: constructs a new CFloatValue
|
||||
*/
|
||||
{
|
||||
m_pstrRep=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CFloatValue::CFloatValue(float fl)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CFloatValue containing value fl
|
||||
*/
|
||||
{
|
||||
m_float = fl;
|
||||
m_pstrRep=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CFloatValue::CFloatValue(float fl,const char *name,AllocationTYPE alloctype)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CFloatValue containing value fl
|
||||
*/
|
||||
{
|
||||
|
||||
m_float = fl;
|
||||
SetName(name);
|
||||
if (alloctype==CValue::STACKVALUE)
|
||||
{
|
||||
CValue::DisableRefCount();
|
||||
|
||||
}
|
||||
m_pstrRep=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CFloatValue::~CFloatValue()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
if (m_pstrRep)
|
||||
delete m_pstrRep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CFloatValue::Calc(VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator op to this
|
||||
object and val
|
||||
*/
|
||||
{
|
||||
//return val->CalcFloat(op, this);
|
||||
switch (op)
|
||||
{
|
||||
case VALUE_POS_OPERATOR:
|
||||
return new CFloatValue (m_float);
|
||||
break;
|
||||
case VALUE_NEG_OPERATOR:
|
||||
return new CFloatValue (-m_float);
|
||||
break;
|
||||
case VALUE_NOT_OPERATOR:
|
||||
return new CErrorValue (op2str(op) + "only allowed on booleans");
|
||||
break;
|
||||
case VALUE_AND_OPERATOR:
|
||||
case VALUE_OR_OPERATOR:
|
||||
return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
|
||||
break;
|
||||
default:
|
||||
return val->CalcFinal(VALUE_FLOAT_TYPE, op, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CFloatValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre: the type of val is dtype
|
||||
ret: a new object containing the result of applying operator op to val and
|
||||
this object
|
||||
*/
|
||||
{
|
||||
CValue *ret;
|
||||
|
||||
switch(dtype)
|
||||
{
|
||||
case VALUE_INT_TYPE:
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case VALUE_MOD_OPERATOR:
|
||||
ret = new CFloatValue(fmod(((CIntValue *) val)->GetInt(), m_float));
|
||||
break;
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float);
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
ret = new CFloatValue(((CIntValue *) val)->GetInt() - m_float);
|
||||
break;
|
||||
case VALUE_MUL_OPERATOR:
|
||||
ret = new CFloatValue(((CIntValue *) val)->GetInt() * m_float);
|
||||
break;
|
||||
case VALUE_DIV_OPERATOR:
|
||||
if (m_float == 0)
|
||||
ret = new CErrorValue("Division by zero");
|
||||
else
|
||||
ret = new CFloatValue (((CIntValue *) val)->GetInt() / m_float);
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_float);
|
||||
break;
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_float);
|
||||
break;
|
||||
case VALUE_GRE_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_float);
|
||||
break;
|
||||
case VALUE_LES_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_float);
|
||||
break;
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_float);
|
||||
break;
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float);
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("illegal operator. please send a bug report.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_EMPTY_TYPE:
|
||||
case VALUE_FLOAT_TYPE:
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case VALUE_MOD_OPERATOR:
|
||||
ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_float));
|
||||
break;
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float);
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
ret = new CFloatValue(((CFloatValue *) val)->GetFloat() - m_float);
|
||||
break;
|
||||
case VALUE_MUL_OPERATOR:
|
||||
ret = new CFloatValue(((CFloatValue *) val)->GetFloat() * m_float);
|
||||
break;
|
||||
case VALUE_DIV_OPERATOR:
|
||||
if (m_float == 0)
|
||||
ret = new CErrorValue("Division by zero");
|
||||
else
|
||||
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_float);
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_float);
|
||||
break;
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_float);
|
||||
break;
|
||||
case VALUE_GRE_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_float);
|
||||
break;
|
||||
case VALUE_LES_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_float);
|
||||
break;
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_float);
|
||||
break;
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_float);
|
||||
break;
|
||||
case VALUE_NEG_OPERATOR:
|
||||
ret = new CFloatValue (-m_float);
|
||||
break;
|
||||
case VALUE_POS_OPERATOR:
|
||||
ret = new CFloatValue (m_float);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = new CErrorValue("illegal operator. please send a bug report.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_STRING_TYPE:
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CStringValue(val->GetText() + GetText(),"");
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
case VALUE_GRE_OPERATOR:
|
||||
case VALUE_LES_OPERATOR:
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CErrorValue("[Cannot compare string with float]" + op2str(op) + GetText());
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_BOOL_TYPE:
|
||||
ret = new CErrorValue("[operator not valid on boolean and float]" + op2str(op) + GetText());
|
||||
break;
|
||||
case VALUE_ERROR_TYPE:
|
||||
ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("illegal type. contact your dealer (if any)");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CFloatValue::SetFloat(float fl)
|
||||
{
|
||||
m_float = fl;
|
||||
SetModified(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
float CFloatValue::GetFloat()
|
||||
/*
|
||||
pre:
|
||||
ret: the float stored in the object
|
||||
*/
|
||||
{
|
||||
return m_float;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CFloatValue::GetNumber()
|
||||
{
|
||||
return m_float;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CFloatValue::SetValue(CValue* newval)
|
||||
{
|
||||
m_float = (float)newval->GetNumber();
|
||||
SetModified(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const STR_String & CFloatValue::GetText()
|
||||
{
|
||||
if (!m_pstrRep)
|
||||
m_pstrRep = new STR_String();
|
||||
|
||||
m_pstrRep->Format("%f",m_float);
|
||||
return *m_pstrRep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CFloatValue::GetReplica()
|
||||
{
|
||||
CFloatValue* replica = new CFloatValue(*this);
|
||||
replica->m_pstrRep = NULL; /* should be in CFloatValue::ProcessReplica() but its not defined, no matter */
|
||||
replica->ProcessReplica();
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject* CFloatValue::ConvertValueToPython()
|
||||
{
|
||||
return PyFloat_FromDouble(m_float);
|
||||
}
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* FloatValue.h: interface for the CFloatValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#if !defined _FLOATVALUE_H
|
||||
#define _FLOATVALUE_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
class CFloatValue : public CPropValue
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL (CFloatValue,CValue)
|
||||
public:
|
||||
CFloatValue();
|
||||
CFloatValue(float fl);
|
||||
CFloatValue(float fl,const char *name,AllocationTYPE alloctype=CValue::HEAPVALUE);
|
||||
|
||||
virtual const STR_String & GetText();
|
||||
|
||||
void Configure(CValue* menuvalue);
|
||||
virtual double GetNumber();
|
||||
virtual void SetValue(CValue* newval);
|
||||
float GetFloat();
|
||||
void SetFloat(float fl);
|
||||
virtual ~CFloatValue();
|
||||
virtual CValue* GetReplica();
|
||||
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
|
||||
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
|
||||
#ifndef DISABLE_PYTHON
|
||||
virtual PyObject* ConvertValueToPython();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
float m_float;
|
||||
STR_String* m_pstrRep;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CFloatValue"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _FLOATVALUE_H
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "IdentifierExpr.h"
|
||||
|
||||
CIdentifierExpr::CIdentifierExpr(const STR_String& identifier,CValue* id_context)
|
||||
:m_identifier(identifier)
|
||||
{
|
||||
if (id_context)
|
||||
m_idContext = id_context->AddRef();
|
||||
else
|
||||
m_idContext=NULL;
|
||||
}
|
||||
|
||||
|
||||
CIdentifierExpr::~CIdentifierExpr()
|
||||
{
|
||||
if (m_idContext)
|
||||
m_idContext->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CIdentifierExpr::Calculate()
|
||||
{
|
||||
CValue* result = NULL;
|
||||
if (m_idContext)
|
||||
result = m_idContext->FindIdentifier(m_identifier);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIdentifierExpr::MergeExpression(CExpression* otherexpr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char CIdentifierExpr::GetExpressionID()
|
||||
{
|
||||
return CIDENTIFIEREXPRESSIONID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIdentifierExpr::NeedsRecalculated()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CExpression* CIdentifierExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
|
||||
{
|
||||
assertd(false); // not implemented yet
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CIdentifierExpr::ClearModified()
|
||||
{
|
||||
assertd(false); // not implemented yet
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CIdentifierExpr::BroadcastOperators(VALUE_OPERATOR op)
|
||||
{
|
||||
assertd(false); // not implemented yet
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __IDENTIFIER_EXPR
|
||||
#define __IDENTIFIER_EXPR
|
||||
|
||||
#include "Expression.h"
|
||||
|
||||
class CIdentifierExpr : public CExpression
|
||||
{
|
||||
CValue* m_idContext;
|
||||
STR_String m_identifier;
|
||||
public:
|
||||
CIdentifierExpr(const STR_String& identifier,CValue* id_context);
|
||||
virtual ~CIdentifierExpr();
|
||||
|
||||
virtual CValue* Calculate();
|
||||
virtual bool MergeExpression(CExpression* otherexpr);
|
||||
virtual unsigned char GetExpressionID();
|
||||
virtual bool NeedsRecalculated();
|
||||
virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
|
||||
virtual void ClearModified();
|
||||
virtual void BroadcastOperators(VALUE_OPERATOR op);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CIdentifierExpr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__IDENTIFIER_EXPR
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
// IfExpr.cpp: implementation of the CIfExpr class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "IfExpr.h"
|
||||
#include "EmptyValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "BoolValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
CIfExpr::CIfExpr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
CIfExpr::CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs an CifExpr-object corresponding to IF(guard, e1, e2)
|
||||
*/
|
||||
{
|
||||
m_guard = guard;
|
||||
m_e1 = e1;
|
||||
m_e2 = e2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CIfExpr::~CIfExpr()
|
||||
/*
|
||||
pre:
|
||||
effect: dereferences the object
|
||||
*/
|
||||
{
|
||||
if (m_guard)
|
||||
m_guard->Release();
|
||||
|
||||
if (m_e1)
|
||||
m_e1->Release();
|
||||
|
||||
if (m_e2)
|
||||
m_e2->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CIfExpr::Calculate()
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE
|
||||
a new object containing the value of m_e2 if m_guard is a boolean FALSE
|
||||
an new errorvalue if m_guard is not a boolean
|
||||
*/
|
||||
{
|
||||
CValue *guardval;
|
||||
guardval = m_guard->Calculate();
|
||||
const STR_String& text = guardval->GetText();
|
||||
guardval->Release();
|
||||
|
||||
if (&text == &CBoolValue::sTrueString)
|
||||
{
|
||||
return m_e1->Calculate();
|
||||
}
|
||||
else if (&text == &CBoolValue::sFalseString)
|
||||
{
|
||||
return m_e2->Calculate();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CErrorValue("Guard should be of boolean type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIfExpr::MergeExpression(CExpression *otherexpr)
|
||||
{
|
||||
assertd(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIfExpr::IsInside(float x,float y,float z,bool bBorderInclude)
|
||||
{
|
||||
assertd(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIfExpr::NeedsRecalculated()
|
||||
{
|
||||
return (m_guard->NeedsRecalculated() ||
|
||||
m_e1->NeedsRecalculated() ||
|
||||
m_e2->NeedsRecalculated());
|
||||
}
|
||||
|
||||
|
||||
|
||||
CExpression* CIfExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
|
||||
{
|
||||
assertd(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CIfExpr::ClearModified()
|
||||
{
|
||||
assertd(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CIfExpr::BroadcastOperators(VALUE_OPERATOR op)
|
||||
{
|
||||
assertd(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char CIfExpr::GetExpressionID()
|
||||
{
|
||||
return CIFEXPRESSIONID;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* IfExpr.h: interface for the CIfExpr class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
|
||||
#define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#include "Expression.h"
|
||||
|
||||
class CIfExpr : public CExpression
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL_EXPRESSION (CIfExpr,CExpression)
|
||||
|
||||
private:
|
||||
CExpression *m_guard, *m_e1, *m_e2;
|
||||
|
||||
public:
|
||||
virtual bool MergeExpression(CExpression* otherexpr);
|
||||
CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2);
|
||||
CIfExpr();
|
||||
|
||||
virtual unsigned char GetExpressionID();
|
||||
virtual ~CIfExpr();
|
||||
virtual CValue* Calculate();
|
||||
|
||||
virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
|
||||
virtual bool NeedsRecalculated();
|
||||
|
||||
|
||||
virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
|
||||
virtual void ClearModified();
|
||||
virtual void BroadcastOperators(VALUE_OPERATOR op);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CIfExpr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
|
||||
|
||||
@@ -1,634 +0,0 @@
|
||||
// Parser.cpp: implementation of the CParser class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MT_assert.h"
|
||||
|
||||
#include "Value.h"
|
||||
#include "InputParser.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "IntValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "FloatValue.h"
|
||||
#include "BoolValue.h"
|
||||
#include "EmptyValue.h"
|
||||
#include "ConstExpr.h"
|
||||
#include "Operator2Expr.h"
|
||||
#include "Operator1Expr.h"
|
||||
#include "IdentifierExpr.h"
|
||||
|
||||
// this is disable at the moment, I expected a memleak from it, but the error-cleanup was the reason
|
||||
// well, looks we don't need it anyway, until maybe the Curved Surfaces are integrated into CSG
|
||||
// cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc...
|
||||
#include "IfExpr.h"
|
||||
|
||||
#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
|
||||
#define strcasecmp _stricmp
|
||||
|
||||
#ifndef strtoll
|
||||
#define strtoll _strtoi64
|
||||
#endif
|
||||
|
||||
#endif /* Def WIN32 or Def WIN64 */
|
||||
|
||||
#define NUM_PRIORITY 6
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CParser::CParser() : m_identifierContext(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
CParser::~CParser()
|
||||
{
|
||||
if (m_identifierContext)
|
||||
m_identifierContext->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::ScanError(const char *str)
|
||||
{
|
||||
// sets the global variable errmsg to an errormessage with
|
||||
// contents str, appending if it already exists
|
||||
// AfxMessageBox("Parse Error:"+str,MB_ICONERROR);
|
||||
if (errmsg)
|
||||
errmsg = new COperator2Expr(VALUE_ADD_OPERATOR, errmsg, Error(str));
|
||||
else
|
||||
errmsg = Error(str);
|
||||
|
||||
sym = errorsym;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CExpression* CParser::Error(const char *str)
|
||||
{
|
||||
// makes and returns a new CConstExpr filled with an CErrorValue
|
||||
// with string str
|
||||
// AfxMessageBox("Error:"+str,MB_ICONERROR);
|
||||
return new CConstExpr(new CErrorValue(str));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::NextCh()
|
||||
{
|
||||
// sets the global variable ch to the next character, if it exists
|
||||
// and increases the global variable chcount
|
||||
chcount++;
|
||||
|
||||
if (chcount < text.Length())
|
||||
ch = text[chcount];
|
||||
else
|
||||
ch = 0x00;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::TermChar(char c)
|
||||
{
|
||||
// generates an error if the next char isn't the specified char c,
|
||||
// otherwise, skip the char
|
||||
if(ch == c)
|
||||
{
|
||||
NextCh();
|
||||
}
|
||||
else
|
||||
{
|
||||
STR_String str;
|
||||
str.Format("Warning: %c expected\ncontinuing without it", c);
|
||||
trace(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::DigRep()
|
||||
{
|
||||
// changes the current character to the first character that
|
||||
// isn't a decimal
|
||||
while ((ch >= '0') && (ch <= '9'))
|
||||
NextCh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::CharRep()
|
||||
{
|
||||
// changes the current character to the first character that
|
||||
// isn't an alphanumeric character
|
||||
while (((ch >= '0') && (ch <= '9'))
|
||||
|| ((ch >= 'a') && (ch <= 'z'))
|
||||
|| ((ch >= 'A') && (ch <= 'Z'))
|
||||
|| (ch == '.') || (ch == '_'))
|
||||
NextCh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::GrabString(int start)
|
||||
{
|
||||
// puts part of the input string into the global variable
|
||||
// const_as_string, from position start, to position chchount
|
||||
const_as_string = text.Mid(start, chcount-start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CParser::NextSym()
|
||||
{
|
||||
// sets the global variable sym to the next symbol, and
|
||||
// if it is an operator
|
||||
// sets the global variable opkind to the kind of operator
|
||||
// if it is a constant
|
||||
// sets the global variable constkind to the kind of operator
|
||||
// if it is a reference to a cell
|
||||
// sets the global variable cellcoord to the kind of operator
|
||||
|
||||
errmsg = NULL;
|
||||
while(ch == ' ' || ch == 0x9)
|
||||
NextCh();
|
||||
|
||||
switch(ch)
|
||||
{
|
||||
case '(':
|
||||
sym = lbracksym; NextCh();
|
||||
break;
|
||||
case ')':
|
||||
sym = rbracksym; NextCh();
|
||||
break;
|
||||
case ',':
|
||||
sym = commasym; NextCh();
|
||||
break;
|
||||
case '%' :
|
||||
sym = opsym; opkind = OPmodulus; NextCh();
|
||||
break;
|
||||
case '+' :
|
||||
sym = opsym; opkind = OPplus; NextCh();
|
||||
break;
|
||||
case '-' :
|
||||
sym = opsym; opkind = OPminus; NextCh();
|
||||
break;
|
||||
case '*' :
|
||||
sym = opsym; opkind = OPtimes; NextCh();
|
||||
break;
|
||||
case '/' :
|
||||
sym = opsym; opkind = OPdivide; NextCh();
|
||||
break;
|
||||
case '&' :
|
||||
sym = opsym; opkind = OPand; NextCh(); TermChar('&');
|
||||
break;
|
||||
case '|' :
|
||||
sym = opsym; opkind = OPor; NextCh(); TermChar('|');
|
||||
break;
|
||||
case '=' :
|
||||
sym = opsym; opkind = OPequal; NextCh(); TermChar('=');
|
||||
break;
|
||||
case '!' :
|
||||
sym = opsym;
|
||||
NextCh();
|
||||
if (ch == '=')
|
||||
{
|
||||
opkind = OPunequal;
|
||||
NextCh();
|
||||
}
|
||||
else
|
||||
{
|
||||
opkind = OPnot;
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
sym = opsym;
|
||||
NextCh();
|
||||
if (ch == '=')
|
||||
{
|
||||
opkind = OPgreaterequal;
|
||||
NextCh();
|
||||
}
|
||||
else
|
||||
{
|
||||
opkind = OPgreater;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
sym = opsym;
|
||||
NextCh();
|
||||
if (ch == '=') {
|
||||
opkind = OPlessequal;
|
||||
NextCh();
|
||||
} else {
|
||||
opkind = OPless;
|
||||
}
|
||||
break;
|
||||
case '\"' : {
|
||||
int start;
|
||||
sym = constsym;
|
||||
constkind = stringtype;
|
||||
NextCh();
|
||||
start = chcount;
|
||||
while ((ch != '\"') && (ch != 0x0))
|
||||
NextCh();
|
||||
GrabString(start);
|
||||
TermChar('\"'); // check for eol before '\"'
|
||||
break;
|
||||
}
|
||||
case 0x0: sym = eolsym; break;
|
||||
default:
|
||||
{
|
||||
int start;
|
||||
start = chcount;
|
||||
DigRep();
|
||||
if ((start != chcount) || (ch == '.')) { // number
|
||||
sym = constsym;
|
||||
if (ch == '.') {
|
||||
constkind = floattype;
|
||||
NextCh();
|
||||
DigRep();
|
||||
}
|
||||
else constkind = inttype;
|
||||
if ((ch == 'e') || (ch == 'E')) {
|
||||
int mark;
|
||||
constkind = floattype;
|
||||
NextCh();
|
||||
if ((ch == '+') || (ch == '-')) NextCh();
|
||||
mark = chcount;
|
||||
DigRep();
|
||||
if (mark == chcount) {
|
||||
ScanError("Number expected after 'E'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
GrabString(start);
|
||||
} else if (((ch >= 'a') && (ch <= 'z'))
|
||||
|| ((ch >= 'A') && (ch <= 'Z')))
|
||||
{ // reserved word?
|
||||
|
||||
start = chcount;
|
||||
CharRep();
|
||||
GrabString(start);
|
||||
if (!strcasecmp(const_as_string, "SUM")) {
|
||||
sym = sumsym;
|
||||
}
|
||||
else if (!strcasecmp(const_as_string, "NOT")) {
|
||||
sym = opsym;
|
||||
opkind = OPnot;
|
||||
}
|
||||
else if (!strcasecmp(const_as_string, "AND")) {
|
||||
sym = opsym; opkind = OPand;
|
||||
}
|
||||
else if (!strcasecmp(const_as_string, "OR")) {
|
||||
sym = opsym; opkind = OPor;
|
||||
}
|
||||
else if (!strcasecmp(const_as_string, "IF"))
|
||||
sym = ifsym;
|
||||
else if (!strcasecmp(const_as_string, "WHOMADE"))
|
||||
sym = whocodedsym;
|
||||
else if (!strcasecmp(const_as_string, "FALSE")) {
|
||||
sym = constsym; constkind = booltype; boolvalue = false;
|
||||
} else if (!strcasecmp(const_as_string, "TRUE")) {
|
||||
sym = constsym; constkind = booltype; boolvalue = true;
|
||||
} else {
|
||||
sym = idsym;
|
||||
//STR_String str;
|
||||
//str.Format("'%s' makes no sense here", (const char*)funstr);
|
||||
//ScanError(str);
|
||||
}
|
||||
} else { // unknown symbol
|
||||
STR_String str;
|
||||
str.Format("Unexpected character '%c'", ch);
|
||||
NextCh();
|
||||
ScanError(str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
int CParser::MakeInt() {
|
||||
// returns the integer representation of the value in the global
|
||||
// variable const_as_string
|
||||
// pre: const_as_string contains only numercal chars
|
||||
return atoi(const_as_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
STR_String CParser::Symbol2Str(int s) {
|
||||
// returns a string representation of of symbol s,
|
||||
// for use in Term when generating an error
|
||||
switch(s) {
|
||||
case errorsym: return "error";
|
||||
case lbracksym: return "(";
|
||||
case rbracksym: return ")";
|
||||
case commasym: return ",";
|
||||
case opsym: return "operator";
|
||||
case constsym: return "constant";
|
||||
case sumsym: return "SUM";
|
||||
case ifsym: return "IF";
|
||||
case whocodedsym: return "WHOMADE";
|
||||
case eolsym: return "end of line";
|
||||
case idsym: return "identifier";
|
||||
default: return "unknown"; // should not happen
|
||||
}
|
||||
}
|
||||
|
||||
void CParser::Term(int s) {
|
||||
// generates an error if the next symbol isn't the specified symbol s
|
||||
// otherwise, skip the symbol
|
||||
if(s == sym) NextSym();
|
||||
else {
|
||||
STR_String msg;
|
||||
msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");
|
||||
|
||||
// AfxMessageBox(msg,MB_ICONERROR);
|
||||
|
||||
trace(msg);
|
||||
}
|
||||
}
|
||||
|
||||
int CParser::Priority(int optorkind) {
|
||||
// returns the priority of an operator
|
||||
// higher number means higher priority
|
||||
switch(optorkind) {
|
||||
case OPor: return 1;
|
||||
case OPand: return 2;
|
||||
case OPgreater:
|
||||
case OPless:
|
||||
case OPgreaterequal:
|
||||
case OPlessequal:
|
||||
case OPequal:
|
||||
case OPunequal: return 3;
|
||||
case OPplus:
|
||||
case OPminus: return 4;
|
||||
case OPmodulus:
|
||||
case OPtimes:
|
||||
case OPdivide: return 5;
|
||||
}
|
||||
MT_assert(false);
|
||||
return 0; // should not happen
|
||||
}
|
||||
|
||||
CExpression *CParser::Ex(int i) {
|
||||
// parses an expression in the imput, starting at priority i, and
|
||||
// returns an CExpression, containing the parsed input
|
||||
CExpression *e1 = NULL, *e2 = NULL;
|
||||
int opkind2;
|
||||
|
||||
if (i < NUM_PRIORITY) {
|
||||
e1 = Ex(i + 1);
|
||||
while ((sym == opsym) && (Priority(opkind) == i)) {
|
||||
opkind2 = opkind;
|
||||
NextSym();
|
||||
e2 = Ex(i + 1);
|
||||
switch(opkind2) {
|
||||
case OPmodulus: e1 = new COperator2Expr(VALUE_MOD_OPERATOR,e1, e2); break;
|
||||
case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break;
|
||||
case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break;
|
||||
case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break;
|
||||
case OPdivide: e1 = new COperator2Expr(VALUE_DIV_OPERATOR,e1, e2); break;
|
||||
case OPand: e1 = new COperator2Expr(VALUE_AND_OPERATOR,e1, e2); break;
|
||||
case OPor: e1 = new COperator2Expr(VALUE_OR_OPERATOR,e1, e2); break;
|
||||
case OPequal: e1 = new COperator2Expr(VALUE_EQL_OPERATOR,e1, e2); break;
|
||||
case OPunequal: e1 = new COperator2Expr(VALUE_NEQ_OPERATOR,e1, e2); break;
|
||||
case OPgreater: e1 = new COperator2Expr(VALUE_GRE_OPERATOR,e1, e2); break;
|
||||
case OPless: e1 = new COperator2Expr(VALUE_LES_OPERATOR,e1, e2); break;
|
||||
case OPgreaterequal: e1 = new COperator2Expr(VALUE_GEQ_OPERATOR,e1, e2); break;
|
||||
case OPlessequal: e1 = new COperator2Expr(VALUE_LEQ_OPERATOR,e1, e2); break;
|
||||
default: MT_assert(false); break; // should not happen
|
||||
}
|
||||
}
|
||||
} else if (i == NUM_PRIORITY) {
|
||||
if ((sym == opsym)
|
||||
&& ( (opkind == OPminus) || (opkind == OPnot) || (opkind == OPplus) )
|
||||
)
|
||||
{
|
||||
NextSym();
|
||||
switch(opkind) {
|
||||
/* +1 is also a valid number! */
|
||||
case OPplus: e1 = new COperator1Expr(VALUE_POS_OPERATOR, Ex(NUM_PRIORITY)); break;
|
||||
case OPminus: e1 = new COperator1Expr(VALUE_NEG_OPERATOR, Ex(NUM_PRIORITY)); break;
|
||||
case OPnot: e1 = new COperator1Expr(VALUE_NOT_OPERATOR, Ex(NUM_PRIORITY)); break;
|
||||
default: {
|
||||
// should not happen
|
||||
e1 = Error("operator +, - or ! expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(sym) {
|
||||
case constsym: {
|
||||
switch(constkind) {
|
||||
case booltype:
|
||||
e1 = new CConstExpr(new CBoolValue(boolvalue));
|
||||
break;
|
||||
case inttype:
|
||||
{
|
||||
cInt temp;
|
||||
temp = strtoll(const_as_string, NULL, 10); /* atoi is for int only */
|
||||
e1 = new CConstExpr(new CIntValue(temp));
|
||||
break;
|
||||
}
|
||||
case floattype:
|
||||
{
|
||||
double temp;
|
||||
temp = atof(const_as_string);
|
||||
e1 = new CConstExpr(new CFloatValue(temp));
|
||||
break;
|
||||
}
|
||||
case stringtype:
|
||||
e1 = new CConstExpr(new CStringValue(const_as_string,""));
|
||||
break;
|
||||
default :
|
||||
MT_assert(false);
|
||||
break;
|
||||
}
|
||||
NextSym();
|
||||
break;
|
||||
}
|
||||
case lbracksym:
|
||||
NextSym();
|
||||
e1 = Ex(1);
|
||||
Term(rbracksym);
|
||||
break;
|
||||
case ifsym:
|
||||
{
|
||||
CExpression *e3;
|
||||
NextSym();
|
||||
Term(lbracksym);
|
||||
e1 = Ex(1);
|
||||
Term(commasym);
|
||||
e2 = Ex(1);
|
||||
if (sym == commasym) {
|
||||
NextSym();
|
||||
e3 = Ex(1);
|
||||
} else {
|
||||
e3 = new CConstExpr(new CEmptyValue());
|
||||
}
|
||||
Term(rbracksym);
|
||||
e1 = new CIfExpr(e1, e2, e3);
|
||||
break;
|
||||
}
|
||||
case idsym:
|
||||
{
|
||||
e1 = new CIdentifierExpr(const_as_string,m_identifierContext);
|
||||
NextSym();
|
||||
|
||||
break;
|
||||
}
|
||||
case errorsym:
|
||||
{
|
||||
MT_assert(!e1);
|
||||
STR_String errtext="[no info]";
|
||||
if (errmsg)
|
||||
{
|
||||
CValue* errmsgval = errmsg->Calculate();
|
||||
errtext=errmsgval->GetText();
|
||||
errmsgval->Release();
|
||||
|
||||
//e1 = Error(errmsg->Calculate()->GetText());//new CConstExpr(errmsg->Calculate());
|
||||
|
||||
if ( !(errmsg->Release()) )
|
||||
{
|
||||
errmsg=NULL;
|
||||
} else {
|
||||
// does this happen ?
|
||||
MT_assert ("does this happen");
|
||||
}
|
||||
}
|
||||
e1 = Error(errtext);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NextSym();
|
||||
//return Error("Expression expected");
|
||||
MT_assert(!e1);
|
||||
e1 = Error("Expression expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
return e1;
|
||||
}
|
||||
|
||||
CExpression *CParser::Expr() {
|
||||
// parses an expression in the imput, and
|
||||
// returns an CExpression, containing the parsed input
|
||||
return Ex(1);
|
||||
}
|
||||
|
||||
CExpression* CParser::ProcessText
|
||||
(const char *intext) {
|
||||
|
||||
// and parses the string in intext and returns it.
|
||||
|
||||
|
||||
CExpression* expr;
|
||||
text = intext;
|
||||
|
||||
|
||||
chcount = 0;
|
||||
if (text.Length() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch = text[0];
|
||||
/*if (ch != '=') {
|
||||
expr = new CConstExpr(new CStringValue(text));
|
||||
*dependant = deplist;
|
||||
return expr;
|
||||
} else
|
||||
*/
|
||||
// NextCh();
|
||||
NextSym();
|
||||
expr = Expr();
|
||||
if (sym != eolsym) {
|
||||
CExpression* oldexpr = expr;
|
||||
expr = new COperator2Expr(VALUE_ADD_OPERATOR,
|
||||
oldexpr, Error(STR_String("Extra characters after expression")));//new CConstExpr(new CErrorValue("Extra characters after expression")));
|
||||
}
|
||||
if (errmsg)
|
||||
errmsg->Release();
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float CParser::GetFloat(STR_String& txt)
|
||||
{
|
||||
// returns parsed text into a float
|
||||
// empty string returns -1
|
||||
|
||||
// AfxMessageBox("parsed string="+txt);
|
||||
CValue* val=NULL;
|
||||
float result=-1;
|
||||
// String tmpstr;
|
||||
|
||||
CExpression* expr = ProcessText(txt);
|
||||
if (expr) {
|
||||
val = expr->Calculate();
|
||||
result=(float)val->GetNumber();
|
||||
|
||||
|
||||
|
||||
val->Release();
|
||||
expr->Release();
|
||||
}
|
||||
// tmpstr.Format("parseresult=%g",result);
|
||||
// AfxMessageBox(tmpstr);
|
||||
return result;
|
||||
}
|
||||
|
||||
CValue* CParser::GetValue(STR_String& txt, bool bFallbackToText)
|
||||
{
|
||||
// returns parsed text into a value,
|
||||
// empty string returns NULL value !
|
||||
// if bFallbackToText then unparsed stuff is put into text
|
||||
|
||||
CValue* result=NULL;
|
||||
CExpression* expr = ProcessText(txt);
|
||||
if (expr) {
|
||||
result = expr->Calculate();
|
||||
expr->Release();
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
// if the parsed stuff lead to an errorvalue, don't return errors, just NULL
|
||||
if (result->IsError()) {
|
||||
result->Release();
|
||||
result=NULL;
|
||||
if (bFallbackToText) {
|
||||
if (txt.Length()>0)
|
||||
{
|
||||
result = new CStringValue(txt,"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CParser::SetContext(CValue* context)
|
||||
{
|
||||
if (m_identifierContext)
|
||||
{
|
||||
m_identifierContext->Release();
|
||||
}
|
||||
m_identifierContext = context;
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Parser.h: interface for the CParser class.
|
||||
* Eindhoven University of Technology 1997
|
||||
* OOPS team (Serge vd Boom, Erwin Coumans, Tom Geelen, Wynke Stuylemeier)
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#ifndef __INPUTPARSER_H__
|
||||
#define __INPUTPARSER_H__
|
||||
|
||||
class CParser;
|
||||
#include "Expression.h"
|
||||
|
||||
|
||||
class CParser
|
||||
{
|
||||
public:
|
||||
CParser();
|
||||
virtual ~CParser();
|
||||
|
||||
float GetFloat(STR_String& txt);
|
||||
CValue* GetValue(STR_String& txt, bool bFallbackToText=false);
|
||||
CExpression* ProcessText(const char *intext);
|
||||
void SetContext(CValue* context);
|
||||
|
||||
private:
|
||||
enum symbols {
|
||||
errorsym,
|
||||
lbracksym,
|
||||
rbracksym,
|
||||
cellsym,
|
||||
commasym,
|
||||
opsym,
|
||||
constsym,
|
||||
sumsym,
|
||||
ifsym,
|
||||
whocodedsym,
|
||||
eolsym,
|
||||
idsym
|
||||
}; // all kinds of symbols
|
||||
|
||||
enum optype {
|
||||
OPmodulus,
|
||||
OPplus,
|
||||
OPminus,
|
||||
OPtimes,
|
||||
OPdivide,
|
||||
OPand,
|
||||
OPor,
|
||||
OPequal,
|
||||
OPunequal,
|
||||
OPgreater,
|
||||
OPless,
|
||||
OPgreaterequal,
|
||||
OPlessequal,
|
||||
OPnot
|
||||
}; // all kinds of operators
|
||||
|
||||
enum consttype {
|
||||
booltype,
|
||||
inttype,
|
||||
floattype,
|
||||
stringtype
|
||||
}; // all kinds of constants
|
||||
|
||||
int sym, // current symbol
|
||||
opkind, // kind of operator, if symbol is an operator
|
||||
constkind; // kind of operator, if symbol is a constant
|
||||
|
||||
char ch; // current character
|
||||
int chcount; // index to character in input string
|
||||
CExpression *errmsg; // contains a errormessage, if scanner error
|
||||
|
||||
STR_String text, // contains a copy of the original text
|
||||
const_as_string; // string representation of the symbol, if symbol is a constant
|
||||
bool boolvalue; // value of the boolean, if symbol is a constant of type boolean
|
||||
CValue* m_identifierContext;// context in which identifiers are looked up
|
||||
|
||||
|
||||
void ScanError(const char *str);
|
||||
CExpression* Error(const char *str);
|
||||
void NextCh();
|
||||
void TermChar(char c);
|
||||
void DigRep();
|
||||
void CharRep();
|
||||
void GrabString(int start);
|
||||
void NextSym();
|
||||
#if 0 /* not used yet */
|
||||
int MakeInt();
|
||||
#endif
|
||||
STR_String Symbol2Str(int s);
|
||||
void Term(int s);
|
||||
int Priority(int optor);
|
||||
CExpression *Ex(int i);
|
||||
CExpression *Expr();
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CParser"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,333 +0,0 @@
|
||||
// IntValue.cpp: implementation of the CIntValue class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "IntValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "FloatValue.h"
|
||||
#include "BoolValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "VoidValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CIntValue::CIntValue()
|
||||
/*
|
||||
pre: false
|
||||
effect: constructs a new CIntValue
|
||||
*/
|
||||
{
|
||||
|
||||
#ifdef _DEBUG_
|
||||
m_textval = "Int illegal constructor";
|
||||
#endif
|
||||
m_pstrRep=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CIntValue::CIntValue(cInt innie)
|
||||
/*
|
||||
pre:
|
||||
effect: constructs a new CIntValue containing cInt innie
|
||||
*/
|
||||
{
|
||||
m_int = innie;
|
||||
m_pstrRep=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CIntValue::CIntValue(cInt innie,const char *name,AllocationTYPE alloctype)
|
||||
{
|
||||
m_int = innie;
|
||||
SetName(name);
|
||||
|
||||
if (alloctype==CValue::STACKVALUE)
|
||||
{
|
||||
CValue::DisableRefCount();
|
||||
}
|
||||
m_pstrRep=NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CIntValue::~CIntValue()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
if (m_pstrRep)
|
||||
delete m_pstrRep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CIntValue::Calc(VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator op to this
|
||||
object and val
|
||||
*/
|
||||
{
|
||||
//return val->CalcInt(op, this);
|
||||
switch (op) {
|
||||
case VALUE_POS_OPERATOR:
|
||||
return new CIntValue (m_int);
|
||||
break;
|
||||
case VALUE_NEG_OPERATOR:
|
||||
return new CIntValue (-m_int);
|
||||
break;
|
||||
case VALUE_NOT_OPERATOR:
|
||||
return new CErrorValue (op2str(op) + "only allowed on booleans");
|
||||
break;
|
||||
case VALUE_AND_OPERATOR:
|
||||
case VALUE_OR_OPERATOR:
|
||||
return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
|
||||
break;
|
||||
default:
|
||||
return val->CalcFinal(VALUE_INT_TYPE, op, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
|
||||
/*
|
||||
pre: the type of val is dtype
|
||||
ret: a new object containing the result of applying operator op to val and
|
||||
this object
|
||||
*/
|
||||
{
|
||||
CValue *ret;
|
||||
|
||||
switch(dtype) {
|
||||
case VALUE_EMPTY_TYPE:
|
||||
case VALUE_INT_TYPE:
|
||||
{
|
||||
switch (op) {
|
||||
case VALUE_MOD_OPERATOR:
|
||||
ret = new CIntValue (((CIntValue *) val)->GetInt() % m_int);
|
||||
break;
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int);
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
ret = new CIntValue (((CIntValue *) val)->GetInt() - m_int);
|
||||
break;
|
||||
case VALUE_MUL_OPERATOR:
|
||||
ret = new CIntValue (((CIntValue *) val)->GetInt() * m_int);
|
||||
break;
|
||||
case VALUE_DIV_OPERATOR:
|
||||
if (m_int == 0)
|
||||
{
|
||||
if (val->GetNumber() == 0)
|
||||
{
|
||||
ret = new CErrorValue("Not a Number");
|
||||
} else
|
||||
{
|
||||
ret = new CErrorValue("Division by zero");
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = new CIntValue (((CIntValue *) val)->GetInt() / m_int);
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_int);
|
||||
break;
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_int);
|
||||
break;
|
||||
case VALUE_GRE_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_int);
|
||||
break;
|
||||
case VALUE_LES_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_int);
|
||||
break;
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_int);
|
||||
break;
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_int);
|
||||
break;
|
||||
case VALUE_NEG_OPERATOR:
|
||||
ret = new CIntValue (-m_int);
|
||||
break;
|
||||
case VALUE_POS_OPERATOR:
|
||||
ret = new CIntValue (m_int);
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("illegal operator. please send a bug report.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_FLOAT_TYPE:
|
||||
{
|
||||
switch (op) {
|
||||
case VALUE_MOD_OPERATOR:
|
||||
ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_int));
|
||||
break;
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int);
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() - m_int);
|
||||
break;
|
||||
case VALUE_MUL_OPERATOR:
|
||||
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() * m_int);
|
||||
break;
|
||||
case VALUE_DIV_OPERATOR:
|
||||
if (m_int == 0)
|
||||
ret = new CErrorValue("Division by zero");
|
||||
else
|
||||
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_int);
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_int);
|
||||
break;
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_int);
|
||||
break;
|
||||
case VALUE_GRE_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_int);
|
||||
break;
|
||||
case VALUE_LES_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_int);
|
||||
break;
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_int);
|
||||
break;
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int);
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("illegal operator. please send a bug report.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_STRING_TYPE:
|
||||
{
|
||||
switch(op) {
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CStringValue(val->GetText() + GetText(),"");
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
case VALUE_GRE_OPERATOR:
|
||||
case VALUE_LES_OPERATOR:
|
||||
case VALUE_GEQ_OPERATOR:
|
||||
case VALUE_LEQ_OPERATOR:
|
||||
ret = new CErrorValue("[Cannot compare string with integer]" + op2str(op) + GetText());
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_BOOL_TYPE:
|
||||
ret = new CErrorValue("[operator not valid on boolean and integer]" + op2str(op) + GetText());
|
||||
break;
|
||||
/*
|
||||
case VALUE_EMPTY_TYPE:
|
||||
{
|
||||
switch(op) {
|
||||
|
||||
case VALUE_ADD_OPERATOR:
|
||||
ret = new CIntValue (m_int);
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
ret = new CIntValue (-m_int);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ret = new CErrorValue(op2str(op) + GetText());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case VALUE_ERROR_TYPE:
|
||||
ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
|
||||
break;
|
||||
default:
|
||||
ret = new CErrorValue("illegal type. contact your dealer (if any)");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
cInt CIntValue::GetInt()
|
||||
/*
|
||||
pre:
|
||||
ret: the cInt stored in the object
|
||||
*/
|
||||
{
|
||||
return m_int;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CIntValue::GetNumber()
|
||||
{
|
||||
return (float) m_int;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const STR_String & CIntValue::GetText()
|
||||
{
|
||||
if (!m_pstrRep)
|
||||
m_pstrRep=new STR_String();
|
||||
m_pstrRep->Format("%lld",m_int);
|
||||
|
||||
return *m_pstrRep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CIntValue::GetReplica() {
|
||||
CIntValue* replica = new CIntValue(*this);
|
||||
replica->ProcessReplica();
|
||||
replica->m_pstrRep = NULL;
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CIntValue::SetValue(CValue* newval)
|
||||
{
|
||||
m_int = (cInt)newval->GetNumber();
|
||||
SetModified(true);
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject* CIntValue::ConvertValueToPython()
|
||||
{
|
||||
if((m_int > INT_MIN) && (m_int < INT_MAX))
|
||||
return PyLong_FromSsize_t(m_int);
|
||||
else
|
||||
return PyLong_FromLongLong(m_int);
|
||||
}
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* IntValue.h: interface for the CIntValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#if !defined _INTVALUE_H
|
||||
#define _INTVALUE_H
|
||||
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
typedef long long cInt;
|
||||
|
||||
class CIntValue : public CPropValue
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL (CIntValue,CValue)
|
||||
|
||||
public:
|
||||
virtual const STR_String& GetText();
|
||||
virtual double GetNumber();
|
||||
|
||||
cInt GetInt();
|
||||
CIntValue();
|
||||
CIntValue(cInt innie);
|
||||
CIntValue(cInt innie,
|
||||
const char *name,
|
||||
AllocationTYPE alloctype=CValue::HEAPVALUE);
|
||||
|
||||
virtual CValue* Calc(VALUE_OPERATOR op,
|
||||
CValue *val);
|
||||
|
||||
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
|
||||
VALUE_OPERATOR op,
|
||||
CValue *val);
|
||||
|
||||
virtual void SetValue(CValue* newval);
|
||||
|
||||
void Configure(CValue* menuvalue);
|
||||
void AddConfigurationData(CValue* menuvalue);
|
||||
virtual CValue* GetReplica();
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
virtual PyObject* ConvertValueToPython();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~CIntValue();
|
||||
|
||||
private:
|
||||
cInt m_int;
|
||||
STR_String* m_pstrRep;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CIntValue"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _INTVALUE_H
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_HashedPtr.h"
|
||||
|
||||
unsigned int KX_Hash(void * inDWord)
|
||||
{
|
||||
#if defined(_WIN64)
|
||||
unsigned __int64 key = (unsigned __int64)inDWord;
|
||||
#else
|
||||
unsigned long key = (unsigned long)inDWord;
|
||||
#endif
|
||||
|
||||
key += ~(key << 16);
|
||||
key ^= (key >> 5);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 13);
|
||||
key += ~(key << 9);
|
||||
key ^= (key >> 17);
|
||||
|
||||
return (unsigned int)(key & 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
CHashedPtr::CHashedPtr(void* val) : m_valptr(val)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int CHashedPtr::hash() const
|
||||
{
|
||||
return KX_Hash(m_valptr);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __KX_HASHEDPTR
|
||||
#define __KX_HASHEDPTR
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
unsigned int KX_Hash(void * inDWord);
|
||||
|
||||
class CHashedPtr
|
||||
{
|
||||
void* m_valptr;
|
||||
|
||||
public:
|
||||
CHashedPtr(void* val);
|
||||
|
||||
unsigned int hash() const;
|
||||
|
||||
inline friend bool operator ==( const CHashedPtr & rhs,const CHashedPtr & lhs)
|
||||
{
|
||||
return rhs.m_valptr == lhs.m_valptr;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:CHashedPtr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_HASHEDPTR
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef KX_PYTHON_H
|
||||
#define KX_PYTHON_H
|
||||
|
||||
//#define USE_DL_EXPORT
|
||||
|
||||
/* python redefines, quiet the compiler */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
#undef _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
#include "Python.h"
|
||||
|
||||
#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <osreldate.h>
|
||||
#if __FreeBSD_version > 500039
|
||||
#undef isalnum
|
||||
#undef isalpha
|
||||
#undef iscntrl
|
||||
#undef isdigit
|
||||
#undef isgraph
|
||||
#undef islower
|
||||
#undef isprint
|
||||
#undef ispunct
|
||||
#undef isspace
|
||||
#undef isupper
|
||||
#undef isxdigit
|
||||
#undef tolower
|
||||
#undef toupper
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // KX_PYTHON_H
|
||||
|
||||
@@ -1,677 +0,0 @@
|
||||
// ListValue.cpp: implementation of the CListValue class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ListValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "VoidValue.h"
|
||||
#include <algorithm>
|
||||
#include "BoolValue.h"
|
||||
|
||||
#include "BLO_sys_types.h" /* for intptr_t support */
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CListValue::CListValue()
|
||||
: CPropValue()
|
||||
{
|
||||
m_bReleaseContents=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CListValue::~CListValue()
|
||||
{
|
||||
|
||||
if (m_bReleaseContents) {
|
||||
for (unsigned int i=0;i<m_pValueArray.size();i++) {
|
||||
m_pValueArray[i]->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static STR_String gstrListRep=STR_String("List");
|
||||
|
||||
const STR_String & CListValue::GetText()
|
||||
{
|
||||
gstrListRep = "[";
|
||||
STR_String commastr = "";
|
||||
|
||||
for (int i=0;i<GetCount();i++)
|
||||
{
|
||||
gstrListRep += commastr;
|
||||
gstrListRep += GetValue(i)->GetText();
|
||||
commastr = ",";
|
||||
}
|
||||
gstrListRep += "]";
|
||||
|
||||
return gstrListRep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CListValue::GetReplica() {
|
||||
CListValue* replica = new CListValue(*this);
|
||||
|
||||
replica->ProcessReplica();
|
||||
|
||||
replica->m_bReleaseContents=true; // for copy, complete array is copied for now...
|
||||
// copy all values
|
||||
int numelements = m_pValueArray.size();
|
||||
unsigned int i=0;
|
||||
replica->m_pValueArray.resize(numelements);
|
||||
for (i=0;i<m_pValueArray.size();i++)
|
||||
replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
|
||||
|
||||
|
||||
return replica;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void CListValue::SetValue(int i, CValue *val)
|
||||
{
|
||||
assertd(i < m_pValueArray.size());
|
||||
m_pValueArray[i]=val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::Resize(int num)
|
||||
{
|
||||
m_pValueArray.resize(num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::Remove(int i)
|
||||
{
|
||||
assertd(i<m_pValueArray.size());
|
||||
m_pValueArray.erase(m_pValueArray.begin()+i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::ReleaseAndRemoveAll()
|
||||
{
|
||||
for (unsigned int i=0;i<m_pValueArray.size();i++)
|
||||
m_pValueArray[i]->Release();
|
||||
m_pValueArray.clear();//.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CListValue::FindValue(const STR_String & name)
|
||||
{
|
||||
for (int i=0; i < GetCount(); i++)
|
||||
if (GetValue(i)->GetName() == name)
|
||||
return GetValue(i);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CValue* CListValue::FindValue(const char * name)
|
||||
{
|
||||
for (int i=0; i < GetCount(); i++)
|
||||
if (GetValue(i)->GetName() == name)
|
||||
return GetValue(i);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CListValue::SearchValue(CValue *val)
|
||||
{
|
||||
for (int i=0;i<GetCount();i++)
|
||||
if (val == GetValue(i))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
|
||||
{
|
||||
m_bReleaseContents = bReleaseContents;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CListValue::RemoveValue(CValue *val)
|
||||
{
|
||||
bool result=false;
|
||||
|
||||
for (int i=GetCount()-1;i>=0;i--)
|
||||
if (val == GetValue(i))
|
||||
{
|
||||
Remove(i);
|
||||
result=true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::MergeList(CListValue *otherlist)
|
||||
{
|
||||
|
||||
int numelements = this->GetCount();
|
||||
int numotherelements = otherlist->GetCount();
|
||||
|
||||
|
||||
Resize(numelements+numotherelements);
|
||||
|
||||
for (int i=0;i<numotherelements;i++)
|
||||
{
|
||||
SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
|
||||
}
|
||||
}
|
||||
|
||||
bool CListValue::CheckEqual(CValue* first,CValue* second)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
|
||||
|
||||
if (eqval==NULL)
|
||||
return false;
|
||||
const STR_String& text = eqval->GetText();
|
||||
if (&text==&CBoolValue::sTrueString)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
eqval->Release();
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Some stuff taken from the header
|
||||
* --------------------------------------------------------------------- */
|
||||
CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val)
|
||||
{
|
||||
//assert(false); // todo: implement me!
|
||||
static int error_printed = 0;
|
||||
if (error_printed==0) {
|
||||
fprintf(stderr, "CValueList::Calc not yet implimented\n");
|
||||
error_printed = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype,
|
||||
VALUE_OPERATOR op,
|
||||
CValue* val)
|
||||
{
|
||||
//assert(false); // todo: implement me!
|
||||
static int error_printed = 0;
|
||||
if (error_printed==0) {
|
||||
fprintf(stderr, "CValueList::CalcFinal not yet implimented\n");
|
||||
error_printed = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::Add(CValue* value)
|
||||
{
|
||||
m_pValueArray.push_back(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CListValue::GetNumber()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CListValue::SetModified(bool bModified)
|
||||
{
|
||||
CValue::SetModified(bModified);
|
||||
int numels = GetCount();
|
||||
|
||||
for (int i=0;i<numels;i++)
|
||||
GetValue(i)->SetModified(bModified);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CListValue::IsModified()
|
||||
{
|
||||
bool bmod = CValue::IsModified(); //normal own flag
|
||||
int numels = GetCount();
|
||||
|
||||
for (int i=0;i<numels;i++)
|
||||
bmod = bmod || GetValue(i)->IsModified();
|
||||
|
||||
return bmod;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Python interface ---------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
Py_ssize_t listvalue_bufferlen(PyObject* self)
|
||||
{
|
||||
CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
if (list==NULL)
|
||||
return 0;
|
||||
|
||||
return (Py_ssize_t)list->GetCount();
|
||||
}
|
||||
|
||||
PyObject* listvalue_buffer_item(PyObject* self, Py_ssize_t index)
|
||||
{
|
||||
CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
CValue *cval;
|
||||
|
||||
if (list==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "val = CList[i], "BGE_PROXY_ERROR_MSG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count = list->GetCount();
|
||||
|
||||
if (index < 0)
|
||||
index = count+index;
|
||||
|
||||
if (index < 0 || index >= count) {
|
||||
PyErr_SetString(PyExc_IndexError, "CList[i]: Python ListIndex out of range in CValueList");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cval= list->GetValue(index);
|
||||
|
||||
PyObject* pyobj = cval->ConvertValueToPython();
|
||||
if (pyobj)
|
||||
return pyobj;
|
||||
else
|
||||
return cval->GetProxy();
|
||||
}
|
||||
|
||||
PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex)
|
||||
{
|
||||
CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
if (list==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "value = CList[i], "BGE_PROXY_ERROR_MSG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyUnicode_Check(pyindex))
|
||||
{
|
||||
CValue *item = ((CListValue*) list)->FindValue(_PyUnicode_AsString(pyindex));
|
||||
if (item) {
|
||||
PyObject* pyobj = item->ConvertValueToPython();
|
||||
if(pyobj)
|
||||
return pyobj;
|
||||
else
|
||||
return item->GetProxy();
|
||||
}
|
||||
}
|
||||
else if (PyLong_Check(pyindex))
|
||||
{
|
||||
int index = PyLong_AsSsize_t(pyindex);
|
||||
return listvalue_buffer_item(self, index); /* wont add a ref */
|
||||
}
|
||||
|
||||
PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */
|
||||
PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", _PyUnicode_AsString(pyindex_str));
|
||||
Py_DECREF(pyindex_str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* just slice it into a python list... */
|
||||
PyObject* listvalue_buffer_slice(PyObject* self,Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||
{
|
||||
CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
if (list==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "val = CList[i:j], "BGE_PROXY_ERROR_MSG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
PyObject *newlist;
|
||||
|
||||
if (ilow < 0) ilow = 0;
|
||||
|
||||
int n = ((CListValue*) list)->GetCount();
|
||||
|
||||
if (ihigh >= n)
|
||||
ihigh = n;
|
||||
if (ihigh < ilow)
|
||||
ihigh = ilow;
|
||||
|
||||
newlist = PyList_New(ihigh - ilow);
|
||||
if (!newlist)
|
||||
return NULL;
|
||||
|
||||
for (i = ilow, j = 0; i < ihigh; i++, j++)
|
||||
{
|
||||
PyObject* pyobj = list->GetValue(i)->ConvertValueToPython();
|
||||
if (!pyobj)
|
||||
pyobj = list->GetValue(i)->GetProxy();
|
||||
PyList_SET_ITEM(newlist, i, pyobj);
|
||||
}
|
||||
return newlist;
|
||||
}
|
||||
|
||||
|
||||
/* clist + list, return a list that python owns */
|
||||
static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other)
|
||||
{
|
||||
CListValue *listval= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
int i, numitems, numitems_orig;
|
||||
|
||||
if (listval==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
numitems_orig= listval->GetCount();
|
||||
|
||||
// for now, we support CListValue concatenated with items
|
||||
// and CListValue concatenated to Python Lists
|
||||
// and CListValue concatenated with another CListValue
|
||||
|
||||
/* Shallow copy, dont use listval->GetReplica(), it will screw up with KX_GameObjects */
|
||||
CListValue* listval_new = new CListValue();
|
||||
|
||||
if (PyList_Check(other))
|
||||
{
|
||||
CValue* listitemval;
|
||||
bool error = false;
|
||||
|
||||
numitems = PyList_Size(other);
|
||||
|
||||
/* copy the first part of the list */
|
||||
listval_new->Resize(numitems_orig + numitems);
|
||||
for (i=0;i<numitems_orig;i++)
|
||||
listval_new->SetValue(i, listval->GetValue(i)->AddRef());
|
||||
|
||||
for (i=0;i<numitems;i++)
|
||||
{
|
||||
listitemval = listval->ConvertPythonToValue(PyList_GetItem(other,i), "cList + pyList: CListValue, ");
|
||||
|
||||
if (listitemval) {
|
||||
listval_new->SetValue(i+numitems_orig, listitemval);
|
||||
} else {
|
||||
error= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
listval_new->Resize(numitems_orig+i); /* resize so we dont try release NULL pointers */
|
||||
listval_new->Release();
|
||||
return NULL; /* ConvertPythonToValue above sets the error */
|
||||
}
|
||||
|
||||
}
|
||||
else if (PyObject_TypeCheck(other, &CListValue::Type)) {
|
||||
// add items from otherlist to this list
|
||||
CListValue* otherval = static_cast<CListValue *>(BGE_PROXY_REF(other));
|
||||
if(otherval==NULL) {
|
||||
listval_new->Release();
|
||||
PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
numitems = otherval->GetCount();
|
||||
|
||||
/* copy the first part of the list */
|
||||
listval_new->Resize(numitems_orig + numitems); /* resize so we dont try release NULL pointers */
|
||||
for (i=0;i<numitems_orig;i++)
|
||||
listval_new->SetValue(i, listval->GetValue(i)->AddRef());
|
||||
|
||||
/* now copy the other part of the list */
|
||||
for (i=0;i<numitems;i++)
|
||||
listval_new->SetValue(i+numitems_orig, otherval->GetValue(i)->AddRef());
|
||||
|
||||
}
|
||||
return listval_new->NewProxy(true); /* python owns this list */
|
||||
}
|
||||
|
||||
static int listvalue_buffer_contains(PyObject *self_v, PyObject *value)
|
||||
{
|
||||
CListValue *self= static_cast<CListValue *>(BGE_PROXY_REF(self_v));
|
||||
|
||||
if (self==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "val in CList, "BGE_PROXY_ERROR_MSG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyUnicode_Check(value)) {
|
||||
if (self->FindValue((const char *)_PyUnicode_AsString(value))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (PyObject_TypeCheck(value, &CValue::Type)) { /* not dict like at all but this worked before __contains__ was used */
|
||||
CValue *item= static_cast<CValue *>(BGE_PROXY_REF(value));
|
||||
for (int i=0; i < self->GetCount(); i++)
|
||||
if (self->GetValue(i) == item) // Com
|
||||
return 1;
|
||||
|
||||
} // not using CheckEqual
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PySequenceMethods listvalue_as_sequence = {
|
||||
listvalue_bufferlen,//(inquiry)buffer_length, /*sq_length*/
|
||||
listvalue_buffer_concat, /*sq_concat*/
|
||||
NULL, /*sq_repeat*/
|
||||
listvalue_buffer_item, /*sq_item*/
|
||||
// TODO, slicing in py3
|
||||
NULL, // listvalue_buffer_slice, /*sq_slice*/
|
||||
NULL, /*sq_ass_item*/
|
||||
NULL, /*sq_ass_slice*/
|
||||
(objobjproc)listvalue_buffer_contains, /* sq_contains */
|
||||
(binaryfunc) NULL, /* sq_inplace_concat */
|
||||
(ssizeargfunc) NULL, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Is this one used ? */
|
||||
static PyMappingMethods instance_as_mapping = {
|
||||
listvalue_bufferlen, /*mp_length*/
|
||||
listvalue_mapping_subscript, /*mp_subscript*/
|
||||
NULL /*mp_ass_subscript*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
PyTypeObject CListValue::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"CListValue", /*tp_name*/
|
||||
sizeof(PyObjectPlus_Proxy), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
py_base_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
py_base_repr, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
&listvalue_as_sequence, /*tp_as_sequence*/
|
||||
&instance_as_mapping, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call */
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&CValue::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyMethodDef CListValue::Methods[] = {
|
||||
/* List style access */
|
||||
{"append", (PyCFunction)CListValue::sPyappend,METH_O},
|
||||
{"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS},
|
||||
{"index", (PyCFunction)CListValue::sPyindex,METH_O},
|
||||
{"count", (PyCFunction)CListValue::sPycount,METH_O},
|
||||
|
||||
/* Dict style access */
|
||||
{"get", (PyCFunction)CListValue::sPyget,METH_VARARGS},
|
||||
|
||||
/* Own cvalue funcs */
|
||||
{"from_id", (PyCFunction)CListValue::sPyfrom_id,METH_O},
|
||||
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef CListValue::Attributes[] = {
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* CListValue::Pyappend(PyObject* value)
|
||||
{
|
||||
CValue* objval = ConvertPythonToValue(value, "CList.append(i): CValueList, ");
|
||||
|
||||
if (!objval) /* ConvertPythonToValue sets the error */
|
||||
return NULL;
|
||||
|
||||
if (!BGE_PROXY_PYOWNS(m_proxy)) {
|
||||
PyErr_SetString(PyExc_TypeError, "CList.append(i): this CValueList is used internally for the game engine and can't be modified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Add(objval);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* CListValue::Pyreverse()
|
||||
{
|
||||
std::reverse(m_pValueArray.begin(),m_pValueArray.end());
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* CListValue::Pyindex(PyObject *value)
|
||||
{
|
||||
PyObject* result = NULL;
|
||||
|
||||
CValue* checkobj = ConvertPythonToValue(value, "val = cList[i]: CValueList, ");
|
||||
if (checkobj==NULL)
|
||||
return NULL; /* ConvertPythonToValue sets the error */
|
||||
|
||||
int numelem = GetCount();
|
||||
for (int i=0;i<numelem;i++)
|
||||
{
|
||||
CValue* elem = GetValue(i);
|
||||
if (checkobj==elem || CheckEqual(checkobj,elem))
|
||||
{
|
||||
result = PyLong_FromSsize_t(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
checkobj->Release();
|
||||
|
||||
if (result==NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "CList.index(x): x not in CListValue");
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* CListValue::Pycount(PyObject* value)
|
||||
{
|
||||
int numfound = 0;
|
||||
|
||||
CValue* checkobj = ConvertPythonToValue(value, ""); /* error ignored */
|
||||
|
||||
if (checkobj==NULL) { /* in this case just return that there are no items in the list */
|
||||
PyErr_Clear();
|
||||
return PyLong_FromSsize_t(0);
|
||||
}
|
||||
|
||||
int numelem = GetCount();
|
||||
for (int i=0;i<numelem;i++)
|
||||
{
|
||||
CValue* elem = GetValue(i);
|
||||
if (checkobj==elem || CheckEqual(checkobj,elem))
|
||||
{
|
||||
numfound ++;
|
||||
}
|
||||
}
|
||||
checkobj->Release();
|
||||
|
||||
return PyLong_FromSsize_t(numfound);
|
||||
}
|
||||
|
||||
/* Matches python dict.get(key, [default]) */
|
||||
PyObject* CListValue::Pyget(PyObject *args)
|
||||
{
|
||||
char *key;
|
||||
PyObject* def = Py_None;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
|
||||
return NULL;
|
||||
|
||||
CValue *item = FindValue((const char *)key);
|
||||
if (item) {
|
||||
PyObject* pyobj = item->ConvertValueToPython();
|
||||
if (pyobj)
|
||||
return pyobj;
|
||||
else
|
||||
return item->GetProxy();
|
||||
}
|
||||
Py_INCREF(def);
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
PyObject* CListValue::Pyfrom_id(PyObject* value)
|
||||
{
|
||||
uintptr_t id= (uintptr_t)PyLong_AsVoidPtr(value);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
int numelem = GetCount();
|
||||
for (int i=0;i<numelem;i++)
|
||||
{
|
||||
if (reinterpret_cast<uintptr_t>(m_pValueArray[i]->m_proxy) == id)
|
||||
return GetValue(i)->GetProxy();
|
||||
}
|
||||
PyErr_SetString(PyExc_IndexError, "from_id(#): id not found in CValueList");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* ListValue.h: interface for the CListValue class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined _LISTVALUE_H
|
||||
#define _LISTVALUE_H
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
class CListValue : public CPropValue
|
||||
{
|
||||
Py_Header;
|
||||
//PLUGIN_DECLARE_SERIAL (CListValue,CValue)
|
||||
|
||||
public:
|
||||
CListValue();
|
||||
virtual ~CListValue();
|
||||
|
||||
void AddConfigurationData(CValue* menuvalue);
|
||||
void Configure(CValue* menuvalue);
|
||||
void Add(CValue* value);
|
||||
|
||||
/** @attention not implemented yet :( */
|
||||
virtual CValue* Calc(VALUE_OPERATOR op,CValue *val);
|
||||
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
|
||||
VALUE_OPERATOR op,
|
||||
CValue* val);
|
||||
virtual double GetNumber();
|
||||
virtual CValue* GetReplica();
|
||||
|
||||
public:
|
||||
void MergeList(CListValue* otherlist);
|
||||
bool RemoveValue(CValue* val);
|
||||
void SetReleaseOnDestruct(bool bReleaseContents);
|
||||
bool SearchValue(CValue* val);
|
||||
|
||||
CValue* FindValue(const STR_String & name);
|
||||
CValue* FindValue(const char *name);
|
||||
|
||||
void ReleaseAndRemoveAll();
|
||||
virtual void SetModified(bool bModified);
|
||||
virtual inline bool IsModified();
|
||||
void Remove(int i);
|
||||
void Resize(int num);
|
||||
void SetValue(int i,CValue* val);
|
||||
CValue* GetValue(int i){ assertd(i < m_pValueArray.size()); return m_pValueArray[i];}
|
||||
int GetCount() { return m_pValueArray.size();};
|
||||
virtual const STR_String & GetText();
|
||||
|
||||
bool CheckEqual(CValue* first,CValue* second);
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
virtual PyObject* py_repr(void) {
|
||||
PyObject *py_proxy= this->GetProxy();
|
||||
PyObject *py_list= PySequence_List(py_proxy);
|
||||
PyObject *py_string= PyObject_Repr(py_list);
|
||||
Py_DECREF(py_list);
|
||||
Py_DECREF(py_proxy);
|
||||
return py_string;
|
||||
}
|
||||
|
||||
KX_PYMETHOD_O(CListValue,append);
|
||||
KX_PYMETHOD_NOARGS(CListValue,reverse);
|
||||
KX_PYMETHOD_O(CListValue,index);
|
||||
KX_PYMETHOD_O(CListValue,count);
|
||||
KX_PYMETHOD_VARARGS(CListValue,get);
|
||||
KX_PYMETHOD_O(CListValue,from_id);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
std::vector<CValue*> m_pValueArray;
|
||||
bool m_bReleaseContents;
|
||||
};
|
||||
|
||||
#endif // !defined _LISTVALUE_H
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = expression
|
||||
DIR = $(OCGDIR)/gameengine/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
|
||||
CPPFLAGS += -I../../blender/makesdna
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
|
||||
CPPFLAGS += -I$(NAN_STRING)/include
|
||||
CPPFLAGS += -I$(NAN_MOTO)/include
|
||||
CPPFLAGS += -I../../kernel/gen_system
|
||||
CPPFLAGS += -I../../gameengine/SceneGraph
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
// Operator1Expr.cpp: implementation of the COperator1Expr class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Operator1Expr.h"
|
||||
#include "EmptyValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
COperator1Expr::COperator1Expr()
|
||||
/*
|
||||
pre:
|
||||
effect: constucts an empty COperator1Expr
|
||||
*/
|
||||
{
|
||||
m_lhs = NULL;
|
||||
}
|
||||
|
||||
COperator1Expr::COperator1Expr(VALUE_OPERATOR op, CExpression * lhs)
|
||||
/*
|
||||
pre:
|
||||
effect: constucts a COperator1Expr with op and lhs in it
|
||||
*/
|
||||
{
|
||||
m_lhs = lhs;
|
||||
m_op = op;
|
||||
}
|
||||
|
||||
COperator1Expr::~COperator1Expr()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
if (m_lhs) m_lhs->Release();
|
||||
}
|
||||
|
||||
CValue * COperator1Expr::Calculate()
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying the operator m_op to the
|
||||
value of m_lhs
|
||||
*/
|
||||
{
|
||||
CValue *ret;
|
||||
CValue *temp = m_lhs->Calculate();
|
||||
CValue* empty = new CEmptyValue();
|
||||
ret = empty->Calc(m_op, temp);
|
||||
empty->Release();
|
||||
temp->Release();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
bool COperator1Expr::IsInside(float x, float y, float z,bool bBorderInclude)
|
||||
{
|
||||
|
||||
bool result = true;
|
||||
switch (m_op)
|
||||
{
|
||||
|
||||
case VALUE_ADD_OPERATOR:
|
||||
{
|
||||
|
||||
if (m_lhs)
|
||||
{
|
||||
result = result || m_lhs->IsInside(x,y,z,bBorderInclude);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_SUB_OPERATOR:
|
||||
{
|
||||
result = true;
|
||||
if (m_lhs)
|
||||
{
|
||||
result = result && (!m_lhs->IsInside(x,y,z,bBorderInclude));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
*/
|
||||
bool COperator1Expr::NeedsRecalculated() {
|
||||
|
||||
return m_lhs->NeedsRecalculated();
|
||||
|
||||
}
|
||||
|
||||
CExpression* COperator1Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
|
||||
|
||||
CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
|
||||
|
||||
if (newlhs)
|
||||
{
|
||||
if (newlhs==m_lhs) {
|
||||
// not changed
|
||||
} else {
|
||||
// changed
|
||||
//numchanges++;
|
||||
newlhs->AddRef();
|
||||
|
||||
//m_lhs->Release();
|
||||
brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
|
||||
|
||||
m_lhs = newlhs;
|
||||
}
|
||||
return this;
|
||||
} else {
|
||||
//numchanges++;
|
||||
AddRef();
|
||||
|
||||
return Release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void COperator1Expr::BroadcastOperators(VALUE_OPERATOR op)
|
||||
{
|
||||
if (m_lhs)
|
||||
m_lhs->BroadcastOperators(m_op);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool COperator1Expr::MergeExpression(CExpression *otherexpr)
|
||||
{
|
||||
if (m_lhs)
|
||||
return m_lhs->MergeExpression(otherexpr);
|
||||
|
||||
assertd(false); // should not get here, expression is not compatible for merge
|
||||
return false;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Operator1Expr.h: interface for the COperator1Expr class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
|
||||
#define AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_
|
||||
|
||||
#include "Expression.h"
|
||||
|
||||
class COperator1Expr : public CExpression
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator1Expr,CExpression)
|
||||
|
||||
|
||||
|
||||
public:
|
||||
virtual bool MergeExpression(CExpression* otherexpr);
|
||||
virtual void BroadcastOperators(VALUE_OPERATOR op);
|
||||
|
||||
virtual unsigned char GetExpressionID() { return COPERATOR1EXPRESSIONID;};
|
||||
CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
|
||||
//virtual bool IsInside(float x,float y,float z,bool bBorderInclude = true);
|
||||
virtual bool NeedsRecalculated();
|
||||
void ClearModified() {
|
||||
if (m_lhs)
|
||||
m_lhs->ClearModified();
|
||||
}
|
||||
virtual CValue* Calculate();
|
||||
COperator1Expr(VALUE_OPERATOR op, CExpression *lhs);
|
||||
COperator1Expr();
|
||||
virtual ~COperator1Expr();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
VALUE_OPERATOR m_op;
|
||||
CExpression * m_lhs;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:COperator1Expr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
// Operator2Expr.cpp: implementation of the COperator2Expr class.
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
// 31 dec 1998 - big update: try to use the cached data for updating, instead of
|
||||
// rebuilding completely it from left and right node. Modified flags and bounding boxes
|
||||
// have to do the trick
|
||||
// when expression is cached, there will be a call to UpdateCalc() instead of Calc()
|
||||
|
||||
#include "Operator2Expr.h"
|
||||
#include "StringValue.h"
|
||||
#include "VoidValue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
COperator2Expr::COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs)
|
||||
:
|
||||
m_rhs(rhs),
|
||||
m_lhs(lhs),
|
||||
m_cached_calculate(NULL),
|
||||
m_op(op)
|
||||
/*
|
||||
pre:
|
||||
effect: constucts a COperator2Expr with op, lhs and rhs in it
|
||||
*/
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
COperator2Expr::COperator2Expr():
|
||||
m_rhs(NULL),
|
||||
m_lhs(NULL),
|
||||
m_cached_calculate(NULL)
|
||||
|
||||
/*
|
||||
pre:
|
||||
effect: constucts an empty COperator2Expr
|
||||
*/
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
COperator2Expr::~COperator2Expr()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
if (m_lhs)
|
||||
m_lhs->Release();
|
||||
if (m_rhs)
|
||||
m_rhs->Release();
|
||||
if (m_cached_calculate)
|
||||
m_cached_calculate->Release();
|
||||
|
||||
}
|
||||
CValue* COperator2Expr::Calculate()
|
||||
/*
|
||||
pre:
|
||||
ret: a new object containing the result of applying operator m_op to m_lhs
|
||||
and m_rhs
|
||||
*/
|
||||
{
|
||||
|
||||
bool leftmodified,rightmodified;
|
||||
leftmodified = m_lhs->NeedsRecalculated();
|
||||
rightmodified = m_rhs->NeedsRecalculated();
|
||||
|
||||
// if no modifications on both left and right subtree, and result is already calculated
|
||||
// then just return cached result...
|
||||
if (!leftmodified && !rightmodified && (m_cached_calculate))
|
||||
{
|
||||
// not modified, just return m_cached_calculate
|
||||
} else {
|
||||
// if not yet calculated, or modified...
|
||||
|
||||
|
||||
if (m_cached_calculate) {
|
||||
m_cached_calculate->Release();
|
||||
m_cached_calculate=NULL;
|
||||
}
|
||||
|
||||
CValue* ffleft = m_lhs->Calculate();
|
||||
CValue* ffright = m_rhs->Calculate();
|
||||
|
||||
ffleft->SetOwnerExpression(this);//->m_pOwnerExpression=this;
|
||||
ffright->SetOwnerExpression(this);//->m_pOwnerExpression=this;
|
||||
|
||||
m_cached_calculate = ffleft->Calc(m_op,ffright);
|
||||
|
||||
//if (m_cached_calculate)
|
||||
// m_cached_calculate->Action(CValue::SETOWNEREXPR,&CVoidValue(this,false,CValue::STACKVALUE));
|
||||
|
||||
ffleft->Release();
|
||||
ffright->Release();
|
||||
}
|
||||
|
||||
return m_cached_calculate->AddRef();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)
|
||||
{
|
||||
bool inside;
|
||||
inside = false;
|
||||
|
||||
switch (m_op)
|
||||
{
|
||||
case VALUE_ADD_OPERATOR: {
|
||||
// inside = first || second; // optimized with early out if first is inside
|
||||
// todo: calculate smallest leaf first ! is much faster...
|
||||
|
||||
bool second;//first ;//,second;
|
||||
|
||||
//first = m_lhs->IsInside(x,y,z) ;
|
||||
second = m_rhs->IsInside(x,y,z,bBorderInclude) ;
|
||||
if (second)
|
||||
return true; //early out
|
||||
|
||||
// second = m_rhs->IsInside(x,y,z) ;
|
||||
|
||||
return m_lhs->IsInside(x,y,z,bBorderInclude) ;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VALUE_SUB_OPERATOR: {
|
||||
//inside = first && !second; // optimized with early out
|
||||
// todo: same as with add_operator: calc smallest leaf first
|
||||
|
||||
bool second;//first ;//,second;
|
||||
//first = m_lhs->IsInside(x,y,z) ;
|
||||
second = m_rhs->IsInside(x,y,z,bBorderInclude);
|
||||
if (second)
|
||||
return false;
|
||||
|
||||
// second space get subtracted -> negate!
|
||||
//second = m_rhs->IsInside(x,y,z);
|
||||
|
||||
return (m_lhs->IsInside(x,y,z,bBorderInclude));
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
assert(false);
|
||||
// not yet implemented, only add or sub csg operations
|
||||
}
|
||||
}
|
||||
|
||||
return inside;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) {
|
||||
|
||||
return m_rhs->IsInside(x,y,z,bBorderInclude) ;
|
||||
|
||||
}
|
||||
|
||||
bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) {
|
||||
return m_lhs->IsInside(x,y,z,bBorderInclude);
|
||||
}
|
||||
*/
|
||||
bool COperator2Expr::NeedsRecalculated() {
|
||||
// added some lines, just for debugging purposes, it could be a one-liner :)
|
||||
//bool modleft
|
||||
//bool modright;
|
||||
assertd(m_lhs);
|
||||
assertd(m_rhs);
|
||||
|
||||
//modright = m_rhs->NeedsRecalculated();
|
||||
if (m_rhs->NeedsRecalculated()) // early out
|
||||
return true;
|
||||
return m_lhs->NeedsRecalculated();
|
||||
//modleft = m_lhs->NeedsRecalculated();
|
||||
//return (modleft || modright);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CExpression* COperator2Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
|
||||
// if both children are 'dead', return NULL
|
||||
// if only one child is alive, return that child
|
||||
// if both childresn are alive, return this
|
||||
|
||||
|
||||
// bool leftalive = true,rightalive=true;
|
||||
/* Does this mean the function will always bomb? */
|
||||
assertd(false);
|
||||
assert(m_lhs);
|
||||
assert(m_rhs);
|
||||
/*
|
||||
if (m_cached_calculate)
|
||||
m_cached_calculate->Action(CValue::REFRESH_CACHE);
|
||||
|
||||
CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
|
||||
CExpression* newrhs = m_rhs->CheckLink(brokenlinks);
|
||||
|
||||
if (m_lhs != newlhs)
|
||||
{
|
||||
brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
|
||||
}
|
||||
|
||||
if (m_rhs != newrhs)
|
||||
{
|
||||
brokenlinks.push_back(new CBrokenLinkInfo(&m_rhs,m_rhs));
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_lhs = newlhs;
|
||||
m_rhs = newrhs;
|
||||
|
||||
if (m_lhs && m_rhs) {
|
||||
return this;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
if (m_lhs)
|
||||
return Release(m_lhs->AddRef());
|
||||
|
||||
if (m_rhs)
|
||||
return Release(m_rhs->AddRef());
|
||||
/
|
||||
|
||||
*/
|
||||
return Release();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool COperator2Expr::MergeExpression(CExpression *otherexpr)
|
||||
{
|
||||
if (m_lhs)
|
||||
{
|
||||
if (m_lhs->GetExpressionID() == CExpression::CCONSTEXPRESSIONID)
|
||||
{
|
||||
// cross fingers ;) replace constexpr by new tree...
|
||||
m_lhs->Release();
|
||||
m_lhs = otherexpr->AddRef();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
assertd(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void COperator2Expr::BroadcastOperators(VALUE_OPERATOR op)
|
||||
{
|
||||
if (m_lhs)
|
||||
m_lhs->BroadcastOperators(m_op);
|
||||
if (m_rhs)
|
||||
m_rhs->BroadcastOperators(m_op);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Operator2Expr.h: interface for the COperator2Expr class.
|
||||
* $Id$
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined _OPERATOR2EXPR_H
|
||||
#define _OPERATOR2EXPR_H
|
||||
|
||||
|
||||
#include "Expression.h"
|
||||
#include "Value.h" // Added by ClassView
|
||||
|
||||
class COperator2Expr : public CExpression
|
||||
{
|
||||
//PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator2Expr,CExpression)
|
||||
|
||||
public:
|
||||
virtual bool MergeExpression(CExpression* otherexpr);
|
||||
virtual unsigned char GetExpressionID() { return COPERATOR2EXPRESSIONID;};
|
||||
virtual void BroadcastOperators(VALUE_OPERATOR op);
|
||||
CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
|
||||
//virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
|
||||
//virtual bool IsLeftInside(float x,float y,float z,bool bBorderInclude);
|
||||
//virtual bool IsRightInside(float x,float y,float z,bool bBorderInclude);
|
||||
bool NeedsRecalculated();
|
||||
void ClearModified() {
|
||||
if (m_lhs)
|
||||
m_lhs->ClearModified();
|
||||
if (m_rhs)
|
||||
m_rhs->ClearModified();
|
||||
}
|
||||
virtual CValue* Calculate();
|
||||
COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs);
|
||||
COperator2Expr();
|
||||
virtual ~COperator2Expr();
|
||||
|
||||
|
||||
protected:
|
||||
CExpression * m_rhs;
|
||||
CExpression * m_lhs;
|
||||
CValue* m_cached_calculate; // cached result
|
||||
|
||||
private:
|
||||
VALUE_OPERATOR m_op;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:COperator2Expr"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // !defined _OPERATOR2EXPR_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,557 +0,0 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef _adr_py_lib_h_ // only process once,
|
||||
#define _adr_py_lib_h_ // even if multiply included
|
||||
|
||||
#ifndef __cplusplus // c++ only
|
||||
#error Must be compiled with C++
|
||||
#endif
|
||||
|
||||
#include "KX_Python.h"
|
||||
#include "STR_String.h"
|
||||
#include "MT_Vector3.h"
|
||||
#include "SG_QList.h"
|
||||
|
||||
/*------------------------------
|
||||
* Python defines
|
||||
------------------------------*/
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
#ifdef USE_MATHUTILS
|
||||
extern "C" {
|
||||
#include "../../blender/python/generic/mathutils.h" /* so we can have mathutils callbacks */
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void Py_Fatal(const char *M) {
|
||||
fprintf(stderr, "%s\n", M);
|
||||
exit(-1);
|
||||
};
|
||||
|
||||
|
||||
/* Use with ShowDeprecationWarning macro */
|
||||
typedef struct {
|
||||
bool warn_done;
|
||||
void *link;
|
||||
} WarnLink;
|
||||
|
||||
#define ShowDeprecationWarning(old_way, new_way) \
|
||||
{ \
|
||||
static WarnLink wlink = {false, NULL}; \
|
||||
if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \
|
||||
{ \
|
||||
ShowDeprecationWarning_func(old_way, new_way); \
|
||||
\
|
||||
WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \
|
||||
wlink.warn_done = true; \
|
||||
wlink.link = NULL; \
|
||||
\
|
||||
if(wlink_last) { \
|
||||
wlink_last->link= (void *)&(wlink); \
|
||||
SetDeprecationWarningLinkLast(&(wlink)); \
|
||||
} else { \
|
||||
SetDeprecationWarningFirst(&(wlink)); \
|
||||
SetDeprecationWarningLinkLast(&(wlink)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
typedef struct PyObjectPlus_Proxy {
|
||||
PyObject_HEAD /* required python macro */
|
||||
class PyObjectPlus *ref; // pointer to GE object, it holds a reference to this proxy
|
||||
void *ptr; // optional pointer to generic structure, the structure holds no reference to this proxy
|
||||
bool py_owns; // true if the object pointed by ref should be deleted when the proxy is deleted
|
||||
bool py_ref; // true if proxy is connected to a GE object (ref is used)
|
||||
} PyObjectPlus_Proxy;
|
||||
|
||||
#define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
|
||||
#define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
|
||||
#define BGE_PROXY_PTR(_self) (((PyObjectPlus_Proxy *)_self)->ptr)
|
||||
#define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
|
||||
#define BGE_PROXY_PYREF(_self) (((PyObjectPlus_Proxy *)_self)->py_ref)
|
||||
|
||||
/* Note, sometimes we dont care what BGE type this is as long as its a proxy */
|
||||
#define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc)
|
||||
|
||||
/* Opposite of BGE_PROXY_REF */
|
||||
#define BGE_PROXY_FROM_REF(_self) (((PyObjectPlus *)_self)->GetProxy())
|
||||
|
||||
|
||||
// This must be the first line of each
|
||||
// PyC++ class
|
||||
// AttributesPtr correspond to attributes of proxy generic pointer
|
||||
// each PyC++ class must be registered in KX_PythonInitTypes.cpp
|
||||
#define __Py_Header \
|
||||
public: \
|
||||
static PyTypeObject Type; \
|
||||
static PyMethodDef Methods[]; \
|
||||
static PyAttributeDef Attributes[]; \
|
||||
virtual PyTypeObject *GetType(void) {return &Type;}; \
|
||||
virtual PyObject *GetProxy() {return GetProxyPlus_Ext(this, &Type, NULL);}; \
|
||||
virtual PyObject *NewProxy(bool py_owns) {return NewProxyPlus_Ext(this, &Type, NULL, py_owns);}; \
|
||||
|
||||
// leave above line empty (macro)!
|
||||
// use this macro for class that use generic pointer in proxy
|
||||
// GetProxy() and NewProxy() must be defined to set the correct pointer in the proxy
|
||||
#define __Py_HeaderPtr \
|
||||
public: \
|
||||
static PyTypeObject Type; \
|
||||
static PyMethodDef Methods[]; \
|
||||
static PyAttributeDef Attributes[]; \
|
||||
static PyAttributeDef AttributesPtr[]; \
|
||||
virtual PyTypeObject *GetType(void) {return &Type;}; \
|
||||
virtual PyObject *GetProxy(); \
|
||||
virtual PyObject *NewProxy(bool py_owns); \
|
||||
|
||||
// leave above line empty (macro)!
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#define Py_Header __Py_Header \
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \
|
||||
void operator delete(void *mem) { MEM_freeN(mem); } \
|
||||
|
||||
#else
|
||||
#define Py_Header __Py_Header
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
#define Py_HeaderPtr __Py_HeaderPtr \
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); } \
|
||||
|
||||
#else
|
||||
#define Py_HeaderPtr __Py_HeaderPtr
|
||||
#endif
|
||||
|
||||
/*
|
||||
* nonzero values are an error for setattr
|
||||
* however because of the nested lookups we need to know if the errors
|
||||
* was because the attribute didnt exits of if there was some problem setting the value
|
||||
*/
|
||||
|
||||
#define PY_SET_ATTR_COERCE_FAIL 2
|
||||
#define PY_SET_ATTR_FAIL 1
|
||||
#define PY_SET_ATTR_MISSING -1
|
||||
#define PY_SET_ATTR_SUCCESS 0
|
||||
|
||||
/**
|
||||
* These macros are helpfull when embedding Python routines. The second
|
||||
* macro is one that also requires a documentation string
|
||||
*/
|
||||
#define KX_PYMETHOD(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \
|
||||
}; \
|
||||
|
||||
#define KX_PYMETHOD_VARARGS(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* args); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \
|
||||
}; \
|
||||
|
||||
#define KX_PYMETHOD_NOARGS(class_name, method_name) \
|
||||
PyObject* Py##method_name(); \
|
||||
static PyObject* sPy##method_name( PyObject* self) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \
|
||||
}; \
|
||||
|
||||
#define KX_PYMETHOD_O(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* value); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \
|
||||
}; \
|
||||
|
||||
#define KX_PYMETHOD_DOC(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \
|
||||
}; \
|
||||
static const char method_name##_doc[]; \
|
||||
|
||||
#define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* args); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \
|
||||
}; \
|
||||
static const char method_name##_doc[]; \
|
||||
|
||||
#define KX_PYMETHOD_DOC_O(class_name, method_name) \
|
||||
PyObject* Py##method_name(PyObject* value); \
|
||||
static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \
|
||||
}; \
|
||||
static const char method_name##_doc[]; \
|
||||
|
||||
#define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \
|
||||
PyObject* Py##method_name(); \
|
||||
static PyObject* sPy##method_name( PyObject* self) { \
|
||||
if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
|
||||
return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \
|
||||
}; \
|
||||
static const char method_name##_doc[]; \
|
||||
|
||||
|
||||
/* The line above should remain empty */
|
||||
/**
|
||||
* Method table macro (with doc)
|
||||
*/
|
||||
#define KX_PYMETHODTABLE(class_name, method_name) \
|
||||
{#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, (const char *)class_name::method_name##_doc}
|
||||
|
||||
#define KX_PYMETHODTABLE_O(class_name, method_name) \
|
||||
{#method_name , (PyCFunction) class_name::sPy##method_name, METH_O, (const char *)class_name::method_name##_doc}
|
||||
|
||||
#define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
|
||||
{#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (const char *)class_name::method_name##_doc}
|
||||
|
||||
/**
|
||||
* Function implementation macro
|
||||
*/
|
||||
#define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
|
||||
const char class_name::method_name##_doc[] = doc_string; \
|
||||
PyObject* class_name::Py##method_name(PyObject* args, PyObject*)
|
||||
|
||||
#define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
|
||||
const char class_name::method_name##_doc[] = doc_string; \
|
||||
PyObject* class_name::Py##method_name(PyObject* args)
|
||||
|
||||
#define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
|
||||
const char class_name::method_name##_doc[] = doc_string; \
|
||||
PyObject* class_name::Py##method_name(PyObject* value)
|
||||
|
||||
#define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
|
||||
const char class_name::method_name##_doc[] = doc_string; \
|
||||
PyObject* class_name::Py##method_name()
|
||||
|
||||
/**
|
||||
* Attribute management
|
||||
*/
|
||||
enum KX_PYATTRIBUTE_TYPE {
|
||||
KX_PYATTRIBUTE_TYPE_BOOL,
|
||||
KX_PYATTRIBUTE_TYPE_ENUM,
|
||||
KX_PYATTRIBUTE_TYPE_SHORT,
|
||||
KX_PYATTRIBUTE_TYPE_INT,
|
||||
KX_PYATTRIBUTE_TYPE_FLOAT,
|
||||
KX_PYATTRIBUTE_TYPE_STRING,
|
||||
KX_PYATTRIBUTE_TYPE_DUMMY,
|
||||
KX_PYATTRIBUTE_TYPE_FUNCTION,
|
||||
KX_PYATTRIBUTE_TYPE_VECTOR,
|
||||
KX_PYATTRIBUTE_TYPE_FLAG,
|
||||
KX_PYATTRIBUTE_TYPE_CHAR,
|
||||
};
|
||||
|
||||
enum KX_PYATTRIBUTE_ACCESS {
|
||||
KX_PYATTRIBUTE_RW,
|
||||
KX_PYATTRIBUTE_RO
|
||||
};
|
||||
|
||||
struct KX_PYATTRIBUTE_DEF;
|
||||
typedef int (*KX_PYATTRIBUTE_CHECK_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
typedef int (*KX_PYATTRIBUTE_SET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
typedef PyObject* (*KX_PYATTRIBUTE_GET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
typedef struct KX_PYATTRIBUTE_DEF {
|
||||
const char *m_name; // name of the python attribute
|
||||
KX_PYATTRIBUTE_TYPE m_type; // type of value
|
||||
KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
|
||||
int m_imin; // minimum value in case of integer attributes
|
||||
// (for string: minimum string length, for flag: mask value, for float: matrix row size)
|
||||
int m_imax; // maximum value in case of integer attributes
|
||||
// (for string: maximum string length, for flag: 1 if flag is negative, float: vector/matrix col size)
|
||||
float m_fmin; // minimum value in case of float attributes
|
||||
float m_fmax; // maximum value in case of float attributes
|
||||
bool m_clamp; // enforce min/max value by clamping
|
||||
bool m_usePtr; // the attribute uses the proxy generic pointer, set at runtime
|
||||
size_t m_offset; // position of field in structure
|
||||
size_t m_size; // size of field for runtime verification (enum only)
|
||||
size_t m_length; // length of array, 1=simple attribute
|
||||
KX_PYATTRIBUTE_CHECK_FUNCTION m_checkFunction; // static function to check the assignment, returns 0 if no error
|
||||
KX_PYATTRIBUTE_SET_FUNCTION m_setFunction; // static function to check the assignment, returns 0 if no error
|
||||
KX_PYATTRIBUTE_GET_FUNCTION m_getFunction; // static function to check the assignment, returns 0 if no error
|
||||
|
||||
// The following pointers are just used to have compile time check for attribute type.
|
||||
// It would have been good to use a union but that would require C99 compatibility
|
||||
// to initialize specific union fields through designated initializers.
|
||||
struct {
|
||||
bool *m_boolPtr;
|
||||
short int *m_shortPtr;
|
||||
int *m_intPtr;
|
||||
float *m_floatPtr;
|
||||
STR_String *m_stringPtr;
|
||||
MT_Vector3 *m_vectorPtr;
|
||||
char *m_charPtr;
|
||||
} m_typeCheck;
|
||||
} PyAttributeDef;
|
||||
|
||||
#define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
/* attribute points to a single bit of an integer field, attribute=true if bit is set */
|
||||
#define KX_PYATTRIBUTE_FLAG_RW(name,object,field,bit) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLAG_RW_CHECK(name,object,field,bit,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLAG_RO(name,object,field,bit) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
/* attribute points to a single bit of an integer field, attribute=true if bit is set*/
|
||||
#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name,object,field,bit) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name,object,field,bit,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name,object,field,bit) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
// enum field cannot be mapped to pointer (because we would need a pointer for each enum)
|
||||
// use field size to verify mapping at runtime only, assuming enum size is equal to int size.
|
||||
#define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
#define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
// SHORT_LIST
|
||||
#define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
#define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
// INT_LIST
|
||||
#define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
|
||||
|
||||
// always clamp for float
|
||||
#define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
|
||||
// field must be float[n], returns a sequence
|
||||
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
// field must be float[n], returns a vector
|
||||
#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name,min,max,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name,min,max,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
|
||||
// field must be float[n][n], returns a matrix
|
||||
#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name,min,max,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name,min,max,object,field,length,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name,object,field,length) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
|
||||
|
||||
// only for STR_String member
|
||||
#define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
|
||||
|
||||
// only for char [] array
|
||||
#define KX_PYATTRIBUTE_CHAR_RW(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
|
||||
#define KX_PYATTRIBUTE_CHAR_RW_CHECK(name,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
|
||||
#define KX_PYATTRIBUTE_CHAR_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
|
||||
|
||||
// for MT_Vector3 member
|
||||
#define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
|
||||
#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
|
||||
#define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
|
||||
|
||||
#define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
#define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
|
||||
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
|
||||
|
||||
|
||||
/*------------------------------
|
||||
* PyObjectPlus
|
||||
------------------------------*/
|
||||
typedef PyTypeObject * PyParentObject; // Define the PyParent Object
|
||||
|
||||
#else // DISABLE_PYTHON
|
||||
|
||||
#define Py_Header \
|
||||
public: \
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:PyObjectPlus"); } \
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); } \
|
||||
|
||||
#define Py_HeaderPtr \
|
||||
public: \
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:PyObjectPlusPtr"); } \
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); } \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// By making SG_QList the ultimate parent for PyObjectPlus objects, it
|
||||
// allows to put them in 2 different dynamic lists at the same time
|
||||
// The use of these links is interesting because they free of memory allocation
|
||||
// but it's very important not to mess up with them. If you decide that
|
||||
// the SG_QList or SG_DList component is used for something for a certain class,
|
||||
// they cannot can be used for anything else at a parent level!
|
||||
// What these lists are and what they are used for must be carefully documented
|
||||
// at the level where they are used.
|
||||
// DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used
|
||||
// at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the
|
||||
// possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level.
|
||||
class PyObjectPlus : public SG_QList
|
||||
{ // The PyObjectPlus abstract class
|
||||
Py_Header; // Always start with Py_Header
|
||||
|
||||
public:
|
||||
PyObjectPlus();
|
||||
|
||||
virtual ~PyObjectPlus(); // destructor
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
|
||||
|
||||
/* These static functions are referenced by ALL PyObjectPlus_Proxy types
|
||||
* they take the C++ reference from the PyObjectPlus_Proxy and call
|
||||
* its own virtual py_repr, py_base_dealloc ,etc. functions.
|
||||
*/
|
||||
|
||||
static PyObject* py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* allows subclassing */
|
||||
static void py_base_dealloc(PyObject *self);
|
||||
static PyObject* py_base_repr(PyObject *self);
|
||||
|
||||
/* These are all virtual python methods that are defined in each class
|
||||
* Our own fake subclassing calls these on each class, then calls the parent */
|
||||
virtual PyObject* py_repr(void);
|
||||
/* subclass may overwrite this function to implement more sophisticated method of validating a proxy */
|
||||
virtual bool py_is_valid(void) { return true; }
|
||||
|
||||
static PyObject* py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef);
|
||||
static int py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef);
|
||||
|
||||
/* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
|
||||
static PyObject* pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
static PyObject *GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr);
|
||||
/* self=NULL => proxy to generic pointer detached from GE object
|
||||
if py_owns is true, the memory pointed by ptr will be deleted automatially with MEM_freeN
|
||||
self!=NULL=> proxy attached to GE object, ptr is optional and point to a struct from which attributes can be defined
|
||||
if py_owns is true, the object will be deleted automatically, ptr will NOT be deleted
|
||||
(assume object destructor takes care of it) */
|
||||
static PyObject *NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr, bool py_owns);
|
||||
|
||||
static WarnLink* GetDeprecationWarningLinkFirst(void);
|
||||
static WarnLink* GetDeprecationWarningLinkLast(void);
|
||||
static void SetDeprecationWarningFirst(WarnLink* wlink);
|
||||
static void SetDeprecationWarningLinkLast(WarnLink* wlink);
|
||||
static void NullDeprecationWarning();
|
||||
|
||||
/** enable/disable display of deprecation warnings */
|
||||
static void SetDeprecationWarnings(bool ignoreDeprecationWarnings);
|
||||
/** Shows a deprecation warning */
|
||||
static void ShowDeprecationWarning_func(const char* method,const char* prop);
|
||||
static void ClearDeprecationWarning();
|
||||
|
||||
#endif
|
||||
|
||||
void InvalidateProxy();
|
||||
|
||||
/**
|
||||
* Makes sure any internal data owned by this class is deep copied.
|
||||
*/
|
||||
virtual void ProcessReplica();
|
||||
|
||||
static bool m_ignore_deprecation_warnings;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
|
||||
#endif
|
||||
|
||||
#endif // _adr_py_lib_h_
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('*.cpp')
|
||||
|
||||
incs ='. #source/kernel/gen_system #intern/guardedalloc #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader'
|
||||
|
||||
defs = []
|
||||
|
||||
if env['WITH_BF_PYTHON']:
|
||||
incs += ' ' + env['BF_PYTHON_INC']
|
||||
else:
|
||||
defs.append('DISABLE_PYTHON')
|
||||
|
||||
env.BlenderLib ( 'bf_expressions', sources, Split(incs), defs, libtype=['core','player'], priority = [360,80], cxx_compileflags=env['BGE_CXXFLAGS'])
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user