-
首页
-
C4D R23.110 C++ SDK
CTrack
Manual
内容表
关于
A
CTrack
represents an animation track of a parameter of an object in
Cinema 4D
. The tracks are stored with the animated object and contain curves and keys.
CTrack
objects are an instance of
CTbase
.
// This example creates a track for the "Camera" parameter of the given Stage object.
// Two keyframes for the given two camera objects are created.
const
DescLevel
trackID =
DescLevel
(
STAGEOBJECT_CLINK
,
DTYPE_BASELISTLINK
, 0);
// search for the track and create a new one if needed
CTrack
* track = stage->
FindCTrack
(trackID);
if
(track ==
nullptr
)
{
track =
CTrack::Alloc
(stage, trackID);
if
(track ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
// add track to stage object
stage->InsertTrackSorted(track);
}
CCurve
*
const
curve = track->
GetCurve
();
if
(curve ==
nullptr
)
return
maxon::UnexpectedError(
MAXON_SOURCE_LOCATION
);
// Create first key
CKey
*
const
key1 = curve->
AddKey
(
BaseTime
(0.0));
if
(key1 ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
MAXON_SCOPE
{
GeData
data;
data.
SetBaseList2D
(camera1);
key1->
SetGeData
(curve, data);
}
// Create second key
CKey
*
const
key2 = curve->
AddKey
(
BaseTime
(1.0));
if
(key2 ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
MAXON_SCOPE
{
GeData
data;
data.
SetBaseList2D
(camera2);
key2->
SetGeData
(curve, data);
}
Access
The animation tracks of an object's parameters are stored with the object itself:
-
注意
-
The keyframe selection is defined with the
BaseList2D
class, see
BaseList2D Manual
.
// This snippet loops through all animation tracks of the given object.
const
CTrack
* track = obj->
GetFirstCTrack
();
while
(track !=
nullptr
)
{
ApplicationOutput
(
"Track: "
+ track->
GetName
());
track = track->
GetNext
();
}
Allocation/Deallocation
A
CTrack
can be created with the usual tools:
A newly created
CTrack
must be added to a host object:
// This example checks if an animation track for the position X parameter
// exists in the given object. If not, the track will be created.
const
DescLevel
relPosLevel =
DescLevel
(
ID_BASEOBJECT_REL_POSITION
,
DTYPE_VECTOR
, 0);
const
DescLevel
vectorXLevel =
DescLevel
(
VECTOR_X
,
DTYPE_REAL
, 0);
const
DescID
id
=
DescID
(relPosLevel, vectorXLevel);
CTrack
* track = obj->
FindCTrack
(
id
);
if
(track ==
nullptr
)
{
track =
CTrack::Alloc
(obj,
id
);
if
(track ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
track->
SetName
(
"My New Animation Track"
_s);
obj->InsertTrackSorted(track);
}
To create special tracks the ID of that special track must be used. The special tracks are:
// This example adds a sound track to the given object
// and sets the referenced sound file.
const
DescLevel
soundTrackID =
DescLevel
(
CTsound
,
CTsound
, 0);
CTrack
*
const
soundTrack =
CTrack::Alloc
(obj, soundTrackID);
if
(soundTrack ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
soundTrack->
SetParameter
(
CID_SOUND_NAME
, soundFile,
DESCFLAGS_SET::NONE
);
soundTrack->
SetName
(
"New Sound Track"
_s);
obj->InsertTrackSorted(soundTrack);
// This example adds a PLA track to the polygon object.
const
DescID
plaID =
DescLevel
(
CTpla
,
CTpla
, 0);
CTrack
*
const
plaTrack =
CTrack::Alloc
(polyObject, plaID);
if
(plaTrack ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
polyObject->
InsertTrackSorted
(plaTrack);
CCurve
* curve = plaTrack->
GetCurve
();
if
(curve ==
nullptr
)
return
maxon::UnexpectedError(
MAXON_SOURCE_LOCATION
);
// set first key
CKey
*
const
key1 = curve->
AddKey
(
BaseTime
(0.0));
if
(key1 ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
plaTrack->
FillKey
(doc, polyObject, key1);
// change polygon object randomly
Random
random;
for
(
Int32
i = 0; i < count; ++i)
points[i] = points[i] +
向量
(0, 100.0 * random.
Get01
(), 0.0);
polyObject->
消息
(
MSG_UPDATE
);
// set second key
CKey
*
const
key2 = curve->
AddKey
(
BaseTime
(1.0));
if
(key2 ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
plaTrack->
FillKey
(doc, polyObject, key2);
导航
CTrack
objects are stored in a list:
// This snippet loops through all animation tracks of the given object.
const
CTrack
* track = obj->
GetFirstCTrack
();
while
(track !=
nullptr
)
{
ApplicationOutput
(
"Track: "
+ track->
GetName
());
track = track->
GetNext
();
}
-
注意
-
The
GeListHead
object that is the parent of the tracks can be obtained with
BaseList2D::GetCTrackRoot()
.
Read-Only Properties
Several values can be read from a
CTrack
:
The track categories are:
// This example checks if the given track is a "value" track.
// If so, the current value is printed to the console.
// check if the track is "value" track (float)
if
(track->
GetTrackCategory
() ==
CTRACK_CATEGORY_VALUE
)
{
const
BaseTime
now = doc->
GetTime
();
const
Float
value = track->
GetValue
(doc, now);
ApplicationOutput
(
"Value: "
+
String::FloatToString
(value));
}
另请参阅
CKey
值
.
特性
参数
The parameters of a track can be edited as usual with
C4DAtom::SetParameter()
and
C4DAtom::GetParameter()
. The parameter IDs are defined in
ctbase.h
.
// This example sets the color to display the track's f-curve:
track->
SetParameter
(
ID_CTRACK_USE_PREF
,
false
,
DESCFLAGS_SET::NONE
);
const
向量
red { 1.0, 0, 0 };
track->
SetParameter
(
ID_CTRACK_FCURVE_COLOR
,
GeData
{ red },
DESCFLAGS_SET::NONE
);
Selection
在
Cinema 4D
there can be up to four timeline windows. An animation track can be selected in one or multiple of these windows. The selection state is stored as a bit:
// This example selects the given track if it does not contain any keys.
const
CCurve
*
const
curve = track->
GetCurve
();
if
(curve)
{
const
Int32
keyCount = curve->
GetKeyCount
();
if
(keyCount == 0)
track->
ChangeNBit
(
NBIT::TL1_SELECT
,
NBITCONTROL::SET
);
else
track->
ChangeNBit
(
NBIT::TL1_SELECT
,
NBITCONTROL::CLEAR
);
}
另请参阅
CKey
Selection
.
Description ID
The parameter animated using a certain track is defined with its
DescID
. This
DescID
can be accessed:
// This example clones a track and sets the new description ID of that clone.
const
DescLevel
relPosLevel(
ID_BASEOBJECT_REL_POSITION
,
DTYPE_VECTOR
, 0);
const
DescLevel
vectorXLevel(
VECTOR_X
,
DTYPE_REAL
, 0);
const
DescID
ID =
DescID
(relPosLevel, vectorXLevel);
// find track
CTrack
*
const
track = obj->
FindCTrack
(ID);
if
(track ==
nullptr
)
return
maxon::IllegalArgumentError(
MAXON_SOURCE_LOCATION
);
// get track root
GeListHead
*
const
trackRoot = obj->GetCTrackRoot();
if
(trackRoot ==
nullptr
)
return
maxon::UnexpectedError(
MAXON_SOURCE_LOCATION
);
// clone track
CTrack
*
const
clone =
static_cast<
CTrack
*
>
(track->
GetClone
(
COPYFLAGS::NONE
,
nullptr
));
if
(clone ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
// insert and set new ID
const
DescLevel
vectorYLevel(
VECTOR_Y
,
DTYPE_REAL
, 0);
const
DescID
targetID =
DescID
(relPosLevel, vectorYLevel);
trackRoot->
InsertLast
(clone);
clone->
SetDescriptionID
(obj, targetID);
Loop Settings
The loop settings define how an animation track should behave before the first key and after the last key.
The loop types are:
// This example defines the loop settings of the given track.
track->
SetBefore
(
CLOOP::CONSTANT
);
track->
SetAfter
(
CLOOP::OFFSETREPEAT
);
Points in time beyond the defined animation track can be mapped into time inside the track.
-
CTrack::Remap()
: Remaps the given time into a position inside the animation track.
// This example calculates the remapped time for each given time in seconds.
// loop from 0.0 to 1.0
for
(
Float64
t = 0.0; t < 10.0; t = t + 0.1)
{
Float64
remapTime;
Int32
cycle;
track->
Remap
(t, &remapTime, &cycle);
ApplicationOutput
(
"Remap Time: "
+
String::FloatToString
(remapTime));
}
Time Track
The behavior of an animation track depends on the current time which is typically the current time of the
BaseDocument
. But the time that controls a track can be also defined with a time track.
// This example applies the found time track to all other tracks.
// serach for time track
CTrack
*
const
timeTrack = obj->
FindCTrack
(
CTtime
);
if
(timeTrack ==
nullptr
)
return
maxon::IllegalArgumentError(
MAXON_SOURCE_LOCATION
);
// apply time track to other tracks
CTrack
* track = obj->
GetFirstCTrack
();
while
(track !=
nullptr
)
{
const
DescID
id
= track->
GetDescriptionID
();
// check if the track is not a "Time" track
if
(
id
[0].
id
!=
CTtime
)
track->
SetTimeTrack
(timeTrack);
track = track->
GetNext
();
}
Timeline Height
An animation track can be displayed in a Timeline window.
Track Information
An animation track can provide additional information for each key or the current time in form of a
String
.
// This example prints the information for each key of the track.
CKey
*
const
key = curve->
GetKey
(i);
if
(key ==
nullptr
)
return
maxon::UnexpectedError(
MAXON_SOURCE_LOCATION
);
String
info;
track->
TrackInformation
(doc, key, &info,
false
);
ApplicationOutput
(info);
Synchronisation
Multiple tracks can be synchronized. Typically this applies to tracks of the components of a
向量
参数。
Functionality
Since a track might be displayed in the GUI (Timeline window) it can draw an image:
// This example calls the "Draw" function of the given sound track
// and displays the result image.
AutoAlloc<GeClipMap>
clipMap;
if
(clipMap ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
if
(clipMap->
Init
(400, 100, 32) !=
IMAGERESULT::OK
)
return
maxon::UnknownError(
MAXON_SOURCE_LOCATION
);
clipMap->
BeginDraw
();
soundTrack->
Draw
(clipMap,
BaseTime
(0),
BaseTime
(1.0));
clipMap->
EndDraw
();
ShowBitmap
(clipMap->
GetBitmap
());
Further utility functions are:
// This eample accesses the CCurve from the given animation track.
CCurve
*
const
curve = track->
GetCurve
();
if
(curve)
{
// do something with the curve
}
另请参阅
CCurve Manual
.
延伸阅读
static String FloatToString(Float32 v, Int32 vvk=-1, Int32 nnk=-3)
定义:
c4d_string.h:529
@ ID_CTRACK_FCURVE_COLOR
定义:
ctbase.h:10
@ OK
Image loaded/created.
static CTrack * Alloc(BaseList2D *bl, const DescID &id)
IMAGERESULT Init(Int32 w, Int32 h, Int32 bits)
C4DAtom * GetClone(COPYFLAGS flags, AliasTrans *trn)
定义:
c4d_baselist.h:1417
定义:
lib_description.h:327
Bool ChangeNBit(NBIT bit, NBITCONTROL bitmode)
const CKey * GetKey(Int32 index) const
定义:
c4d_canimation.h:377
@ VECTOR_X
X component.
定义:
lib_description.h:267
@ ID_BASEOBJECT_REL_POSITION
定义:
obase.h:12
maxon::Float Float
定义:
ge_sys_math.h:64
@ DTYPE_BASELISTLINK
BaseLink.
定义:
lib_description.h:74
void SetTimeTrack(CTrack *track)
定义:
c4d_canimation.h:758
void SetAfter(CLOOP type)
定义:
c4d_canimation.h:740
const DescID & GetDescriptionID() const
定义:
c4d_canimation.h:703
void InsertTrackSorted(CTrack *track)
#define MAXON_SOURCE_LOCATION
定义:
memoryallocationbase.h:66
#define CTtime
Time.
定义:
ge_prepass.h:1320
CTrack * FindCTrack(const DescID &id)
CKey * AddKey(const BaseTime &time, Int32 *nidx=nullptr, Bool bUndo=false, Bool SynchronizeKeys=false)
定义:
c4d_canimation.h:412
@ STAGEOBJECT_CLINK
定义:
ostage.h:6
void SetBefore(CLOOP type)
定义:
c4d_canimation.h:728
Float GetValue(BaseDocument *doc, const BaseTime &time)
定义:
c4d_canimation.h:825
#define CTpla
PLA.
定义:
ge_prepass.h:1317
void BeginDraw()
Must be called before any drawing functions.
#define MSG_UPDATE
Must be sent if the bounding box has to be recalculated. (Otherwise use MSG_CHANGE....
定义:
c4d_baselist.h:340
Bool FillKey(BaseDocument *doc, BaseList2D *bl, CKey *key)
定义:
c4d_canimation.h:791
@ OFFSETREPEAT
Offset repeat.
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
CTrack * GetNext() const
定义:
c4d_canimation.h:686
BaseTime GetTime(void) const
@ DTYPE_VECTOR
向量
定义:
lib_description.h:70
@ VECTOR_Y
Y component.
定义:
lib_description.h:268
Represents a level within a DescID.
定义:
lib_description.h:286
@ CID_SOUND_NAME
定义:
ctsound.h:7
void SetGeData(CCurve *seq, const GeData &d)
定义:
c4d_canimation.h:170
Int32 GetTrackCategory() const
定义:
c4d_canimation.h:811
void SetBaseList2D(BaseList2D *bl)
定义:
c4d_gedata.h:657
void SetName(const maxon::String &name)
定义:
c4d_baselist.h:2324
maxon::Int32 Int32
定义:
ge_sys_math.h:58
#define ApplicationOutput(formatString,...)
定义:
debugdiagnostics.h:207
Bool Message(Int32 type, void *data=nullptr)
定义:
c4d_baselist.h:1394
Bool ShowBitmap(const Filename &fn)
Bool TrackInformation(BaseDocument *doc, CKey *key, maxon::String *str, Bool set)
定义:
c4d_canimation.h:866
void InsertLast(GeListNode *bn)
定义:
c4d_baselist.h:2065
maxon::Vec3< maxon::Float64, 1 > Vector
定义:
ge_math.h:145
Bool Draw(GeClipMap *map, const BaseTime &clip_left, const BaseTime &clip_right) const
定义:
c4d_canimation.h:782
#define CTRACK_CATEGORY_VALUE
Value track.
定义:
c4d_canimation.h:603
Bool Remap(Float64 time, Float64 *ret_time, Int32 *ret_cycle) const
定义:
c4d_canimation.h:855
@ TL1_SELECT
Selection bit for Timeline 1.
void EndDraw()
Must be called after a sequence of drawing functions to free the memory allocated by BeginDraw().
String GetName() const
定义:
c4d_baselist.h:2318
@ ID_CTRACK_USE_PREF
定义:
ctbase.h:37
@ DTYPE_REAL
Float
定义:
lib_description.h:68
CCurve * GetCurve(CCURVE type=CCURVE::CURVE, Bool bCreate=true)
定义:
c4d_canimation.h:805
CTrack * GetFirstCTrack()
#define MAXON_SCOPE
定义:
apibase.h:2645
Bool SetDescriptionID(BaseList2D *object, const DescID &id)
定义:
c4d_canimation.h:711
Int32 GetKeyCount(void) const
定义:
c4d_canimation.h:370
maxon::Float64 Float64
定义:
ge_sys_math.h:65
#define CTsound
Sound.
定义:
ge_prepass.h:1318