pgraph data graph
This commit is contained in:
parent
5e3785cbf5
commit
d3e2ffbda2
|
|
@ -9,21 +9,25 @@
|
|||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
analogNode.I analogNode.h buttonNode.I buttonNode.h \
|
||||
clientAnalogDevice.I clientAnalogDevice.h clientBase.I \
|
||||
clientBase.h clientButtonDevice.I clientButtonDevice.h \
|
||||
clientDevice.I clientDevice.h clientDialDevice.I \
|
||||
clientDialDevice.h clientTrackerDevice.I \
|
||||
clientTrackerDevice.h config_device.h dialNode.I dialNode.h \
|
||||
mouse.h trackerData.I trackerData.h trackerNode.I \
|
||||
trackerNode.h virtualMouse.h
|
||||
analogNode.I analogNode.h buttonNode.I buttonNode.h \
|
||||
clientAnalogDevice.I clientAnalogDevice.h clientBase.I \
|
||||
clientBase.h clientButtonDevice.I clientButtonDevice.h \
|
||||
clientDevice.I clientDevice.h clientDialDevice.I \
|
||||
clientDialDevice.h clientTrackerDevice.I \
|
||||
clientTrackerDevice.h config_device.h dialNode.I dialNode.h \
|
||||
mouse.h \
|
||||
mouseAndKeyboard.h \
|
||||
trackerData.I trackerData.h trackerNode.I \
|
||||
trackerNode.h virtualMouse.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
analogNode.cxx buttonNode.cxx clientAnalogDevice.cxx \
|
||||
clientBase.cxx clientButtonDevice.cxx clientDevice.cxx \
|
||||
clientDialDevice.cxx clientTrackerDevice.cxx \
|
||||
config_device.cxx dialNode.cxx mouse.cxx trackerData.cxx \
|
||||
trackerNode.cxx virtualMouse.cxx
|
||||
analogNode.cxx buttonNode.cxx clientAnalogDevice.cxx \
|
||||
clientBase.cxx clientButtonDevice.cxx clientDevice.cxx \
|
||||
clientDialDevice.cxx clientTrackerDevice.cxx \
|
||||
config_device.cxx dialNode.cxx mouse.cxx \
|
||||
mouseAndKeyboard.cxx \
|
||||
trackerData.cxx \
|
||||
trackerNode.cxx virtualMouse.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
analogNode.I analogNode.h \
|
||||
|
|
@ -35,6 +39,7 @@
|
|||
clientDialDevice.I clientDialDevice.h \
|
||||
clientTrackerDevice.I clientTrackerDevice.h \
|
||||
config_device.h mouse.h \
|
||||
mouseAndKeyboard.h \
|
||||
dialNode.I dialNode.h \
|
||||
trackerData.I trackerData.h \
|
||||
trackerNode.I trackerNode.h virtualMouse.h
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "clientTrackerDevice.h"
|
||||
#include "dialNode.h"
|
||||
#include "mouse.h"
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "trackerNode.h"
|
||||
#include "virtualMouse.h"
|
||||
|
||||
|
|
@ -68,6 +69,7 @@ init_libdevice() {
|
|||
ClientTrackerDevice::init_type();
|
||||
DialNode::init_type();
|
||||
MouseAndKeyboard::init_type();
|
||||
qpMouseAndKeyboard::init_type();
|
||||
TrackerNode::init_type();
|
||||
VirtualMouse::init_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "buttonNode.cxx"
|
||||
#include "dialNode.cxx"
|
||||
#include "mouse.cxx"
|
||||
#include "mouseAndKeyboard.cxx"
|
||||
#include "trackerData.cxx"
|
||||
#include "trackerNode.cxx"
|
||||
#include "virtualMouse.cxx"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
// Filename: mouseAndKeyboard.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "mouseData.h"
|
||||
#include "buttonHandle.h"
|
||||
#include "buttonEvent.h"
|
||||
#include "dataNodeTransmit.h"
|
||||
|
||||
TypeHandle qpMouseAndKeyboard::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpMouseAndKeyboard::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpMouseAndKeyboard::
|
||||
qpMouseAndKeyboard(GraphicsWindow *window, int device, const string &name) :
|
||||
qpDataNode(name),
|
||||
_window(window),
|
||||
_device(device)
|
||||
{
|
||||
_pixel_xy_output = define_output("PixelXY", EventStoreVec2::get_class_type());
|
||||
_xy_output = define_output("XY", EventStoreVec2::get_class_type());
|
||||
_button_events_output = define_output("ButtonEvents", ButtonEventList::get_class_type());
|
||||
|
||||
_pixel_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_button_events = new ButtonEventList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpMouseAndKeyboard::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of transmit_data(). This
|
||||
// function receives an array of input parameters and
|
||||
// should generate an array of output parameters. The
|
||||
// input parameters may be accessed with the index
|
||||
// numbers returned by the define_input() calls that
|
||||
// were made earlier (presumably in the constructor);
|
||||
// likewise, the output parameters should be set with
|
||||
// the index numbers returned by the define_output()
|
||||
// calls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpMouseAndKeyboard::
|
||||
do_transmit_data(const DataNodeTransmit &, DataNodeTransmit &output) {
|
||||
if (_window->has_button_event(_device)) {
|
||||
// Fill up the button events.
|
||||
_button_events->clear();
|
||||
while (_window->has_button_event(_device)) {
|
||||
ButtonEvent be = _window->get_button_event(_device);
|
||||
_button_events->add_event(be);
|
||||
}
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
}
|
||||
|
||||
if (_window->has_pointer(_device)) {
|
||||
const MouseData &mdata = _window->get_mouse_data(_device);
|
||||
|
||||
if (mdata._in_window) {
|
||||
// Get mouse motion in pixels.
|
||||
_pixel_xy->set_value(LPoint2f(mdata._xpos, mdata._ypos));
|
||||
output.set_data(_pixel_xy_output, EventParameter(_pixel_xy));
|
||||
|
||||
int w = _window->get_width();
|
||||
int h = _window->get_height();
|
||||
|
||||
// Normalize pixel motion to range [-1,1].
|
||||
float xf = (float)(2 * mdata._xpos) / (float)w - 1.0f;
|
||||
float yf = 1.0f - (float)(2 * mdata._ypos) / (float)h;
|
||||
|
||||
_xy->set_value(LPoint2f(xf, yf));
|
||||
output.set_data(_xy_output, EventParameter(_xy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Filename: mouseAndKeyboard.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MOUSEANDKEYBOARD_H
|
||||
#define MOUSEANDKEYBOARD_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "qpdataNode.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "linmath_events.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MouseAndKeyboard
|
||||
// Description : Reads the mouse and/or keyboard data sent from a
|
||||
// GraphicsWindow, and transmits it down the data graph.
|
||||
//
|
||||
// The mouse and keyboard devices are bundled together
|
||||
// into one device here, because they interrelate so
|
||||
// much. A mouse might be constrained by the holding
|
||||
// down of the shift key, for instance, or the clicking
|
||||
// of the mouse button might be handled in much the same
|
||||
// way as a keyboard key.
|
||||
//
|
||||
// Mouse data is sent down the data graph as an x,y
|
||||
// position as well as the set of buttons currently
|
||||
// being held down; keyboard data is sent down as a set
|
||||
// of keypress events in an EventDataTransition. To
|
||||
// throw these events to the system, you must attach an
|
||||
// EventThrower to the MouseAndKeyboard object;
|
||||
// otherwise, the events will be discarded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpMouseAndKeyboard : public qpDataNode {
|
||||
PUBLISHED:
|
||||
qpMouseAndKeyboard(GraphicsWindow *window, int device,
|
||||
const string &name);
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
DataNodeTransmit &output);
|
||||
|
||||
private:
|
||||
// outputs
|
||||
int _pixel_xy_output;
|
||||
int _xy_output;
|
||||
int _button_events_output;
|
||||
|
||||
PT(EventStoreVec2) _pixel_xy;
|
||||
PT(EventStoreVec2) _xy;
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
PT(GraphicsWindow) _window;
|
||||
int _device;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpDataNode::init_type();
|
||||
register_type(_type_handle, "qpMouseAndKeyboard",
|
||||
qpDataNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -4,38 +4,52 @@
|
|||
#begin lib_target
|
||||
#define TARGET dgraph
|
||||
#define LOCAL_LIBS \
|
||||
pstatclient sgraph graph putil sgattrib mathutil
|
||||
pstatclient sgraph graph putil sgattrib mathutil event
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
buttonEventDataTransition.I buttonEventDataTransition.h \
|
||||
config_dgraph.h dataGraphTraversal.h dataGraphTraverser.I \
|
||||
dataGraphTraverser.h dataNode.h dataRelation.I \
|
||||
dataRelation.N dataRelation.h describe_data_verbose.h \
|
||||
doubleDataTransition.I doubleDataTransition.h \
|
||||
intDataTransition.I intDataTransition.h \
|
||||
matrixDataTransition.I matrixDataTransition.h \
|
||||
numericDataTransition.I numericDataTransition.h \
|
||||
vec3DataTransition.I vec3DataTransition.h \
|
||||
vec4DataTransition.I vec4DataTransition.h \
|
||||
vectorDataTransition.I vectorDataTransition.h
|
||||
buttonEventDataTransition.I buttonEventDataTransition.h \
|
||||
config_dgraph.h dataGraphTraversal.h dataGraphTraverser.I \
|
||||
dataGraphTraverser.h \
|
||||
qpdataGraphTraverser.I qpdataGraphTraverser.h \
|
||||
dataNode.h \
|
||||
qpdataNode.I qpdataNode.h \
|
||||
dataNodeTransmit.I dataNodeTransmit.h \
|
||||
dataRelation.I \
|
||||
dataRelation.N dataRelation.h describe_data_verbose.h \
|
||||
doubleDataTransition.I doubleDataTransition.h \
|
||||
intDataTransition.I intDataTransition.h \
|
||||
matrixDataTransition.I matrixDataTransition.h \
|
||||
numericDataTransition.I numericDataTransition.h \
|
||||
vec3DataTransition.I vec3DataTransition.h \
|
||||
vec4DataTransition.I vec4DataTransition.h \
|
||||
vectorDataTransition.I vectorDataTransition.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
buttonEventDataTransition.cxx \
|
||||
config_dgraph.cxx dataGraphTraversal.cxx \
|
||||
dataGraphTraverser.cxx dataNode.cxx dataRelation.cxx \
|
||||
describe_data_verbose.cxx \
|
||||
doubleDataTransition.cxx \
|
||||
intDataTransition.cxx \
|
||||
matrixDataTransition.cxx \
|
||||
vec3DataTransition.cxx \
|
||||
vec4DataTransition.cxx
|
||||
buttonEventDataTransition.cxx \
|
||||
config_dgraph.cxx dataGraphTraversal.cxx \
|
||||
dataGraphTraverser.cxx \
|
||||
qpdataGraphTraverser.cxx \
|
||||
dataNode.cxx \
|
||||
qpdataNode.cxx \
|
||||
dataNodeTransmit.cxx \
|
||||
dataRelation.cxx \
|
||||
describe_data_verbose.cxx \
|
||||
doubleDataTransition.cxx \
|
||||
intDataTransition.cxx \
|
||||
matrixDataTransition.cxx \
|
||||
vec3DataTransition.cxx \
|
||||
vec4DataTransition.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
buttonEventDataTransition.I buttonEventDataTransition.h \
|
||||
dataGraphTraversal.h \
|
||||
dataNode.h dataRelation.I dataRelation.h \
|
||||
qpdataGraphTraverser.I qpdataGraphTraverser.h \
|
||||
dataNode.h \
|
||||
qpdataNode.I qpdataNode.h \
|
||||
dataNodeTransmit.I dataNodeTransmit.h \
|
||||
dataRelation.I dataRelation.h \
|
||||
describe_data_verbose.h \
|
||||
doubleDataTransition.I doubleDataTransition.h \
|
||||
intDataTransition.I intDataTransition.h \
|
||||
|
|
@ -46,8 +60,7 @@
|
|||
vectorDataTransition.I vectorDataTransition.h
|
||||
|
||||
#define IGATESCAN \
|
||||
dataNode.cxx dataNode.h dataRelation.cxx dataRelation.h \
|
||||
dataGraphTraversal.cxx dataGraphTraversal.h
|
||||
all
|
||||
|
||||
#end lib_target
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "config_dgraph.h"
|
||||
#include "dataNode.h"
|
||||
#include "qpdataNode.h"
|
||||
#include "dataRelation.h"
|
||||
#include "intDataTransition.h"
|
||||
#include "doubleDataTransition.h"
|
||||
|
|
@ -32,6 +33,7 @@ NotifyCategoryDef(dgraph, "");
|
|||
|
||||
ConfigureFn(config_dgraph) {
|
||||
DataNode::init_type();
|
||||
qpDataNode::init_type();
|
||||
DataRelation::init_type();
|
||||
IntDataTransition::init_type();
|
||||
DoubleDataTransition::init_type();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
// Filename: dataNodeTransmit.I
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataNodeTransmit::
|
||||
DataNodeTransmit() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataNodeTransmit::
|
||||
DataNodeTransmit(const DataNodeTransmit ©) :
|
||||
_data(copy._data)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DataNodeTransmit::
|
||||
operator = (const DataNodeTransmit ©) {
|
||||
_data = copy._data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataNodeTransmit::
|
||||
~DataNodeTransmit() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::reserve
|
||||
// Access: Public
|
||||
// Description: Tells the DataNodeTransmit object how many wires it
|
||||
// is expected to store data for.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DataNodeTransmit::
|
||||
reserve(int num_wires) {
|
||||
_data.reserve(num_wires);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::get_data
|
||||
// Access: Public
|
||||
// Description: Extracts the data for the indicated index, if it has
|
||||
// been stored, or the empty parameter if it has not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const EventParameter &DataNodeTransmit::
|
||||
get_data(int index) const {
|
||||
if (index >= 0 && index < (int)_data.size()) {
|
||||
return _data[index];
|
||||
}
|
||||
static EventParameter empty_parameter;
|
||||
return empty_parameter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::has_data
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated parameter has been
|
||||
// stored, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DataNodeTransmit::
|
||||
has_data(int index) const {
|
||||
if (index >= 0 && index < (int)_data.size()) {
|
||||
return !_data[index].is_empty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::set_data
|
||||
// Access: Public
|
||||
// Description: Sets the data for the indicated parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DataNodeTransmit::
|
||||
set_data(int index, const EventParameter &data) {
|
||||
if (index >= (int)_data.size()) {
|
||||
slot_data(index);
|
||||
}
|
||||
nassertv(index >= 0 && index < (int)_data.size());
|
||||
_data[index] = data;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Filename: dataNodeTransmit.cxx
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dataNodeTransmit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataNodeTransmit::slot_data
|
||||
// Access: Private
|
||||
// Description: Ensures that the given index number exists in the
|
||||
// data array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DataNodeTransmit::
|
||||
slot_data(int index) {
|
||||
nassertv(index < 1000);
|
||||
while (index >= (int)_data.size()) {
|
||||
_data.push_back(EventParameter());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// Filename: dataNodeTransmit.h
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DATANODETRANSMIT_H
|
||||
#define DATANODETRANSMIT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "eventParameter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DataNodeTransmit
|
||||
// Description : Encapsulates the data generated from (or sent into)
|
||||
// any particular DataNode. This is basically just an
|
||||
// array of EventParameters, one for each registered
|
||||
// input or output wire.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DataNodeTransmit {
|
||||
public:
|
||||
INLINE DataNodeTransmit();
|
||||
INLINE DataNodeTransmit(const DataNodeTransmit ©);
|
||||
INLINE void operator = (const DataNodeTransmit ©);
|
||||
INLINE ~DataNodeTransmit();
|
||||
|
||||
INLINE void reserve(int num_wires);
|
||||
|
||||
INLINE const EventParameter &get_data(int index) const;
|
||||
INLINE bool has_data(int index) const;
|
||||
INLINE void set_data(int index, const EventParameter &data);
|
||||
|
||||
private:
|
||||
void slot_data(int index);
|
||||
|
||||
typedef pvector<EventParameter> Data;
|
||||
Data _data;
|
||||
};
|
||||
|
||||
#include "dataNodeTransmit.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
|
||||
#include "dataGraphTraversal.cxx"
|
||||
#include "dataGraphTraverser.cxx"
|
||||
#include "qpdataGraphTraverser.cxx"
|
||||
#include "dataNode.cxx"
|
||||
#include "qpdataNode.cxx"
|
||||
#include "dataNodeTransmit.cxx"
|
||||
#include "dataRelation.cxx"
|
||||
#include "describe_data_verbose.cxx"
|
||||
#include "doubleDataTransition.cxx"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Filename: qpdataGraphTraverser.I
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::CollectedData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpDataGraphTraverser::CollectedData::
|
||||
CollectedData() :
|
||||
_num_parents(0)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
// Filename: qpdataGraphTraverser.cxx
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qpdataGraphTraverser.h"
|
||||
#include "qpdataNode.h"
|
||||
#include "config_dgraph.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::CollectedData::set_data
|
||||
// Access: Public
|
||||
// Description: Sets the data associated with the indicated parent of
|
||||
// this CollectedData object's node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataGraphTraverser::CollectedData::
|
||||
set_data(int parent_index, const DataNodeTransmit &data) {
|
||||
if ((int)_data.size() <= parent_index) {
|
||||
_data.reserve(parent_index + 1);
|
||||
while ((int)_data.size() <= parent_index) {
|
||||
_data.push_back(DataNodeTransmit());
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(parent_index >= 0 && parent_index < (int)_data.size());
|
||||
_data[parent_index] = data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpDataGraphTraverser::
|
||||
qpDataGraphTraverser() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpDataGraphTraverser::
|
||||
~qpDataGraphTraverser() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::traverse
|
||||
// Access: Public
|
||||
// Description: Starts the traversal of the data graph at the
|
||||
// indicated root node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataGraphTraverser::
|
||||
traverse(PandaNode *node) {
|
||||
if (node->is_of_type(qpDataNode::get_class_type())) {
|
||||
qpDataNode *data_node = DCAST(qpDataNode, node);
|
||||
int num_parents = data_node->get_num_parents();
|
||||
// We must start the traversal at the root of the graph.
|
||||
nassertv(num_parents == 0);
|
||||
|
||||
r_transmit(data_node, (DataNodeTransmit *)NULL);
|
||||
|
||||
} else {
|
||||
r_traverse_children(node, DataNodeTransmit());
|
||||
}
|
||||
|
||||
// Now pick up any nodes that didn't get completely traversed.
|
||||
// These must be nodes that have multiple parents, with at least one
|
||||
// parent completely outside of the data graph.
|
||||
|
||||
while (!_multipass_data.empty()) {
|
||||
MultipassData::iterator mi = _multipass_data.begin();
|
||||
qpDataNode *data_node = (*mi).first;
|
||||
const CollectedData &collected_data = (*mi).second;
|
||||
|
||||
dgraph_cat.warning()
|
||||
<< *data_node << " improperly parented partly outside of data graph.\n";
|
||||
|
||||
r_transmit(data_node, &collected_data._data[0]);
|
||||
_multipass_data.erase(mi);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::r_transmit
|
||||
// Access: Private
|
||||
// Description: Part of the recursive implementation of traverse().
|
||||
// This transmits the given data into the indicated
|
||||
// DataNode, and then sends the output data to each of
|
||||
// the node's children.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataGraphTraverser::
|
||||
r_transmit(qpDataNode *data_node, const DataNodeTransmit inputs[]) {
|
||||
DataNodeTransmit output;
|
||||
output.reserve(data_node->get_num_outputs());
|
||||
data_node->transmit_data(inputs, output);
|
||||
|
||||
r_traverse_children(data_node, output);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataGraphTraverser::r_traverse_children
|
||||
// Access: Private
|
||||
// Description: Part of the recursive implementation of traverse().
|
||||
// This visits each of the children of the indicated
|
||||
// node, passing in the given data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataGraphTraverser::
|
||||
r_traverse_children(PandaNode *node, const DataNodeTransmit &output) {
|
||||
PandaNode::Children cr = node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
PandaNode *child_node = cr.get_child(i);
|
||||
if (child_node->is_of_type(qpDataNode::get_class_type())) {
|
||||
qpDataNode *data_node = DCAST(qpDataNode, child_node);
|
||||
// If it's a DataNode-type child, we need to pass it the data.
|
||||
// Maybe it has only one parent, and can accept the data
|
||||
// immediately.
|
||||
int num_parents = data_node->get_num_parents();
|
||||
if (num_parents == 1) {
|
||||
// The easy, common case: only one parent. We make our output
|
||||
// into a one-element array of inputs by turning it into a
|
||||
// pointer.
|
||||
r_transmit(data_node, &output);
|
||||
} else {
|
||||
// A more difficult case: multiple parents. We must collect
|
||||
// instances together, meaning we must hold onto this node
|
||||
// until we have reached it through all paths.
|
||||
CollectedData &collected_data = _multipass_data[data_node];
|
||||
int parent_index = data_node->find_parent(node);
|
||||
nassertv(parent_index != -1);
|
||||
|
||||
collected_data.set_data(parent_index, output);
|
||||
collected_data._num_parents++;
|
||||
nassertv(collected_data._num_parents <= num_parents);
|
||||
if (collected_data._num_parents == num_parents) {
|
||||
// Now we've got all the data; go into the child.
|
||||
r_transmit(data_node, &collected_data._data[0]);
|
||||
_multipass_data.erase(data_node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The child node is not a DataNode-type child. We continue the
|
||||
// traversal, but data does not pass through this node, and
|
||||
// instances are not collected together. (Although we appear to
|
||||
// be passing the data through here, it doesn't do any good
|
||||
// anyway, since the child nodes of this node will not know how
|
||||
// to interpret the data from a non-DataNode parent.)
|
||||
r_traverse_children(child_node, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// Filename: qpdataGraphTraverser.h
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpDATAGRAPHTRAVERSER_H
|
||||
#define qpDATAGRAPHTRAVERSER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "dataNodeTransmit.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class qpDataNode;
|
||||
class PandaNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DataGraphTraverser
|
||||
// Description : This object supervises the traversal of the data
|
||||
// graph and the moving of data from one DataNode to its
|
||||
// children. The data graph is used to manage data from
|
||||
// input devices, etc. See the overview of the data
|
||||
// graph in dataNode.h.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpDataGraphTraverser {
|
||||
PUBLISHED:
|
||||
qpDataGraphTraverser();
|
||||
~qpDataGraphTraverser();
|
||||
|
||||
void traverse(PandaNode *node);
|
||||
|
||||
private:
|
||||
void r_transmit(qpDataNode *data_node, const DataNodeTransmit inputs[]);
|
||||
void r_traverse_children(PandaNode *node, const DataNodeTransmit &output);
|
||||
|
||||
typedef pvector<DataNodeTransmit> DataVector;
|
||||
|
||||
class CollectedData {
|
||||
public:
|
||||
INLINE CollectedData();
|
||||
void set_data(int parent_index, const DataNodeTransmit &data);
|
||||
|
||||
int _num_parents;
|
||||
DataVector _data;
|
||||
};
|
||||
typedef pmap<qpDataNode *, CollectedData> MultipassData;
|
||||
MultipassData _multipass_data;
|
||||
};
|
||||
|
||||
#include "qpdataGraphTraverser.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// Filename: qpdataNode.I
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpDataNode::
|
||||
qpDataNode(const string &name) :
|
||||
PandaNode(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpDataNode::
|
||||
qpDataNode(const qpDataNode ©) :
|
||||
PandaNode(copy)
|
||||
{
|
||||
// Copying a DataNode doesn't copy its inputs or outputs.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::get_num_inputs
|
||||
// Access: Public
|
||||
// Description: Returns the number of different inputs that have been
|
||||
// defined for this node using define_input(). This
|
||||
// indicates the size of the DataNodeTransmit object
|
||||
// that should be passed to do_transmit_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpDataNode::
|
||||
get_num_inputs() const {
|
||||
return _input_wires.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::get_num_outputs
|
||||
// Access: Public
|
||||
// Description: Returns the number of different outputs that have been
|
||||
// defined for this node using define_output(). This
|
||||
// indicates the size of the DataNodeTransmit object
|
||||
// that should be passed to do_transmit_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpDataNode::
|
||||
get_num_outputs() const {
|
||||
return _output_wires.size();
|
||||
}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
// Filename: qpdataNode.cxx
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qpdataNode.h"
|
||||
#include "dataNodeTransmit.h"
|
||||
#include "config_dgraph.h"
|
||||
|
||||
TypeHandle qpDataNode::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns a newly-allocated Node that is a shallow copy
|
||||
// of this one. It will be a different Node pointer,
|
||||
// but its internal data may or may not be shared with
|
||||
// that of the original Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *qpDataNode::
|
||||
make_copy() const {
|
||||
return new qpDataNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::transmit_data
|
||||
// Access: Public
|
||||
// Description: Collects the data from all of the parent nodes and
|
||||
// puts it into one DataNodeTransmit object, for
|
||||
// processing; calls do_transmit_data() to read all the
|
||||
// inputs and put the result into the indicated output.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
transmit_data(const DataNodeTransmit inputs[],
|
||||
DataNodeTransmit &output) {
|
||||
DataNodeTransmit new_input;
|
||||
new_input.reserve(get_num_inputs());
|
||||
|
||||
DataConnections::const_iterator ci;
|
||||
for (ci = _data_connections.begin(); ci != _data_connections.end(); ++ci) {
|
||||
const DataConnection &connect = (*ci);
|
||||
const EventParameter &data =
|
||||
inputs[connect._parent_index].get_data(connect._output_index);
|
||||
new_input.set_data(connect._input_index, data);
|
||||
}
|
||||
|
||||
do_transmit_data(new_input, output);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::write_inputs
|
||||
// Access: Published
|
||||
// Description: Writes to the indicated ostream a list of all the
|
||||
// inputs this DataNode might expect to receive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
write_inputs(ostream &out) const {
|
||||
Wires::const_iterator wi;
|
||||
for (wi = _input_wires.begin(); wi != _input_wires.end(); ++wi) {
|
||||
const string &name = (*wi).first;
|
||||
const WireDef &def = (*wi).second;
|
||||
out << name << " " << def._data_type << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::write_outputs
|
||||
// Access: Published
|
||||
// Description: Writes to the indicated ostream a list of all the
|
||||
// outputs this DataNode might generate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
write_outputs(ostream &out) const {
|
||||
Wires::const_iterator wi;
|
||||
for (wi = _output_wires.begin(); wi != _output_wires.end(); ++wi) {
|
||||
const string &name = (*wi).first;
|
||||
const WireDef &def = (*wi).second;
|
||||
out << name << " " << def._data_type << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::write_connections
|
||||
// Access: Published
|
||||
// Description: Writes to the indicated ostream a list of all the
|
||||
// connections currently showing between this DataNode
|
||||
// and its parent(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
write_connections(ostream &out) const {
|
||||
DataConnections::const_iterator ci;
|
||||
for (ci = _data_connections.begin(); ci != _data_connections.end(); ++ci) {
|
||||
const DataConnection &connect = (*ci);
|
||||
nassertv(connect._parent_index >= 0 && connect._parent_index < get_num_parents());
|
||||
|
||||
// Now we have to search exhaustively for the input with the
|
||||
// matching index number.
|
||||
Wires::const_iterator wi;
|
||||
bool found = false;
|
||||
for (wi = _input_wires.begin(); wi != _input_wires.end() && !found; ++wi) {
|
||||
const string &name = (*wi).first;
|
||||
const WireDef &def = (*wi).second;
|
||||
if (def._index == connect._input_index) {
|
||||
out << name << " " << def._data_type << " from "
|
||||
<< *get_parent(connect._parent_index) << "\n";
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
nassertv(found);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::define_input
|
||||
// Access: Protected
|
||||
// Description: Adds a new input wire with the given name and the
|
||||
// indicated data type. The data type should be the
|
||||
// TypeHandle for some type that derives from
|
||||
// TypedReferenceCount, e.g. EventStoreInt,
|
||||
// EventStoreDouble, or some fancier data type like
|
||||
// Texture.
|
||||
//
|
||||
// If there is already an input wire defined with the
|
||||
// indicated name, its type is changed.
|
||||
//
|
||||
// The return value is the index into the "input"
|
||||
// parameter to do_transmit_data() that can be used to
|
||||
// access the input data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpDataNode::
|
||||
define_input(const string &name, TypeHandle data_type) {
|
||||
// We shouldn't already be connected.
|
||||
nassertr(_data_connections.empty(), 0);
|
||||
|
||||
Wires::iterator wi;
|
||||
wi = _input_wires.find(name);
|
||||
if (wi != _input_wires.end()) {
|
||||
// This wire already existed; modify it and return the original
|
||||
// index.
|
||||
WireDef &def = (*wi).second;
|
||||
def._data_type = data_type;
|
||||
return def._index;
|
||||
}
|
||||
|
||||
// This wire did not already exist; add it.
|
||||
WireDef &def = _input_wires[name];
|
||||
def._data_type = data_type;
|
||||
def._index = _input_wires.size() - 1;
|
||||
return def._index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::define_output
|
||||
// Access: Protected
|
||||
// Description: Adds a new output wire with the given name and the
|
||||
// indicated data type. The data type should be the
|
||||
// TypeHandle for some type that derives from
|
||||
// TypedReferenceCount, e.g. EventStoreInt,
|
||||
// EventStoreDouble, or some fancier data type like
|
||||
// Texture.
|
||||
//
|
||||
// If there is already an output wire defined with the
|
||||
// indicated name, its type is changed.
|
||||
//
|
||||
// The return value is the index into the "output"
|
||||
// parameter to do_transmit_data() where the output data
|
||||
// should be stored.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpDataNode::
|
||||
define_output(const string &name, TypeHandle data_type) {
|
||||
// We shouldn't already be connected.
|
||||
nassertr(_data_connections.empty(), 0);
|
||||
|
||||
Wires::iterator wi;
|
||||
wi = _output_wires.find(name);
|
||||
if (wi != _output_wires.end()) {
|
||||
// This wire already existed; modify it and return the original
|
||||
// index.
|
||||
WireDef &def = (*wi).second;
|
||||
def._data_type = data_type;
|
||||
return def._index;
|
||||
}
|
||||
|
||||
// This wire did not already exist; add it.
|
||||
WireDef &def = _output_wires[name];
|
||||
def._data_type = data_type;
|
||||
def._index = _output_wires.size() - 1;
|
||||
return def._index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::parents_changed
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called after a scene graph update that either adds or
|
||||
// remove parents from this node, this just provides a
|
||||
// hook for derived PandaNode objects that need to
|
||||
// update themselves based on the set of parents the
|
||||
// node has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
parents_changed() {
|
||||
reconnect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of transmit_data(). This
|
||||
// function receives an array of input parameters and
|
||||
// should generate an array of output parameters. The
|
||||
// input parameters may be accessed with the index
|
||||
// numbers returned by the define_input() calls that
|
||||
// were made earlier (presumably in the constructor);
|
||||
// likewise, the output parameters should be set with
|
||||
// the index numbers returned by the define_output()
|
||||
// calls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
do_transmit_data(const DataNodeTransmit &, DataNodeTransmit &) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpDataNode::reconnect
|
||||
// Access: Private
|
||||
// Description: Establishes the input(s) that this DataNode has in
|
||||
// common with its parents' output(s). Builds up the
|
||||
// _data_connections list correspondingly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpDataNode::
|
||||
reconnect() {
|
||||
int num_parents = get_num_parents();
|
||||
_data_connections.clear();
|
||||
// Look for each input among one of the parents.
|
||||
|
||||
Wires::const_iterator wi;
|
||||
for (wi = _input_wires.begin(); wi != _input_wires.end(); ++wi) {
|
||||
const string &name = (*wi).first;
|
||||
const WireDef &input_def = (*wi).second;
|
||||
|
||||
int num_found = 0;
|
||||
for (int i = 0; i < num_parents; i++) {
|
||||
PandaNode *parent_node = get_parent(i);
|
||||
if (parent_node->is_of_type(qpDataNode::get_class_type())) {
|
||||
qpDataNode *data_node = DCAST(qpDataNode, parent_node);
|
||||
Wires::const_iterator pi;
|
||||
pi = data_node->_output_wires.find(name);
|
||||
if (pi != data_node->_output_wires.end()) {
|
||||
const WireDef &output_def = (*pi).second;
|
||||
num_found++;
|
||||
if (output_def._data_type != input_def._data_type) {
|
||||
dgraph_cat.warning()
|
||||
<< "Ignoring mismatched type for connection " << name
|
||||
<< " between " << *data_node << " and " << *this << "\n";
|
||||
} else if (num_found == 1) {
|
||||
DataConnection dc;
|
||||
dc._parent_index = i;
|
||||
dc._output_index = output_def._index;
|
||||
dc._input_index = input_def._index;
|
||||
_data_connections.push_back(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_found > 1) {
|
||||
dgraph_cat.warning()
|
||||
<< "Multiple connections found for " << name << " into " << *this
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (_data_connections.empty() && get_num_inputs() != 0 && num_parents != 0) {
|
||||
dgraph_cat.warning()
|
||||
<< "No data connected to " << *this << "\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
// Filename: qpdataNode.h
|
||||
// Created by: drose (11Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpDATANODE_H
|
||||
#define qpDATANODE_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Data Graph.
|
||||
//
|
||||
// The data graph is intended to hook up devices and their inputs
|
||||
// and/or outputs in a clean interface. It uses the same graph
|
||||
// relationship that is used to construct the scene graph, with the
|
||||
// same sort of nodes and NodePaths.
|
||||
//
|
||||
// In a data graph, each node may potentially produce and/or consume
|
||||
// data, and the arcs transmit data downward, from the root of the
|
||||
// graph to its leaves. Thus, an input device such as a mouse might
|
||||
// be added to the graph near the root, and a tformer-style object
|
||||
// that interprets the mouse data as a trackball motion and outputs a
|
||||
// matrix might be the immediate child of the mouse, followed by an
|
||||
// object that accepts a matrix and sets it on some particular arc in
|
||||
// the scene graph.
|
||||
//
|
||||
// Each different kind of DataNode defines its own set of input values
|
||||
// and output values, identified by name. When a DataNode is attached
|
||||
// to another DataNode, the inputs of the child are automatically
|
||||
// connected up to the corresponding outputs of the parent, and an
|
||||
// error message is issued if there are no matching connections.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class DataNodeTransmit;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpDataNode
|
||||
// Description : The fundamental type of node for the data graph. The
|
||||
// DataNode class is itself primarily intended as an
|
||||
// abstract class; it defines no inputs and no outputs.
|
||||
// Most kinds of data nodes will derive from this to
|
||||
// specify the inputs and outputs in the constructor.
|
||||
//
|
||||
// DataNode does not attempt to cycle its data with a
|
||||
// PipelineCycler. The data graph is intended to be
|
||||
// used only within a single thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpDataNode : public PandaNode {
|
||||
PUBLISHED:
|
||||
INLINE qpDataNode(const string &name);
|
||||
|
||||
protected:
|
||||
INLINE qpDataNode(const qpDataNode ©);
|
||||
public:
|
||||
virtual PandaNode *make_copy() const;
|
||||
|
||||
void transmit_data(const DataNodeTransmit inputs[],
|
||||
DataNodeTransmit &output);
|
||||
|
||||
INLINE int get_num_inputs() const;
|
||||
INLINE int get_num_outputs() const;
|
||||
|
||||
PUBLISHED:
|
||||
void write_inputs(ostream &out) const;
|
||||
void write_outputs(ostream &out) const;
|
||||
void write_connections(ostream &out) const;
|
||||
|
||||
//protected:
|
||||
int define_input(const string &name, TypeHandle data_type);
|
||||
int define_output(const string &name, TypeHandle data_type);
|
||||
|
||||
protected:
|
||||
// Inherited from PandaNode
|
||||
virtual void parents_changed();
|
||||
|
||||
// Local to DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
DataNodeTransmit &output);
|
||||
|
||||
private:
|
||||
void reconnect();
|
||||
|
||||
class WireDef {
|
||||
public:
|
||||
TypeHandle _data_type;
|
||||
int _index;
|
||||
};
|
||||
|
||||
typedef pmap<string, WireDef> Wires;
|
||||
|
||||
Wires _input_wires;
|
||||
Wires _output_wires;
|
||||
|
||||
class DataConnection {
|
||||
public:
|
||||
int _parent_index;
|
||||
int _output_index;
|
||||
int _input_index;
|
||||
};
|
||||
typedef pvector<DataConnection> DataConnections;
|
||||
DataConnections _data_connections;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
PandaNode::init_type();
|
||||
register_type(_type_handle, "qpDataNode",
|
||||
PandaNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "qpdataNode.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -32,6 +32,5 @@ ConfigureFn(config_event) {
|
|||
EventStoreInt::init_type("EventStoreInt");
|
||||
EventStoreDouble::init_type("EventStoreDouble");
|
||||
EventStoreString::init_type("EventStoreString");
|
||||
// EventStoreVec3::init_type("EventStoreVec3");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,16 @@
|
|||
template<class Type>
|
||||
TypeHandle EventStoreValue<Type>::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::Default constructor
|
||||
// Access: Public
|
||||
// Description: Defines an EventParameter that stores nothing: the
|
||||
// "empty" parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EventParameter::
|
||||
EventParameter() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::Pointer constructor
|
||||
// Access: Public
|
||||
|
|
@ -61,18 +71,6 @@ INLINE EventParameter::
|
|||
EventParameter(const string &value) : _ptr(new EventStoreString(value)) { }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::LVecBase3f constructor
|
||||
// Access: Public
|
||||
// Description: Defines an EventParameter that stores a
|
||||
// three-component numeric value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
INLINE EventParameter::
|
||||
EventParameter(const LVecBase3f &value) : _ptr(new EventStoreVec3(value)) { }
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::Copy constructor
|
||||
// Access: Public
|
||||
|
|
@ -93,6 +91,17 @@ operator = (const EventParameter &other) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::is_empty
|
||||
// Access: Public
|
||||
// Description: Returns true if the EventParameter is the empty
|
||||
// parameter, storing nothing, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EventParameter::
|
||||
is_empty() const {
|
||||
return (_ptr == (TypedReferenceCount *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::is_int
|
||||
// Access: Public
|
||||
|
|
@ -101,7 +110,9 @@ operator = (const EventParameter &other) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EventParameter::
|
||||
is_int() const {
|
||||
nassertr(_ptr != (TypedReferenceCount *)NULL, false);
|
||||
if (is_empty()) {
|
||||
return false;
|
||||
}
|
||||
return _ptr->is_of_type(EventStoreInt::get_class_type());
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +140,9 @@ get_int_value() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EventParameter::
|
||||
is_double() const {
|
||||
nassertr(_ptr != (TypedReferenceCount *)NULL, false);
|
||||
if (is_empty()) {
|
||||
return false;
|
||||
}
|
||||
return _ptr->is_of_type(EventStoreDouble::get_class_type());
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +167,9 @@ get_double_value() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EventParameter::
|
||||
is_string() const {
|
||||
nassertr(_ptr != (TypedReferenceCount *)NULL, false);
|
||||
if (is_empty()) {
|
||||
return false;
|
||||
}
|
||||
return _ptr->is_of_type(EventStoreString::get_class_type());
|
||||
}
|
||||
|
||||
|
|
@ -171,34 +186,6 @@ get_string_value() const {
|
|||
return ((const EventStoreString *)_ptr.p())->get_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::is_vec3
|
||||
// Access: Public
|
||||
// Description: Returns true if the EventParameter stores a
|
||||
// three-component vector value, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EventParameter::
|
||||
is_vec3() const {
|
||||
nassertr(_ptr != (TypedReferenceCount *)NULL, false);
|
||||
return false;
|
||||
// return _ptr->is_of_type(EventStoreVec3::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::get_vec3_value
|
||||
// Access: Public
|
||||
// Description: Retrieves the value stored in the EventParameter. It
|
||||
// is only valid to call this if is_vec3() has already
|
||||
// returned true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
INLINE LVecBase3f EventParameter::
|
||||
get_vec3_value() const {
|
||||
nassertr(is_vec3(), LVecBase3f(0.0, 0.0, 0.0));
|
||||
return ((const EventStoreVec3 *)_ptr.p())->get_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EventParameter::get_ptr
|
||||
// Access: Public
|
||||
|
|
@ -234,7 +221,7 @@ set_value(const Type &value) {
|
|||
// Description: Retrieves the value stored in the parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Type>
|
||||
INLINE Type EventStoreValue<Type>::
|
||||
INLINE const Type &EventStoreValue<Type>::
|
||||
get_value() const {
|
||||
return _value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@
|
|||
#ifndef EVENTPARAMETER_H
|
||||
#define EVENTPARAMETER_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include <typedef.h>
|
||||
#include <typedObject.h>
|
||||
#include <typedReferenceCount.h>
|
||||
#include <pointerTo.h>
|
||||
//#include <luse.h>
|
||||
#include <string>
|
||||
#include "typedef.h"
|
||||
#include "typedObject.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EventParameter
|
||||
|
|
@ -40,11 +38,11 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS EventParameter {
|
||||
PUBLISHED:
|
||||
INLINE EventParameter();
|
||||
INLINE EventParameter(const TypedReferenceCount *ptr);
|
||||
INLINE EventParameter(int value);
|
||||
INLINE EventParameter(double value);
|
||||
INLINE EventParameter(const string &value);
|
||||
// INLINE EventParameter(const LVecBase3f &value);
|
||||
|
||||
INLINE EventParameter(const EventParameter ©);
|
||||
INLINE EventParameter &operator = (const EventParameter ©);
|
||||
|
|
@ -54,14 +52,13 @@ PUBLISHED:
|
|||
// retrieve the corresponding value. Of course, it is possible that
|
||||
// the EventParameter is some user-defined type, and is none of
|
||||
// these.
|
||||
INLINE bool is_empty() const;
|
||||
INLINE bool is_int() const;
|
||||
INLINE int get_int_value() const;
|
||||
INLINE bool is_double() const;
|
||||
INLINE double get_double_value() const;
|
||||
INLINE bool is_string() const;
|
||||
INLINE string get_string_value() const;
|
||||
INLINE bool is_vec3() const;
|
||||
// INLINE LVecBase3f get_vec3_value() const;
|
||||
|
||||
INLINE const TypedReferenceCount *get_ptr() const;
|
||||
|
||||
|
|
@ -85,7 +82,7 @@ public:
|
|||
EventStoreValue(const Type &value) : _value(value) { }
|
||||
|
||||
INLINE void set_value(const Type &value);
|
||||
INLINE Type get_value() const;
|
||||
INLINE const Type &get_value() const;
|
||||
|
||||
Type _value;
|
||||
|
||||
|
|
@ -93,7 +90,7 @@ public:
|
|||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type(const string &type_name) {
|
||||
static void init_type(const string &type_name = "EventStoreValue") {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, type_name,
|
||||
TypedReferenceCount::get_class_type());
|
||||
|
|
@ -114,12 +111,10 @@ private:
|
|||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<int>);
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<double>);
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<std::string>);
|
||||
//EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<LVecBase3f>);
|
||||
|
||||
typedef EventStoreValue<int> EventStoreInt;
|
||||
typedef EventStoreValue<double> EventStoreDouble;
|
||||
typedef EventStoreValue<string> EventStoreString;
|
||||
//typedef EventStoreValue<LVecBase3f> EventStoreVec3;
|
||||
|
||||
#include "eventParameter.I"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,28 +4,32 @@
|
|||
#begin lib_target
|
||||
#define TARGET mathutil
|
||||
#define LOCAL_LIBS \
|
||||
linmath putil express
|
||||
linmath putil event express
|
||||
#define USE_FFTW yes
|
||||
#define UNIX_SYS_LIBS m
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
boundingHexahedron.I boundingHexahedron.h boundingLine.I \
|
||||
boundingLine.h boundingSphere.I boundingSphere.h \
|
||||
boundingVolume.I boundingVolume.h config_mathutil.h \
|
||||
fftCompressor.h finiteBoundingVolume.h frustum.h \
|
||||
frustum_src.I frustum_src.h geometricBoundingVolume.I \
|
||||
geometricBoundingVolume.h look_at.h look_at_src.I \
|
||||
look_at_src.cxx look_at_src.h omniBoundingVolume.I \
|
||||
omniBoundingVolume.h plane.h plane_src.I plane_src.cxx \
|
||||
plane_src.h rotate_to.h rotate_to_src.cxx
|
||||
boundingHexahedron.I boundingHexahedron.h boundingLine.I \
|
||||
boundingLine.h boundingSphere.I boundingSphere.h \
|
||||
boundingVolume.I boundingVolume.h config_mathutil.h \
|
||||
fftCompressor.h finiteBoundingVolume.h frustum.h \
|
||||
frustum_src.I frustum_src.h geometricBoundingVolume.I \
|
||||
geometricBoundingVolume.h \
|
||||
linmath_events.h \
|
||||
look_at.h look_at_src.I \
|
||||
look_at_src.cxx look_at_src.h omniBoundingVolume.I \
|
||||
omniBoundingVolume.h plane.h plane_src.I plane_src.cxx \
|
||||
plane_src.h rotate_to.h rotate_to_src.cxx
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
boundingHexahedron.cxx boundingLine.cxx boundingSphere.cxx \
|
||||
boundingVolume.cxx config_mathutil.cxx fftCompressor.cxx \
|
||||
finiteBoundingVolume.cxx geometricBoundingVolume.cxx \
|
||||
look_at.cxx omniBoundingVolume.cxx plane.cxx rotate_to.cxx
|
||||
boundingHexahedron.cxx boundingLine.cxx boundingSphere.cxx \
|
||||
boundingVolume.cxx config_mathutil.cxx fftCompressor.cxx \
|
||||
finiteBoundingVolume.cxx geometricBoundingVolume.cxx \
|
||||
look_at.cxx \
|
||||
linmath_events.cxx \
|
||||
omniBoundingVolume.cxx plane.cxx rotate_to.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
boundingHexahedron.I boundingHexahedron.h boundingLine.I \
|
||||
|
|
@ -33,7 +37,9 @@
|
|||
boundingVolume.h config_mathutil.h fftCompressor.h \
|
||||
finiteBoundingVolume.h frustum.h frustum_src.I frustum_src.h \
|
||||
geometricBoundingVolume.I geometricBoundingVolume.h look_at.h \
|
||||
look_at_src.I look_at_src.h mathHelpers.I mathHelpers.h \
|
||||
look_at_src.I look_at_src.h \
|
||||
linmath_events.h \
|
||||
mathHelpers.I mathHelpers.h \
|
||||
omniBoundingVolume.I omniBoundingVolume.h plane.h plane_src.I \
|
||||
plane_src.h rotate_to.h
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
#include "boundingSphere.h"
|
||||
#include "boundingHexahedron.h"
|
||||
#include "boundingLine.h"
|
||||
#include <dconfig.h>
|
||||
#include "linmath_events.h"
|
||||
#include "dconfig.h"
|
||||
|
||||
Configure(config_mathutil);
|
||||
NotifyCategoryDef(mathutil, "");
|
||||
|
|
@ -41,5 +42,8 @@ ConfigureFn(config_mathutil) {
|
|||
GeometricBoundingVolume::init_type();
|
||||
OmniBoundingVolume::init_type();
|
||||
BoundingLine::init_type();
|
||||
EventStoreVec2::init_type("EventStoreVec2");
|
||||
EventStoreVec3::init_type("EventStoreVec3");
|
||||
EventStoreMat4::init_type("EventStoreMat4");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
// Filename: linmath_events.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "linmath_events.h"
|
||||
|
||||
// Tell GCC that we'll take care of the instantiation explicitly here.
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// Filename: linmath_events.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LINMATH_EVENTS_H
|
||||
#define LINMATH_EVENTS_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eventParameter.h"
|
||||
#include "luse.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file defines a few more EventStore classes for storing linmath
|
||||
// objects in an EventParameter. We can't define this with the other
|
||||
// EventStore classes, because linmath hasn't been defined yet at that
|
||||
// point.
|
||||
//
|
||||
// See eventParameter.h.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<LVecBase2f>);
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<LVecBase3f>);
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, EventStoreValue<LMatrix4f>);
|
||||
|
||||
typedef EventStoreValue<LVecBase2f> EventStoreVec2;
|
||||
typedef EventStoreValue<LVecBase3f> EventStoreVec3;
|
||||
typedef EventStoreValue<LMatrix4f> EventStoreMat4;
|
||||
|
||||
|
||||
// Tell GCC that we'll take care of the instantiation explicitly here.
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -3,5 +3,6 @@
|
|||
#include "plane.cxx"
|
||||
#include "rotate_to.cxx"
|
||||
#include "look_at.cxx"
|
||||
#include "linmath_events.cxx"
|
||||
#include "fftCompressor.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -510,6 +510,10 @@ add_child(PandaNode *child_node, int sort) {
|
|||
|
||||
// Mark the bounding volumes stale.
|
||||
force_bound_stale();
|
||||
|
||||
// Call callback hooks.
|
||||
children_changed();
|
||||
child_node->parents_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -519,11 +523,12 @@ add_child(PandaNode *child_node, int sort) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
remove_child(int n) {
|
||||
PT(PandaNode) child_node;
|
||||
{
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(n >= 0 && n < (int)cdata->_down.size());
|
||||
|
||||
PT(PandaNode) child_node = cdata->_down[n].get_child();
|
||||
child_node = cdata->_down[n].get_child();
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
|
||||
cdata->_down.erase(cdata->_down.begin() + n);
|
||||
|
|
@ -562,6 +567,10 @@ remove_child(int n) {
|
|||
|
||||
// Mark the bounding volumes stale.
|
||||
force_bound_stale();
|
||||
|
||||
// Call callback hooks.
|
||||
children_changed();
|
||||
child_node->parents_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -574,9 +583,9 @@ remove_child(int n) {
|
|||
bool PandaNode::
|
||||
remove_child(PandaNode *child_node) {
|
||||
// Ensure the child_node is not deleted while we do this.
|
||||
{
|
||||
PT(PandaNode) keep_child = child_node;
|
||||
PT(PandaNode) keep_child = child_node;
|
||||
|
||||
{
|
||||
CDWriter cdata(_cycler);
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
|
||||
|
|
@ -626,6 +635,10 @@ remove_child(PandaNode *child_node) {
|
|||
|
||||
// Mark the bounding volumes stale.
|
||||
force_bound_stale();
|
||||
|
||||
// Call callback hooks.
|
||||
children_changed();
|
||||
child_node->parents_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -641,36 +654,40 @@ remove_all_children() {
|
|||
Down::iterator ci;
|
||||
for (ci = cdata->_down.begin(); ci != cdata->_down.end(); ++ci) {
|
||||
PT(PandaNode) child_node = (*ci).get_child();
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
cdata_child->_up.erase(UpConnection(this));
|
||||
{
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
cdata_child->_up.erase(UpConnection(this));
|
||||
|
||||
// Now sever any qpNodePathComponents on the child that reference
|
||||
// this node. If we have multiple of these, we have to collapse
|
||||
// them together (see above).
|
||||
qpNodePathComponent *collapsed = (qpNodePathComponent *)NULL;
|
||||
Chains::iterator ci;
|
||||
ci = cdata_child->_chains.begin();
|
||||
while (ci != cdata_child->_chains.end()) {
|
||||
Chains::iterator cnext = ci;
|
||||
++cnext;
|
||||
if (!(*ci)->is_top_node() && (*ci)->get_next()->get_node() == this) {
|
||||
if (collapsed == (qpNodePathComponent *)NULL) {
|
||||
(*ci)->set_top_node();
|
||||
collapsed = (*ci);
|
||||
} else {
|
||||
(*ci)->collapse_with(collapsed);
|
||||
cdata_child->_chains.erase(ci);
|
||||
// Now sever any qpNodePathComponents on the child that
|
||||
// reference this node. If we have multiple of these, we have
|
||||
// to collapse them together (see above).
|
||||
qpNodePathComponent *collapsed = (qpNodePathComponent *)NULL;
|
||||
Chains::iterator ci;
|
||||
ci = cdata_child->_chains.begin();
|
||||
while (ci != cdata_child->_chains.end()) {
|
||||
Chains::iterator cnext = ci;
|
||||
++cnext;
|
||||
if (!(*ci)->is_top_node() && (*ci)->get_next()->get_node() == this) {
|
||||
if (collapsed == (qpNodePathComponent *)NULL) {
|
||||
(*ci)->set_top_node();
|
||||
collapsed = (*ci);
|
||||
} else {
|
||||
(*ci)->collapse_with(collapsed);
|
||||
cdata_child->_chains.erase(ci);
|
||||
}
|
||||
}
|
||||
ci = cnext;
|
||||
}
|
||||
ci = cnext;
|
||||
|
||||
child_node->fix_chain_lengths(cdata_child);
|
||||
}
|
||||
|
||||
child_node->fix_chain_lengths(cdata_child);
|
||||
child_node->parents_changed();
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the bounding volumes stale.
|
||||
force_bound_stale();
|
||||
children_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -813,6 +830,32 @@ recompute_internal_bound() {
|
|||
return _internal_bound.recompute_bound();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::parents_changed
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called after a scene graph update that either adds or
|
||||
// remove parents from this node, this just provides a
|
||||
// hook for derived PandaNode objects that need to
|
||||
// update themselves based on the set of parents the
|
||||
// node has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
parents_changed() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::children_changed
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called after a scene graph update that either adds or
|
||||
// remove children from this node, this just provides a
|
||||
// hook for derived PandaNode objects that need to
|
||||
// update themselves based on the set of children the
|
||||
// node has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
children_changed() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::attach
|
||||
// Access: Private, Static
|
||||
|
|
@ -900,6 +943,10 @@ detach(qpNodePathComponent *child) {
|
|||
|
||||
// Mark the bounding volumes stale.
|
||||
parent_node->force_bound_stale();
|
||||
|
||||
// Call callback hooks.
|
||||
parent_node->children_changed();
|
||||
child_node->parents_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -936,6 +983,10 @@ reparent(qpNodePathComponent *new_parent, qpNodePathComponent *child, int sort)
|
|||
|
||||
// Mark the bounding volumes stale.
|
||||
parent_node->force_bound_stale();
|
||||
|
||||
// Call callback hooks.
|
||||
parent_node->children_changed();
|
||||
child_node->parents_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ protected:
|
|||
// Local to PandaNode
|
||||
virtual BoundingVolume *recompute_internal_bound();
|
||||
INLINE void changed_internal_bound();
|
||||
virtual void parents_changed();
|
||||
virtual void children_changed();
|
||||
|
||||
// This is the bounding volume around the contents of the node
|
||||
// itself (without including all of the node's children).
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
#define SOURCES \
|
||||
bam.h bamReader.I bamReader.N bamReader.h bamReaderParam.I \
|
||||
bamReaderParam.h bamWriter.I bamWriter.h bitMask.I \
|
||||
bitMask.h buttonEvent.I buttonEvent.h buttonHandle.I \
|
||||
bitMask.h buttonEvent.I buttonEvent.h \
|
||||
buttonEventList.I buttonEventList.h \
|
||||
buttonHandle.I \
|
||||
buttonHandle.h buttonRegistry.I buttonRegistry.h \
|
||||
collideMask.h \
|
||||
compareTo.I compareTo.h \
|
||||
|
|
@ -50,7 +52,9 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
bamReader.cxx bamReaderParam.cxx bamWriter.cxx bitMask.cxx \
|
||||
buttonEvent.cxx buttonHandle.cxx buttonRegistry.cxx \
|
||||
buttonEvent.cxx \
|
||||
buttonEventList.cxx \
|
||||
buttonHandle.cxx buttonRegistry.cxx \
|
||||
config_util.cxx configurable.cxx \
|
||||
cycleData.cxx \
|
||||
cycleDataReader.cxx \
|
||||
|
|
@ -78,7 +82,9 @@
|
|||
#define INSTALL_HEADERS \
|
||||
bam.h bamReader.I bamReader.h bamReaderParam.I bamReaderParam.h \
|
||||
bamWriter.I bamWriter.h bitMask.I bitMask.h buttonEvent.I \
|
||||
buttonEvent.h buttonHandle.I buttonHandle.h buttonRegistry.I \
|
||||
buttonEvent.h \
|
||||
buttonEventList.I buttonEventList.h \
|
||||
buttonHandle.I buttonHandle.h buttonRegistry.I \
|
||||
buttonRegistry.h collideMask.h \
|
||||
compareTo.I compareTo.h \
|
||||
config_util.h configurable.h factory.I factory.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// Filename: buttonEventList.I
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonEventList::
|
||||
ButtonEventList() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::add_event
|
||||
// Access: Public
|
||||
// Description: Adds a new event to the end of the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ButtonEventList::
|
||||
add_event(ButtonEvent event) {
|
||||
_events.push_back(event);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::get_num_events
|
||||
// Access: Public
|
||||
// Description: Returns the number of events in the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ButtonEventList::
|
||||
get_num_events() const {
|
||||
return _events.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::get_event
|
||||
// Access: Public
|
||||
// Description: Returns the nth event in the list. This does not
|
||||
// remove the event from the list; the only way to
|
||||
// remove events is to empty the whole list with
|
||||
// clear().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const ButtonEvent &ButtonEventList::
|
||||
get_event(int n) const {
|
||||
#ifndef NDEBUG
|
||||
static ButtonEvent empty_event;
|
||||
nassertr(n >= 0 && n < (int)_events.size(), empty_event);
|
||||
#endif // NDEBUG
|
||||
return _events[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::clear
|
||||
// Access: Public
|
||||
// Description: Empties all the events from the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ButtonEventList::
|
||||
clear() {
|
||||
_events.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Filename: buttonEventList.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "buttonEventList.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle ButtonEventList::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::update_mods
|
||||
// Access: Public
|
||||
// Description: Updates the indicated ModifierButtons object with all
|
||||
// of the button up/down transitions indicated in the
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ButtonEventList::
|
||||
update_mods(ModifierButtons &mods) const {
|
||||
Events::const_iterator ei;
|
||||
for (ei = _events.begin(); ei != _events.end(); ++ei) {
|
||||
mods.add_event(*ei);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ButtonEventList::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << " (" << get_num_events() << " events)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonEventList::write
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ButtonEventList::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << *this << ":\n";
|
||||
Events::const_iterator ei;
|
||||
for (ei = _events.begin(); ei != _events.end(); ++ei) {
|
||||
indent(out, indent_level + 2) << (*ei) << "\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Filename: buttonEventList.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BUTTONEVENTLIST_H
|
||||
#define BUTTONEVENTLIST_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "buttonEvent.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class ModifierButtons;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ButtonEventList
|
||||
// Description : Records a set of button events that happened
|
||||
// recently. This class is usually used only in the
|
||||
// data graph, to transmit the recent button presses,
|
||||
// but it may be used anywhere a list of ButtonEvents
|
||||
// is desired.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA ButtonEventList : public TypedReferenceCount {
|
||||
public:
|
||||
INLINE ButtonEventList();
|
||||
|
||||
INLINE void add_event(ButtonEvent event);
|
||||
INLINE int get_num_events() const;
|
||||
INLINE const ButtonEvent &get_event(int n) const;
|
||||
INLINE void clear();
|
||||
|
||||
void update_mods(ModifierButtons &mods) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
typedef pvector<ButtonEvent> Events;
|
||||
Events _events;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "ButtonEventList",
|
||||
TypedReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const ButtonEventList &list) {
|
||||
list.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "buttonEventList.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_util.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "clockObject.h"
|
||||
#include "typedObject.h"
|
||||
#include "configurable.h"
|
||||
|
|
@ -43,6 +44,7 @@ NotifyCategoryDef(bam, util_cat);
|
|||
|
||||
ConfigureFn(config_util) {
|
||||
// ClockObject::init_ptr();
|
||||
ButtonEventList::init_type();
|
||||
TypedObject::init_type();
|
||||
Configurable::init_type();
|
||||
Namable::init_type();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "bamWriter.cxx"
|
||||
#include "bitMask.cxx"
|
||||
#include "buttonEvent.cxx"
|
||||
#include "buttonEventList.cxx"
|
||||
#include "buttonHandle.cxx"
|
||||
#include "buttonRegistry.cxx"
|
||||
#include "config_util.cxx"
|
||||
|
|
|
|||
|
|
@ -39,21 +39,16 @@
|
|||
#include "notify.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "cullBinManager.h"
|
||||
|
||||
// These are in support of legacy data graph operations.
|
||||
#include "namedNode.h"
|
||||
#include "mouse.h"
|
||||
#include "mouseWatcher.h"
|
||||
#include "trackball.h"
|
||||
#include "transform2sg.h"
|
||||
#include "dataRelation.h"
|
||||
#include "dataGraphTraversal.h"
|
||||
#include "buttonThrower.h"
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "qpbuttonThrower.h"
|
||||
#include "qptrackball.h"
|
||||
#include "qptransform2sg.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "event.h"
|
||||
#include "eventQueue.h"
|
||||
#include "eventHandler.h"
|
||||
#include "qpdataGraphTraverser.h"
|
||||
|
||||
// Use dconfig to read a few Configrc variables.
|
||||
Configure(config_pview);
|
||||
|
|
@ -233,32 +228,32 @@ get_models(PandaNode *parent, int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
NamedNode *
|
||||
setup_mouse(NamedNode *data_root, GraphicsWindow *window) {
|
||||
MouseAndKeyboard *mouse = new MouseAndKeyboard(window, 0);
|
||||
new DataRelation(data_root, mouse);
|
||||
PandaNode *
|
||||
setup_mouse(PandaNode *data_root, GraphicsWindow *window) {
|
||||
qpMouseAndKeyboard *mouse = new qpMouseAndKeyboard(window, 0, "mouse");
|
||||
data_root->add_child(mouse);
|
||||
|
||||
// Create a ButtonThrower to throw events from the keyboard.
|
||||
PT(ButtonThrower) bt = new ButtonThrower("kb-events");
|
||||
PT(qpButtonThrower) bt = new qpButtonThrower("kb-events");
|
||||
ModifierButtons mods;
|
||||
mods.add_button(KeyboardButton::shift());
|
||||
mods.add_button(KeyboardButton::control());
|
||||
mods.add_button(KeyboardButton::alt());
|
||||
bt->set_modifier_buttons(mods);
|
||||
new DataRelation(mouse, bt);
|
||||
mouse->add_child(bt);
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
void
|
||||
setup_trackball(NamedNode *mouse, qpCamera *camera) {
|
||||
PT(Trackball) trackball = new Trackball("trackball");
|
||||
setup_trackball(PandaNode *mouse, qpCamera *camera) {
|
||||
PT(qpTrackball) trackball = new qpTrackball("trackball");
|
||||
trackball->set_pos(LVector3f::forward() * 50.0);
|
||||
new DataRelation(mouse, trackball);
|
||||
mouse->add_child(trackball);
|
||||
|
||||
PT(Transform2SG) tball2cam = new Transform2SG("tball2cam");
|
||||
PT(qpTransform2SG) tball2cam = new qpTransform2SG("tball2cam");
|
||||
tball2cam->set_node(camera);
|
||||
new DataRelation(trackball, tball2cam);
|
||||
trackball->add_child(tball2cam);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -365,11 +360,11 @@ main(int argc, char *argv[]) {
|
|||
// sorting, above, in event_s().
|
||||
CullBinManager::get_global_ptr()->add_bin("unsorted", CullBinManager::BT_unsorted, 0);
|
||||
|
||||
// Set up a data graph for tracking user input. For now, this uses
|
||||
// the old-style graph interface.
|
||||
PT(NamedNode) data_root = new NamedNode("data_root");
|
||||
NamedNode *mouse = setup_mouse(data_root, window);
|
||||
// Set up a data graph for tracking user input.
|
||||
PT(PandaNode) data_root = new PandaNode("data_root");
|
||||
PandaNode *mouse = setup_mouse(data_root, window);
|
||||
setup_trackball(mouse, camera);
|
||||
qpDataGraphTraverser dg_trav;
|
||||
|
||||
// Use an event handler to manage keyboard events.
|
||||
EventHandler event_handler(EventQueue::get_global_event_queue());
|
||||
|
|
@ -401,7 +396,7 @@ main(int argc, char *argv[]) {
|
|||
// This is our main update loop. Loop here until someone
|
||||
// (e.g. event_esc) sets run_flag to false.
|
||||
while (run_flag) {
|
||||
traverse_data_graph(data_root);
|
||||
dg_trav.traverse(data_root);
|
||||
event_handler.process_events();
|
||||
engine->render_frame();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,41 @@
|
|||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
buttonThrower.h config_tform.h dataValve.I dataValve.h \
|
||||
buttonThrower.h \
|
||||
qpbuttonThrower.h \
|
||||
config_tform.h dataValve.I dataValve.h \
|
||||
driveInterface.I driveInterface.h mouseWatcher.I \
|
||||
mouseWatcher.h mouseWatcherGroup.h \
|
||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||
mouseWatcherRegion.I mouseWatcherRegion.h \
|
||||
planarSlider.h trackball.h transform2sg.h
|
||||
planarSlider.h trackball.h \
|
||||
qptrackball.h \
|
||||
transform2sg.h \
|
||||
qptransform2sg.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
buttonThrower.cxx config_tform.cxx dataValve.cxx \
|
||||
buttonThrower.cxx \
|
||||
qpbuttonThrower.cxx \
|
||||
config_tform.cxx dataValve.cxx \
|
||||
driveInterface.cxx mouseWatcher.cxx mouseWatcherGroup.cxx \
|
||||
mouseWatcherParameter.cxx mouseWatcherRegion.cxx \
|
||||
planarSlider.cxx trackball.cxx transform2sg.cxx
|
||||
planarSlider.cxx trackball.cxx \
|
||||
qptrackball.cxx \
|
||||
transform2sg.cxx \
|
||||
qptransform2sg.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
buttonThrower.h dataValve.I dataValve.h \
|
||||
buttonThrower.h \
|
||||
qpbuttonThrower.h \
|
||||
dataValve.I dataValve.h \
|
||||
driveInterface.I driveInterface.h mouseWatcher.I mouseWatcher.h \
|
||||
mouseWatcherGroup.h \
|
||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||
mouseWatcherRegion.I mouseWatcherRegion.h \
|
||||
planarSlider.h trackball.h transform2sg.h
|
||||
planarSlider.h trackball.h \
|
||||
qptrackball.h \
|
||||
transform2sg.h \
|
||||
qptransform2sg.h
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,15 @@
|
|||
#include "dataValve.h"
|
||||
#include "driveInterface.h"
|
||||
#include "buttonThrower.h"
|
||||
#include "qpbuttonThrower.h"
|
||||
#include "mouseWatcher.h"
|
||||
#include "mouseWatcherGroup.h"
|
||||
#include "mouseWatcherRegion.h"
|
||||
#include "planarSlider.h"
|
||||
#include "trackball.h"
|
||||
#include "qptrackball.h"
|
||||
#include "transform2sg.h"
|
||||
#include "qptransform2sg.h"
|
||||
|
||||
#include <dconfig.h>
|
||||
|
||||
|
|
@ -49,10 +52,13 @@ ConfigureFn(config_tform) {
|
|||
DataValve::init_type();
|
||||
DriveInterface::init_type();
|
||||
ButtonThrower::init_type();
|
||||
qpButtonThrower::init_type();
|
||||
MouseWatcher::init_type();
|
||||
MouseWatcherGroup::init_type();
|
||||
MouseWatcherRegion::init_type();
|
||||
PlanarSlider::init_type();
|
||||
Trackball::init_type();
|
||||
qpTrackball::init_type();
|
||||
Transform2SG::init_type();
|
||||
qpTransform2SG::init_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,399 @@
|
|||
// Filename: qpbuttonThrower.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qpbuttonThrower.h"
|
||||
|
||||
#include "buttonEvent.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "dataNodeTransmit.h"
|
||||
#include "throw_event.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle qpButtonThrower::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpButtonThrower::
|
||||
qpButtonThrower(const string &name) :
|
||||
qpDataNode(name)
|
||||
{
|
||||
_button_events_input = define_input("ButtonEvents", ButtonEventList::get_class_type());
|
||||
_button_events_output = define_output("ButtonEvents", ButtonEventList::get_class_type());
|
||||
|
||||
_button_events = new ButtonEventList;
|
||||
|
||||
_throw_buttons_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpButtonThrower::
|
||||
~qpButtonThrower() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::set_prefix
|
||||
// Access: Published
|
||||
// Description: Sets the prefix which is prepended to all event names
|
||||
// thrown by this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
set_prefix(const string &prefix) {
|
||||
_prefix = prefix;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::has_prefix
|
||||
// Access: Published
|
||||
// Description: Returns true if the qpButtonThrower has a prefix set,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
has_prefix() const {
|
||||
return !_prefix.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::get_prefix
|
||||
// Access: Published
|
||||
// Description: Returns the prefix that has been set on this
|
||||
// qpButtonThrower. See set_prefix().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string qpButtonThrower::
|
||||
get_prefix() const {
|
||||
return _prefix;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::get_modifier_buttons
|
||||
// Access: Published
|
||||
// Description: Returns the set of ModifierButtons that the
|
||||
// qpButtonThrower will consider important enough to
|
||||
// prepend the event name with. Normally, this set will
|
||||
// be empty, and the qpButtonThrower will therefore ignore
|
||||
// all ModifierButtons attached to the key events, but
|
||||
// if one or more buttons have been added to this set,
|
||||
// and those modifier buttons are set on the button
|
||||
// event, then the event name will be prepended with the
|
||||
// names of the modifier buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const ModifierButtons &qpButtonThrower::
|
||||
get_modifier_buttons() const {
|
||||
return _mods;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::set_modifier_buttons
|
||||
// Access: Published
|
||||
// Description: Changes the set of ModifierButtons that the
|
||||
// qpButtonThrower will consider important enough to
|
||||
// prepend the event name with. Normally, this set will
|
||||
// be empty, and the qpButtonThrower will therefore ignore
|
||||
// all ModifierButtons attached to the key events, but
|
||||
// if one or more buttons have been added to this set,
|
||||
// then the event name will be prepended with the names
|
||||
// of the modifier buttons.
|
||||
//
|
||||
// It is recommended that you change this setting by
|
||||
// first calling get_modifier_buttons(), making
|
||||
// adjustments, and passing the new value to
|
||||
// set_modifier_buttons(). This way the current state
|
||||
// of the modifier buttons will not be lost.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
set_modifier_buttons(const ModifierButtons &mods) {
|
||||
_mods = mods;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::set_throw_buttons_active
|
||||
// Access: Published
|
||||
// Description: Sets the flag that indicates whether the
|
||||
// qpButtonThrower will only process events for the
|
||||
// explicitly named buttons or not. Normally this is
|
||||
// false, meaning all buttons are processed; set it true
|
||||
// to indicate that only some buttons should be
|
||||
// processed. See add_throw_button().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
set_throw_buttons_active(bool flag) {
|
||||
_throw_buttons_active = flag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::get_throw_buttons_active
|
||||
// Access: Published
|
||||
// Description: Returns the flag that indicates whether the
|
||||
// qpButtonThrower will only process events for the
|
||||
// explicitly named buttons or not. See
|
||||
// set_throw_buttons_active().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
get_throw_buttons_active() const {
|
||||
return _throw_buttons_active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::add_throw_button
|
||||
// Access: Published
|
||||
// Description: Adds a new button to the set of buttons that the
|
||||
// qpButtonThrower explicitly processes.
|
||||
//
|
||||
// If set_throw_buttons_active is false (which is the
|
||||
// default), the qpButtonThrower will process all buttons.
|
||||
// Otherwise, the qpButtonThrower will only process events
|
||||
// for the button(s) explicitly named by this function;
|
||||
// buttons not on the list will be ignored by this
|
||||
// object and passed on downstream to the child node(s)
|
||||
// in the data graph. A button that *is* on the list
|
||||
// will be processed by the qpButtonThrower and not passed
|
||||
// on to the child node(s).
|
||||
//
|
||||
// The return value is true if the button is added, or
|
||||
// false if it was already in the set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
add_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
|
||||
ThrowButtonDef &def = _throw_buttons[button];
|
||||
|
||||
// This is a vector of ModifierButtons for which the indicated
|
||||
// button is handled. Make sure the current ModifierButtons object
|
||||
// is not already on the list.
|
||||
ThrowButtonDef::iterator di;
|
||||
for (di = def.begin(); di != def.end(); ++di) {
|
||||
if (mods.matches(*di)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
def.push_back(mods);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::remove_throw_button
|
||||
// Access: Published
|
||||
// Description: Removes the indicated button from the set of buttons
|
||||
// that the qpButtonThrower explicitly processes. See
|
||||
// add_throw_button().
|
||||
//
|
||||
// The return value is true if the button is removed, or
|
||||
// false if it was not on the set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
remove_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
|
||||
ThrowButtons::iterator ti = _throw_buttons.find(button);
|
||||
if (ti == _throw_buttons.end()) {
|
||||
// No buttons of this kind are in the set.
|
||||
return false;
|
||||
}
|
||||
|
||||
ThrowButtonDef &def = (*ti).second;
|
||||
|
||||
// This is a vector of ModifierButtons for which the indicated
|
||||
// button is handled.
|
||||
ThrowButtonDef::iterator di;
|
||||
for (di = def.begin(); di != def.end(); ++di) {
|
||||
if (mods.matches(*di)) {
|
||||
def.erase(di);
|
||||
if (def.empty()) {
|
||||
_throw_buttons.erase(ti);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The indicated ModifierButtons are not applied to this button in
|
||||
// the set.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::has_throw_button
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated button is on the set of
|
||||
// buttons that will be processed by the qpButtonThrower,
|
||||
// false otherwise. See add_throw_button().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
has_throw_button(const ModifierButtons &mods, const ButtonHandle &button) const {
|
||||
ThrowButtons::const_iterator ti = _throw_buttons.find(button);
|
||||
if (ti == _throw_buttons.end()) {
|
||||
// No buttons of this kind are in the set.
|
||||
return false;
|
||||
}
|
||||
|
||||
const ThrowButtonDef &def = (*ti).second;
|
||||
|
||||
// This is a vector of ModifierButtons for which the indicated
|
||||
// button is handled.
|
||||
ThrowButtonDef::const_iterator di;
|
||||
for (di = def.begin(); di != def.end(); ++di) {
|
||||
if (mods.matches(*di)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The indicated ModifierButtons are not applied to this button in
|
||||
// the set.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::has_throw_button
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated button, in conjunction
|
||||
// with any nonspecified modifier buttons, is on the set
|
||||
// of buttons that will be processed by the
|
||||
// qpButtonThrower. That is to say, returns true if this
|
||||
// button was ever passed as the second parameter
|
||||
// add_throw_button(), regardless of what the first
|
||||
// parameter was.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpButtonThrower::
|
||||
has_throw_button(const ButtonHandle &button) const {
|
||||
ThrowButtons::const_iterator ti = _throw_buttons.find(button);
|
||||
if (ti == _throw_buttons.end()) {
|
||||
// No buttons of this kind are in the set.
|
||||
return false;
|
||||
}
|
||||
|
||||
const ThrowButtonDef &def = (*ti).second;
|
||||
return !def.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::clear_throw_buttons
|
||||
// Access: Published
|
||||
// Description: Empties the set of buttons that were added via
|
||||
// add_throw_button(). See add_throw_button().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
clear_throw_buttons() {
|
||||
_throw_buttons.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::write
|
||||
// Access: Public, Virtual
|
||||
// Description: Throw all events for button events found in the data
|
||||
// element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
write(ostream &out, int indent_level) const {
|
||||
qpDataNode::write(out, indent_level);
|
||||
if (_throw_buttons_active) {
|
||||
indent(out, indent_level)
|
||||
<< "Processing keys:\n";
|
||||
// Write the list of buttons that we're processing too.
|
||||
ThrowButtons::const_iterator ti;
|
||||
for (ti = _throw_buttons.begin(); ti != _throw_buttons.end(); ++ti) {
|
||||
ButtonHandle button = (*ti).first;
|
||||
const ThrowButtonDef &def = (*ti).second;
|
||||
ThrowButtonDef::const_iterator di;
|
||||
for (di = def.begin(); di != def.end(); ++di) {
|
||||
indent(out, indent_level + 2)
|
||||
<< (*di).get_prefix() << button.get_name() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpButtonThrower::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of transmit_data(). This
|
||||
// function receives an array of input parameters and
|
||||
// should generate an array of output parameters. The
|
||||
// input parameters may be accessed with the index
|
||||
// numbers returned by the define_input() calls that
|
||||
// were made earlier (presumably in the constructor);
|
||||
// likewise, the output parameters should be set with
|
||||
// the index numbers returned by the define_output()
|
||||
// calls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpButtonThrower::
|
||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||
// Clear our outgoing button events. We'll fill it up again with
|
||||
// just those events that want to carry on.
|
||||
_button_events->clear();
|
||||
|
||||
if (input.has_data(_button_events_input)) {
|
||||
const ButtonEventList *button_events;
|
||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
||||
|
||||
int num_events = button_events->get_num_events();
|
||||
for (int i = 0; i < num_events; i++) {
|
||||
const ButtonEvent &be = button_events->get_event(i);
|
||||
string event_name = be._button.get_name();
|
||||
|
||||
if (be._type == ButtonEvent::T_down) {
|
||||
// Button down.
|
||||
if (!_mods.button_down(be._button)) {
|
||||
// We only prepend modifier names on the button-down events,
|
||||
// and only for buttons which are not themselves modifiers.
|
||||
event_name = _mods.get_prefix() + event_name;
|
||||
}
|
||||
|
||||
if (!_throw_buttons_active || has_throw_button(_mods, be._button)) {
|
||||
// Process this button.
|
||||
throw_event(_prefix + event_name);
|
||||
|
||||
} else {
|
||||
// Don't process this button; instead, pass it down to future
|
||||
// generations.
|
||||
_button_events->add_event(be);
|
||||
}
|
||||
|
||||
} else if (be._type == ButtonEvent::T_up) {
|
||||
// Button up.
|
||||
_mods.button_up(be._button);
|
||||
|
||||
// We always throw button "up" events if we have any
|
||||
// definition for the button at all, regardless of the state
|
||||
// of the modifier keys.
|
||||
if (!_throw_buttons_active || has_throw_button(be._button)) {
|
||||
throw_event(_prefix + event_name + "-up");
|
||||
}
|
||||
if (_throw_buttons_active) {
|
||||
// Now pass the event on to future generations. We always
|
||||
// pass "up" events, even if we are intercepting this
|
||||
// particular button; unless we're processing all buttons in
|
||||
// which case it doesn't matter.
|
||||
_button_events->add_event(be);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Some other kind of button event (e.g. keypress). Don't
|
||||
// throw an event for this, but do pass it down.
|
||||
_button_events->add_event(be);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
// Filename: qpbuttonThrower.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpBUTTONTHROWER_H
|
||||
#define qpBUTTONTHROWER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "qpdataNode.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpButtonThrower
|
||||
// Description : Throws Panda Events for button down/up events
|
||||
// generated within the data graph.
|
||||
//
|
||||
// This is a DataNode which is intended to be parented
|
||||
// to the data graph below a device which is generating
|
||||
// a sequence of button events, like a MouseAndKeyboard
|
||||
// device. It simply takes each button it finds and
|
||||
// throws a corresponding event based on the button name
|
||||
// via the throw_event() call.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpButtonThrower : public qpDataNode {
|
||||
PUBLISHED:
|
||||
qpButtonThrower(const string &name);
|
||||
~qpButtonThrower();
|
||||
|
||||
void set_prefix(const string &prefix);
|
||||
bool has_prefix() const;
|
||||
string get_prefix() const;
|
||||
|
||||
const ModifierButtons &get_modifier_buttons() const;
|
||||
void set_modifier_buttons(const ModifierButtons &mods);
|
||||
|
||||
void set_throw_buttons_active(bool flag);
|
||||
bool get_throw_buttons_active() const;
|
||||
|
||||
bool add_throw_button(const ModifierButtons &mods, const ButtonHandle &button);
|
||||
bool remove_throw_button(const ModifierButtons &mods, const ButtonHandle &button);
|
||||
bool has_throw_button(const ModifierButtons &mods, const ButtonHandle &button) const;
|
||||
bool has_throw_button(const ButtonHandle &button) const;
|
||||
void clear_throw_buttons();
|
||||
|
||||
public:
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
string _prefix;
|
||||
ModifierButtons _mods;
|
||||
|
||||
typedef pvector<ModifierButtons> ThrowButtonDef;
|
||||
typedef pmap<ButtonHandle, ThrowButtonDef> ThrowButtons;
|
||||
ThrowButtons _throw_buttons;
|
||||
bool _throw_buttons_active;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
DataNodeTransmit &output);
|
||||
|
||||
private:
|
||||
// inputs
|
||||
int _button_events_input;
|
||||
|
||||
// outputs
|
||||
int _button_events_output;
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpDataNode::init_type();
|
||||
register_type(_type_handle, "qpButtonThrower",
|
||||
qpDataNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,530 @@
|
|||
// Filename: qptrackball.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qptrackball.h"
|
||||
#include "buttonEvent.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "dataNodeTransmit.h"
|
||||
#include "compose_matrix.h"
|
||||
#include "mouseData.h"
|
||||
#include "modifierButtons.h"
|
||||
|
||||
TypeHandle qpTrackball::_type_handle;
|
||||
|
||||
// These are used internally.
|
||||
#define B1_MASK 0x1
|
||||
#define B2_MASK 0x2
|
||||
#define B3_MASK 0x4
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpTrackball::
|
||||
qpTrackball(const string &name) :
|
||||
qpDataNode(name)
|
||||
{
|
||||
_pixel_xy_input = define_input("PixelXY", EventStoreVec2::get_class_type());
|
||||
_button_events_input = define_input("ButtonEvents", ButtonEventList::get_class_type());
|
||||
|
||||
_transform_output = define_output("Transform", EventStoreMat4::get_class_type());
|
||||
|
||||
_transform = new EventStoreMat4(LMatrix4f::ident_mat());
|
||||
|
||||
_rotscale = 0.3f;
|
||||
_fwdscale = 0.3f;
|
||||
|
||||
_lastx = _lasty = 0.5f;
|
||||
|
||||
_rotation = LMatrix4f::ident_mat();
|
||||
_translation.set(0.0f, 0.0f, 0.0f);
|
||||
_mat = LMatrix4f::ident_mat();
|
||||
_orig = LMatrix4f::ident_mat();
|
||||
_invert = true;
|
||||
_cs = default_coordinate_system;
|
||||
|
||||
_mods.add_button(MouseButton::one());
|
||||
_mods.add_button(MouseButton::two());
|
||||
_mods.add_button(MouseButton::three());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::Destructor
|
||||
// Access: Public, Scheme
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpTrackball::
|
||||
~qpTrackball() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::reset
|
||||
// Access: Public, Scheme
|
||||
// Description: Reinitializes all transforms to identity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
reset() {
|
||||
_rotation = LMatrix4f::ident_mat();
|
||||
_translation.set(0.0f, 0.0f, 0.0f);
|
||||
_orig = LMatrix4f::ident_mat();
|
||||
_mat = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_pos
|
||||
// Access: Public, Scheme
|
||||
// Description: Return the offset from the center of rotation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LPoint3f &qpTrackball::
|
||||
get_pos() const {
|
||||
return _translation;
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_x() const {
|
||||
return _translation[0];
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_y() const {
|
||||
return _translation[1];
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_z() const {
|
||||
return _translation[2];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_pos
|
||||
// Access: Public, Scheme
|
||||
// Description: Directly set the offset from the rotational origin.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_pos(const LVecBase3f &vec) {
|
||||
_translation = vec;
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_pos(float x, float y, float z) {
|
||||
_translation.set(x, y, z);
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_x(float x) {
|
||||
_translation[0] = x;
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_y(float y) {
|
||||
_translation[1] = y;
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_z(float z) {
|
||||
_translation[2] = z;
|
||||
recompute();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_hpr
|
||||
// Access: Public, Scheme
|
||||
// Description: Return the trackball's orientation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVecBase3f qpTrackball::
|
||||
get_hpr() const {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
return hpr;
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_h() const {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
return hpr[0];
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_p() const {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
return hpr[1];
|
||||
}
|
||||
|
||||
float qpTrackball::
|
||||
get_r() const {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
return hpr[2];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_hpr
|
||||
// Access: Public, Scheme
|
||||
// Description: Directly set the mover's orientation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_hpr(const LVecBase3f &hpr) {
|
||||
LVecBase3f scale, old_hpr, translate;
|
||||
decompose_matrix(_rotation, scale, old_hpr, translate);
|
||||
compose_matrix(_rotation, scale, hpr, translate);
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_hpr(float h, float p, float r) {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
hpr.set(h, p, r);
|
||||
compose_matrix(_rotation, scale, hpr, translate);
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_h(float h) {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
hpr[0] = h;
|
||||
compose_matrix(_rotation, scale, hpr, translate);
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_p(float p) {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
hpr[1] = p;
|
||||
compose_matrix(_rotation, scale, hpr, translate);
|
||||
recompute();
|
||||
}
|
||||
|
||||
void qpTrackball::
|
||||
set_r(float r) {
|
||||
LVecBase3f scale, hpr, translate;
|
||||
decompose_matrix(_rotation, scale, hpr, translate);
|
||||
hpr[2] = r;
|
||||
compose_matrix(_rotation, scale, hpr, translate);
|
||||
recompute();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::reset_origin_here
|
||||
// Access: Public, Scheme
|
||||
// Description: Reposition the center of rotation to coincide with
|
||||
// the current translation offset. Future rotations
|
||||
// will be about the current origin.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
reset_origin_here() {
|
||||
recompute();
|
||||
_rotation = _orig;
|
||||
_translation.set(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::move_origin
|
||||
// Access: Public, Scheme
|
||||
// Description: Moves the center of rotation by the given amount.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
move_origin(float x, float y, float z) {
|
||||
_rotation = LMatrix4f::translate_mat(LVecBase3f(x, y, z)) * _rotation;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_invert
|
||||
// Access: Public, Scheme
|
||||
// Description: Sets the invert flag. When this is set, the inverse
|
||||
// matrix is generated, suitable for joining to a
|
||||
// camera, instead of parenting the scene under it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_invert(bool flag) {
|
||||
_invert = flag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_invert
|
||||
// Access: Public, Scheme
|
||||
// Description: Returns the invert flag. When this is set, the
|
||||
// inverse matrix is generated, suitable for joining to
|
||||
// a camera, instead of parenting the scene under it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpTrackball::
|
||||
get_invert() const {
|
||||
return _invert;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_rel_to
|
||||
// Access: Public, Scheme
|
||||
// Description: Sets the NodePath that all trackball manipulations
|
||||
// are to be assumed to be relative to. For instance,
|
||||
// set your camera node here to make the trackball
|
||||
// motion camera relative. The default is the empty
|
||||
// path, which means trackball motion is in global
|
||||
// space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_rel_to(const qpNodePath &rel_to) {
|
||||
_rel_to = rel_to;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_rel_to
|
||||
// Access: Public, Scheme
|
||||
// Description: Returns the NodePath that all trackball manipulations
|
||||
// are relative to, or the empty path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpNodePath &qpTrackball::
|
||||
get_rel_to() const {
|
||||
return _rel_to;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_coordinate_system
|
||||
// Access: Public, Scheme
|
||||
// Description: Sets the coordinate system of the Trackball.
|
||||
// Normally, this is the default coordinate system.
|
||||
// This changes the axes the Trackball manipulates so
|
||||
// that the user interface remains consistent across
|
||||
// different coordinate systems.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_coordinate_system(CoordinateSystem cs) {
|
||||
_cs = cs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_coordinate_system
|
||||
// Access: Public, Scheme
|
||||
// Description: Returns the coordinate system of the Trackball.
|
||||
// See set_coordinate_system().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CoordinateSystem qpTrackball::
|
||||
get_coordinate_system() const {
|
||||
return _cs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::set_mat
|
||||
// Access: Public, Scheme
|
||||
// Description: Stores the indicated transform in the trackball.
|
||||
// This is a transform in global space, regardless of
|
||||
// the rel_to node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
set_mat(const LMatrix4f &mat) {
|
||||
_orig = mat;
|
||||
if (_invert) {
|
||||
_mat = invert(_orig);
|
||||
} else {
|
||||
_mat = _orig;
|
||||
}
|
||||
|
||||
reextract();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_mat
|
||||
// Access: Public, Scheme
|
||||
// Description: Returns the matrix represented by the trackball
|
||||
// rotation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &qpTrackball::
|
||||
get_mat() const {
|
||||
return _orig;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::get_trans_mat
|
||||
// Access: Public, Scheme
|
||||
// Description: Returns the actual transform that will be applied to
|
||||
// the scene graph. This is the same as get_mat(),
|
||||
// unless invert is in effect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &qpTrackball::
|
||||
get_trans_mat() const {
|
||||
return _mat;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::apply
|
||||
// Access: Private
|
||||
// Description: Applies the operation indicated by the user's mouse
|
||||
// motion to the current state. Returns the matrix
|
||||
// indicating the new state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
apply(double x, double y, int button) {
|
||||
if (button && !_rel_to.is_empty()) {
|
||||
// If we have a rel_to node, we must first adjust our rotation and
|
||||
// translation to be in those local coordinates.
|
||||
reextract();
|
||||
}
|
||||
if (button == B1_MASK) {
|
||||
// Button 1: translate in plane parallel to screen.
|
||||
|
||||
_translation +=
|
||||
x * _fwdscale * LVector3f::right(_cs) +
|
||||
y * _fwdscale * LVector3f::down(_cs);
|
||||
|
||||
} else if (button == (B2_MASK | B3_MASK)) {
|
||||
// Buttons 2 + 3: rotate about the vector perpendicular to the
|
||||
// screen.
|
||||
|
||||
_rotation *=
|
||||
LMatrix4f::rotate_mat_normaxis((x - y) * _rotscale,
|
||||
LVector3f::forward(_cs), _cs);
|
||||
|
||||
} else if ((button == B2_MASK) || (button == (B1_MASK | B3_MASK))) {
|
||||
// Button 2, or buttons 1 + 3: rotate about the right and up
|
||||
// vectors. (We alternately define this as buttons 1 + 3, to
|
||||
// support two-button mice.)
|
||||
|
||||
_rotation *=
|
||||
LMatrix4f::rotate_mat_normaxis(x * _rotscale, LVector3f::up(_cs), _cs) *
|
||||
LMatrix4f::rotate_mat_normaxis(y * _rotscale, LVector3f::right(_cs), _cs);
|
||||
|
||||
} else if ((button == B3_MASK) || (button == (B1_MASK | B2_MASK))) {
|
||||
// Button 3, or buttons 1 + 2: dolly in and out along the forward
|
||||
// vector. (We alternately define this as buttons 1 + 2, to
|
||||
// support two-button mice.)
|
||||
_translation -= y * _fwdscale * LVector3f::forward(_cs);
|
||||
}
|
||||
|
||||
if (button) {
|
||||
recompute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::reextract
|
||||
// Access: Private
|
||||
// Description: Given a correctly computed _orig matrix, rederive the
|
||||
// translation and rotation elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
reextract() {
|
||||
LMatrix4f m = _orig;
|
||||
if (!_rel_to.is_empty()) {
|
||||
qpNodePath root;
|
||||
const LMatrix4f &rel_mat = root.get_mat(_rel_to);
|
||||
m = _orig * rel_mat;
|
||||
}
|
||||
|
||||
m.get_row3(_translation,3);
|
||||
_rotation = m;
|
||||
_rotation.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::recompute
|
||||
// Access: Private
|
||||
// Description: Rebuilds the matrix according to the stored rotation
|
||||
// and translation components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
recompute() {
|
||||
_orig = _rotation * LMatrix4f::translate_mat(_translation);
|
||||
|
||||
if (!_rel_to.is_empty()) {
|
||||
qpNodePath root;
|
||||
const LMatrix4f &rel_mat = _rel_to.get_mat(root);
|
||||
_orig = _orig * rel_mat;
|
||||
}
|
||||
|
||||
if (_invert) {
|
||||
_mat = invert(_orig);
|
||||
} else {
|
||||
_mat = _orig;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTrackball::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of transmit_data(). This
|
||||
// function receives an array of input parameters and
|
||||
// should generate an array of output parameters. The
|
||||
// input parameters may be accessed with the index
|
||||
// numbers returned by the define_input() calls that
|
||||
// were made earlier (presumably in the constructor);
|
||||
// likewise, the output parameters should be set with
|
||||
// the index numbers returned by the define_output()
|
||||
// calls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTrackball::
|
||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||
// First, update our modifier buttons.
|
||||
if (input.has_data(_button_events_input)) {
|
||||
const ButtonEventList *button_events;
|
||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
||||
button_events->update_mods(_mods);
|
||||
}
|
||||
|
||||
// Now, check for mouse motion.
|
||||
if (input.has_data(_pixel_xy_input)) {
|
||||
const EventStoreVec2 *pixel_xy;
|
||||
DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
|
||||
const LVecBase2f &p = pixel_xy->get_value();
|
||||
float this_x = p[0];
|
||||
float this_y = p[1];
|
||||
int this_button = 0;
|
||||
|
||||
if (_mods.is_down(MouseButton::one())) {
|
||||
this_button |= B1_MASK;
|
||||
}
|
||||
if (_mods.is_down(MouseButton::two())) {
|
||||
this_button |= B2_MASK;
|
||||
}
|
||||
if (_mods.is_down(MouseButton::three())) {
|
||||
this_button |= B3_MASK;
|
||||
}
|
||||
|
||||
float x = this_x - _lastx;
|
||||
float y = this_y - _lasty;
|
||||
|
||||
apply(x, y, this_button);
|
||||
|
||||
_lastx = this_x;
|
||||
_lasty = this_y;
|
||||
}
|
||||
|
||||
// Now send our matrix down the pipe.
|
||||
_transform->set_value(_mat);
|
||||
output.set_data(_transform_output, EventParameter(_transform));
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
// Filename: qptrackball.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpTRACKBALL_H
|
||||
#define qpTRACKBALL_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "qpdataNode.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "luse.h"
|
||||
#include "linmath_events.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpTrackball
|
||||
// Description : Trackball acts like Performer in trackball mode. It
|
||||
// can either spin around a piece of geometry directly,
|
||||
// or it can spin around a camera with the inverse
|
||||
// transform to make it appear that the whole world is
|
||||
// spinning.
|
||||
//
|
||||
// The Trackball object actually just places a transform
|
||||
// in the data graph; parent a Transform2SG node under
|
||||
// it to actually transform objects (or cameras) in the
|
||||
// world.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpTrackball : public qpDataNode {
|
||||
PUBLISHED:
|
||||
qpTrackball(const string &name);
|
||||
~qpTrackball();
|
||||
|
||||
void reset();
|
||||
|
||||
/// **** Translation ****
|
||||
|
||||
const LPoint3f &get_pos() const;
|
||||
float get_x() const;
|
||||
float get_y() const;
|
||||
float get_z() const;
|
||||
void set_pos(const LVecBase3f &vec);
|
||||
void set_pos(float x, float y, float z);
|
||||
void set_x(float x);
|
||||
void set_y(float y);
|
||||
void set_z(float z);
|
||||
|
||||
/// **** Rotation ****
|
||||
|
||||
LVecBase3f get_hpr() const;
|
||||
float get_h() const;
|
||||
float get_p() const;
|
||||
float get_r() const;
|
||||
void set_hpr(const LVecBase3f &hpr);
|
||||
void set_hpr(float h, float p, float r);
|
||||
void set_h(float h);
|
||||
void set_p(float p);
|
||||
void set_r(float r);
|
||||
|
||||
/// **** Origin of Rotation ****
|
||||
|
||||
void reset_origin_here();
|
||||
void move_origin(float x, float y, float z);
|
||||
|
||||
/// **** Misc ****
|
||||
|
||||
void set_invert(bool flag);
|
||||
bool get_invert() const;
|
||||
|
||||
void set_rel_to(const qpNodePath &_rel_to);
|
||||
const qpNodePath &get_rel_to() const;
|
||||
|
||||
void set_coordinate_system(CoordinateSystem cs);
|
||||
CoordinateSystem get_coordinate_system() const;
|
||||
|
||||
void set_mat(const LMatrix4f &mat);
|
||||
const LMatrix4f &get_mat() const;
|
||||
const LMatrix4f &get_trans_mat() const;
|
||||
|
||||
|
||||
private:
|
||||
void apply(double x, double y, int button);
|
||||
|
||||
void reextract();
|
||||
void recompute();
|
||||
|
||||
|
||||
float _lastx, _lasty;
|
||||
|
||||
float _rotscale;
|
||||
float _fwdscale;
|
||||
|
||||
LMatrix4f _rotation;
|
||||
LPoint3f _translation;
|
||||
LMatrix4f _mat, _orig;
|
||||
bool _invert;
|
||||
qpNodePath _rel_to;
|
||||
CoordinateSystem _cs;
|
||||
|
||||
// Remember which mouse buttons are being held down.
|
||||
ModifierButtons _mods;
|
||||
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
DataNodeTransmit &output);
|
||||
|
||||
private:
|
||||
// inputs
|
||||
int _pixel_xy_input;
|
||||
int _button_events_input;
|
||||
|
||||
// outputs
|
||||
int _transform_output;
|
||||
|
||||
PT(EventStoreMat4) _transform;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpDataNode::init_type();
|
||||
register_type(_type_handle, "qpTrackball",
|
||||
qpDataNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// Filename: qptransform2sg.cxx
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qptransform2sg.h"
|
||||
#include "transformState.h"
|
||||
|
||||
|
||||
TypeHandle qpTransform2SG::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTransform2SG::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpTransform2SG::
|
||||
qpTransform2SG(const string &name) :
|
||||
qpDataNode(name)
|
||||
{
|
||||
_transform_input = define_input("Transform", EventStoreMat4::get_class_type());
|
||||
|
||||
_node = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTransform2SG::set_node
|
||||
// Access: Public
|
||||
// Description: Sets the node that this node will adjust.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTransform2SG::
|
||||
set_node(PandaNode *node) {
|
||||
_node = node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTransform2SG::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the node that this node will adjust, or NULL
|
||||
// if the node has not yet been set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *qpTransform2SG::
|
||||
get_node() const {
|
||||
return _node;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpTransform2SG::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of transmit_data(). This
|
||||
// function receives an array of input parameters and
|
||||
// should generate an array of output parameters. The
|
||||
// input parameters may be accessed with the index
|
||||
// numbers returned by the define_input() calls that
|
||||
// were made earlier (presumably in the constructor);
|
||||
// likewise, the output parameters should be set with
|
||||
// the index numbers returned by the define_output()
|
||||
// calls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpTransform2SG::
|
||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &) {
|
||||
if (input.has_data(_transform_input)) {
|
||||
const EventStoreMat4 *transform;
|
||||
DCAST_INTO_V(transform, input.get_data(_transform_input).get_ptr());
|
||||
const LMatrix4f &mat = transform->get_value();
|
||||
if (_node != (PandaNode *)NULL) {
|
||||
_node->set_transform(TransformState::make_mat(mat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Filename: qptransform2sg.h
|
||||
// Created by: drose (12Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpTRANSFORM2SG_H
|
||||
#define qpTRANSFORM2SG_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "qpdataNode.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpTransform2SG
|
||||
// Description : input: Transform (matrix)
|
||||
//
|
||||
// output: none, but applies the matrix as the transform
|
||||
// transition for a given arc of the scene graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpTransform2SG : public qpDataNode {
|
||||
PUBLISHED:
|
||||
qpTransform2SG(const string &name);
|
||||
|
||||
void set_node(PandaNode *node);
|
||||
PandaNode *get_node() const;
|
||||
|
||||
private:
|
||||
PandaNode *_node;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
DataNodeTransmit &output);
|
||||
|
||||
private:
|
||||
// inputs
|
||||
int _transform_input;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpDataNode::init_type();
|
||||
register_type(_type_handle, "qpTransform2SG",
|
||||
qpDataNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include "buttonThrower.cxx"
|
||||
#include "qpbuttonThrower.cxx"
|
||||
#include "config_tform.cxx"
|
||||
#include "dataValve.cxx"
|
||||
#include "driveInterface.cxx"
|
||||
|
|
|
|||
|
|
@ -4,5 +4,7 @@
|
|||
#include "mouseWatcherParameter.cxx"
|
||||
#include "mouseWatcherRegion.cxx"
|
||||
#include "trackball.cxx"
|
||||
#include "qptrackball.cxx"
|
||||
#include "transform2sg.cxx"
|
||||
#include "qptransform2sg.cxx"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue