cc = cc or {}
|
|
|
|
--Cat_Todo : 本文件暂时没用,所以没测试过的
|
|
|
|
local DeepCopy = function ( object )
|
|
local lookup_table = {}
|
|
local function _copy(object)
|
|
if type(object) ~= "table" then
|
|
return object
|
|
elseif lookup_table[object] then
|
|
return lookup_table[object]
|
|
end
|
|
|
|
local new_table = {}
|
|
lookup_table[object] = new_table
|
|
for index, value in pairs(object) do
|
|
new_table[_copy(index)] = _copy(value)
|
|
end
|
|
|
|
return setmetatable(new_table, getmetatable(object))
|
|
end
|
|
return _copy(object)
|
|
end
|
|
|
|
cc.PointArray = cc.PointArray or BaseClass()
|
|
function cc.PointArray:__init( points )
|
|
self._controlPoints = points
|
|
end
|
|
function cc.PointArray:clone()
|
|
return DeepCopy(self)
|
|
end
|
|
|
|
function cc.PointArray:getControlPoints()
|
|
return _controlPoints;
|
|
end
|
|
|
|
function cc.PointArray:setControlPoints(controlPoints)
|
|
self._controlPoints = controlPoints
|
|
end
|
|
|
|
function cc.PointArray:addControlPoint(controlPoint)
|
|
table.insert( self._controlPoints, controlPoint )
|
|
end
|
|
|
|
function cc.PointArray:insertControlPoint(controlPoint, index)
|
|
-- self._controlPoints[index] = controlPoint
|
|
table.insert( self._controlPoints, index, controlPoint )
|
|
end
|
|
|
|
function cc.PointArray:getControlPointAtIndex(index)
|
|
index = math.floor( index )
|
|
local count = 0
|
|
if self._controlPoints then
|
|
count = #self._controlPoints
|
|
end
|
|
if index > count then
|
|
index = count
|
|
end
|
|
if index <= 0 then
|
|
index = 1
|
|
end
|
|
-- index = math.min(count, index)
|
|
-- index = index>=1 and index or 1
|
|
-- print("Cat:ActionCatmullRom.lua [34][start] self._controlPoints", self._controlPoints,index)
|
|
-- PrintTable(self._controlPoints)
|
|
-- print("Cat:ActionCatmullRom.lua [34][end]")
|
|
return self._controlPoints[index]
|
|
end
|
|
|
|
function cc.PointArray:replaceControlPoint(controlPoint, index)
|
|
self._controlPoints[index] = controlPoint
|
|
end
|
|
|
|
function cc.PointArray:removeControlPointAtIndex(index)
|
|
if self._controlPoints[index] then
|
|
table.remove( self._controlPoints, index )
|
|
end
|
|
end
|
|
|
|
function cc.PointArray:count()
|
|
return #self._controlPoints
|
|
end
|
|
|
|
function cc.PointArray:reverse()
|
|
local newArray = {}
|
|
for i=#self._controlPoints,1,-1 do
|
|
table.insert( newArray, self._controlPoints[i])
|
|
end
|
|
local config = cc.PointArray.New()
|
|
config:setControlPoints(newArray);
|
|
|
|
return config;
|
|
end
|
|
|
|
-- function cc.PointArray:reverseInline()
|
|
-- {
|
|
-- size_t l = _controlPoints->size();
|
|
-- Vec2 *p1 = nullptr;
|
|
-- Vec2 *p2 = nullptr;
|
|
-- float x, y;
|
|
-- for (size_t i = 0; i < l/2; ++i)
|
|
-- {
|
|
-- p1 = _controlPoints->at(i);
|
|
-- p2 = _controlPoints->at(l-i-1);
|
|
|
|
-- x = p1->x;
|
|
-- y = p1->y;
|
|
|
|
-- p1->x = p2->x;
|
|
-- p1->y = p2->y;
|
|
|
|
-- p2->x = x;
|
|
-- p2->y = y;
|
|
-- }
|
|
-- }
|
|
|
|
-- CatmullRom Spline formula:
|
|
function cc.CardinalSplineAt(p0, p1, p2, p3, tension, t)
|
|
local t2 = t * t
|
|
local t3 = t2 * t
|
|
--Formula: s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
|
|
|
|
local s = (1 - tension) / 2
|
|
|
|
local b1 = s * ((-t3 + (2 * t2)) - t); -- s(-t3 + 2 t2 - t)P1
|
|
local b2 = s * (-t3 + t2) + (2 * t3 - 3 * t2 + 1); -- s(-t3 + t2)P2 + (2 t3 - 3 t2 + 1)P2
|
|
local b3 = s * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2); -- s(t3 - 2 t2 + t)P3 + (-2 t3 + 3 t2)P3
|
|
local b4 = s * (t3 - t2); -- s(t3 - t2)P4
|
|
|
|
local x = (p0.x*b1 + p1.x*b2 + p2.x*b3 + p3.x*b4);
|
|
local y = (p0.y*b1 + p1.y*b2 + p2.y*b3 + p3.y*b4);
|
|
|
|
return {x=x, y=y}
|
|
end
|
|
|
|
--points是控制点列表,tension是松紧程度。tension==1时,样条线是分段直线。tension<1向外松弛弯曲,tension>1向内缩紧弯曲。By动作是以当前坐标为新坐标原点
|
|
cc.CardinalSplineTo = cc.CardinalSplineTo or BaseClass(cc.ActionInterval)
|
|
function cc.CardinalSplineTo:__init(duration, points, tension)
|
|
self:initWithDuration(duration, points, tension)
|
|
end
|
|
|
|
function cc.CardinalSplineTo:initWithDuration(duration, points, tension)
|
|
self._deltaT = 0.0
|
|
-- self._tension = 0.0
|
|
-- CCASSERT(points->count() > 0, "Invalid configuration. It must at least have one control point");
|
|
cc.ActionInterval.initWithDuration(self, duration)
|
|
self._points = cc.PointArray.New(points)
|
|
self._tension = tension
|
|
end
|
|
|
|
function cc.CardinalSplineTo:startWithTarget(target)
|
|
cc.ActionInterval.startWithTarget(self, target);
|
|
-- _deltaT = (float) 1 / _points->count();
|
|
self._deltaT = 1 / (self._points:count() - 1);
|
|
self._previousPosition = {}
|
|
self._previousPosition.x, self._previousPosition.y, self._previousPosition.z = cc.Wrapper.GetLocalPosition(target)
|
|
self._accumulatedDiff = {x=0, y=0}
|
|
end
|
|
|
|
function cc.CardinalSplineTo:clone()
|
|
local a = cc.CardinalSplineTo.New()
|
|
a:initWithDuration(self._duration, self._points:clone(), self._tension)
|
|
return a
|
|
end
|
|
|
|
function cc.CardinalSplineTo:update(time)
|
|
local p;
|
|
local lt;
|
|
|
|
-- eg.
|
|
-- p..p..p..p..p..p..p
|
|
-- 1..2..3..4..5..6..7
|
|
-- want p to be 1, 2, 3, 4, 5, 6
|
|
if (time == 1) then
|
|
p = self._points:count()-1
|
|
lt = 1;
|
|
else
|
|
p = math.floor(time / self._deltaT)
|
|
lt = (time - self._deltaT * p) / self._deltaT
|
|
end
|
|
-- print("Cat:ActionCatmullRom.lua [150] time,p,lt:", time,p,lt)
|
|
-- Interpolate
|
|
local addition = 0
|
|
local pp0 = DeepCopy(self._points:getControlPointAtIndex(p+0+addition))
|
|
local pp1 = DeepCopy(self._points:getControlPointAtIndex(p+1+addition))
|
|
local pp2 = DeepCopy(self._points:getControlPointAtIndex(p+2+addition))
|
|
local pp3 = DeepCopy(self._points:getControlPointAtIndex(p+3+addition))
|
|
|
|
print("Cat:ActionCatmullRom [166] pp0, pp1, pp2, pp3: ", pp0.x, pp0.y, pp1.x, pp1.y, pp2.x, pp2.y, pp3.x, pp3.y, p)
|
|
pp0.y = 720-pp0.y
|
|
pp1.y = 720-pp1.y
|
|
pp2.y = 720-pp2.y
|
|
pp3.y = 720-pp3.y
|
|
local newPos = cc.CardinalSplineAt(pp0, pp1, pp2, pp3, self._tension, lt)
|
|
newPos.y = 720-newPos.y
|
|
-- print("Cat:ActionCatmullRom.lua [157] newPos.x,newPos.y:", newPos.x,newPos.y, lt)
|
|
-- #if CC_ENABLE_STACKABLE_ACTIONS
|
|
-- -- Support for stacked actions
|
|
-- Node *node = _target;
|
|
-- local diff = node->getPosition() - _previousPosition;
|
|
-- if( diff.x !=0 || diff.y != 0 )
|
|
-- _accumulatedDiff = _accumulatedDiff + diff;
|
|
-- newPos = newPos + _accumulatedDiff;
|
|
-- end
|
|
-- #endif
|
|
self:updatePosition(newPos)
|
|
end
|
|
|
|
function cc.CardinalSplineTo:updatePosition(newPos)
|
|
if self._target.SetVectorValue then
|
|
self._target:SetVectorValue(WidgetProperty.Position, newPos.x, newPos.y)
|
|
elseif self._target.setPosition then
|
|
self._target:setPosition(newPos.x, newPos.y)
|
|
end
|
|
self._previousPosition = newPos
|
|
end
|
|
|
|
function cc.CardinalSplineTo:reverse()
|
|
local pReverse = self._points:reverse()
|
|
return cc.CardinalSplineTo.New(self._duration, pReverse, self._tension)
|
|
end
|
|
|
|
|
|
-- function cc.CardinalSplineBy:create(duration, points, tension)
|
|
|
|
-- CardinalSplineBy *ret = new (std:nothrow) CardinalSplineBy();
|
|
-- if (ret)
|
|
|
|
-- if (ret->initWithDuration(duration, points, tension))
|
|
|
|
-- ret->autorelease();
|
|
-- else
|
|
|
|
-- CC_SAFE_RELEASE_NULL(ret);
|
|
-- end
|
|
-- end
|
|
|
|
-- return ret;
|
|
-- end
|
|
|
|
-- CardinalSplineBy:CardinalSplineBy() : _startPosition(0,0)
|
|
|
|
-- end
|
|
|
|
-- function cc.CardinalSplineBy:updatePosition(cocos2d:Vec2 &newPos)
|
|
|
|
-- Vec2 p = newPos + _startPosition;
|
|
-- _target->setPosition(p);
|
|
-- _previousPosition = p;
|
|
-- end
|
|
|
|
-- CardinalSplineBy* CardinalSplineBy:reverse() const
|
|
|
|
-- PointArray *copyConfig = _points->clone();
|
|
|
|
-- //
|
|
-- // convert "absolutes" to "diffs"
|
|
-- //
|
|
-- Vec2 p = copyConfig->getControlPointAtIndex(0);
|
|
-- for (ssize_t i = 1; i < copyConfig->count(); ++i)
|
|
|
|
-- Vec2 current = copyConfig->getControlPointAtIndex(i);
|
|
-- Vec2 diff = current - p;
|
|
-- copyConfig->replaceControlPoint(diff, i);
|
|
|
|
-- p = current;
|
|
-- end
|
|
|
|
-- // convert to "diffs" to "reverse absolute"
|
|
|
|
-- PointArray *pReverse = copyConfig->reverse();
|
|
|
|
-- // 1st element (which should be 0,0) should be here too
|
|
|
|
-- p = pReverse->getControlPointAtIndex(pReverse->count()-1);
|
|
-- pReverse->removeControlPointAtIndex(pReverse->count()-1);
|
|
|
|
-- p = -p;
|
|
-- pReverse->insertControlPoint(p, 0);
|
|
|
|
-- for (ssize_t i = 1; i < pReverse->count(); ++i)
|
|
|
|
-- Vec2 current = pReverse->getControlPointAtIndex(i);
|
|
-- current = -current;
|
|
-- Vec2 abs = current + p;
|
|
-- pReverse->replaceControlPoint(abs, i);
|
|
|
|
-- p = abs;
|
|
-- end
|
|
|
|
-- return CardinalSplineBy:create(_duration, pReverse, _tension);
|
|
-- end
|
|
|
|
-- function cc.CardinalSplineBy:startWithTarget(cocos2d:Node *target)
|
|
|
|
-- CardinalSplineTo:startWithTarget(target);
|
|
-- _startPosition = target->getPosition();
|
|
-- end
|
|
|
|
-- CardinalSplineBy* CardinalSplineBy:clone() const
|
|
|
|
-- // no copy constructor
|
|
-- auto a = new (std:nothrow) CardinalSplineBy();
|
|
-- a->initWithDuration(this->_duration, this->_points->clone(), this->_tension);
|
|
-- a->autorelease();
|
|
-- return a;
|
|
-- end
|